//////////////////////////////////////////////////////////////////////
// Copyright (C) SUGIMURA Lab. 2022.08.30
// SwitchBot関係の処理
//////////////////////////////////////////////////////////////////////
'use strict'
////////////////////////////////////////////////////////////////////////////////
// HTMLロードしたら準備
/**
* @namespace subSwitchBot
*/
window.addEventListener('DOMContentLoaded', function () {
console.dir('## DOMContentLoaded subSwitchBot.js');
let facilitiesSwitchBot; // 宅内情報(switchBot)
let H3SwitchBot = document.getElementById('H3SwitchBot');
let H3SwitchBotPower = document.getElementById('H3SwitchBotPower');
let divSwitchBot = document.getElementById('divSwitchBot'); // switchBotのセンサデータ
// config
let inSwitchBotUse = document.getElementById('inSwitchBotUse'); // switchBot; use or not
let inSwitchBotToken = document.getElementById('inSwitchBotToken'); // switchBot; token
let inSwitchBotSecret = document.getElementById('inSwitchBotSecret'); // switchBot; secret
let btnSwitchBotConfigSet = document.getElementById('btnSwitchBotConfigSet'); // switchBot; 設定ボタン
// control tab
let H2ControlSwitchBot = document.getElementById('H2ControlSwitchBot'); // ヘッダ
let divControlSwitchBot = document.getElementById('divControlSwitchBot'); // SwitchBotのコントロール
const canRoomEnvChartSwitchBot = document.getElementById('canRoomEnvChartSwitchBot'); // 部屋環境グラフ
let divSwitchBotSuggest = document.getElementById('divSwitchBotSuggest'); // switchBot; サジェスト
//----------------------------------------------------------------------------------------------
/**
* @func
* @desc SwitchBot デバイス情報のrenew
* @param {void}
* @return {void}
*/
window.renewFacilitiesSwitchBot = function (arg) {
// console.log('window.renewFacilitiesSwitchBot() arg:', arg);
facilitiesSwitchBot = arg;
if (!inSwitchBotUse.checked) { // 機能無効なのにrenewが来た
return;
}
let doc = '';
if (!facilitiesSwitchBot || isObjEmpty(facilitiesSwitchBot)) { // 機器情報なし
doc = '<img src="./img/loadingRed.gif">接続中、又は機器情報取得中';
divControlSwitchBot.innerHTML = doc;
return; // 機器情報なければやらない、存在も消す
}
let devs = facilitiesSwitchBot.deviceList; // array
for (const d of devs) {
let devState = facilitiesSwitchBot[d.deviceId];
let icon = '';
let subicon = '';
let control = '';
// console.log('window.renewFacilitiesSwitchBot() d:', d, 'devState:', devState);
doc += "<div class='LinearLayoutChild'> <section>";
switch (d.deviceType) {
case 'Bot':
switch (devState.power) {
case 'on': icon = 'fa-regular fa-square'; break;
case 'off': icon = 'fa-solid fa-square-xmark'; break;
}
doc += `<div class="tooltip"><i class="${icon} switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>`;
break;
case 'Curtain':
doc += `<div class="tooltip"><i class="fa-solid fa-person-booth switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>Position:${devState.slidePosition}`;
break;
case 'Hub':
case 'Hub Plus':
case 'Hub Mini':
doc += `<div class="tooltip"><i class="fa-solid fa-cube switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
case 'Meter':
case 'MeterPlus':
doc += `<div class="tooltip"><i class="fa-solid fa-temperature-half switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>${devState.temperature} ℃ / ${devState.humidity} %`;
break;
case 'Lock':
doc += `<div class="tooltip"><i class="fa-solid fa-lock switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>LockState:${d.lockState}<br>DoorState:${devState.doorState}`;
break;
case 'Keypad': // 指紋認証鍵
case 'Keypad Touch':
doc += `<div class="tooltip"><i class="fa-solid fa-fingerprint switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
case 'Remote': // リモートボタン
doc += `<div class="tooltip"><i class="fa-solid fa-toggle-off switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
case 'Motion Sensor':
switch (devState.brightness) {
case "bright": subicon = "fa-regular fa-sun"; break; // 明るい
case "dim": subicon = "fa-solid fa-moon"; break; // 暗い
}
doc += `<div class="tooltip"><i class="fa-solid fa-person-rays switchBot-dev"></i><i class="${subicon} switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>MoveDetected: ${devState.moveDetected}`;
break;
case 'Contact Sensor': // 開閉センサ
/* APIマニュアルにはあるけど、実際はセンサデータとれてない。常にbrightになる。
switch(devState.brightness){
case "bright": subicon = "fa-regular fa-sun"; break; // 明るい
case "dim": subicon = "fa-solid fa-moon"; break; // 暗い
} */
switch (devState.openState) {
case "open": // 開いた
case "timeOutNotClose": icon = "fa-door-open"; break; // 開きっぱなし
case "close": icon = "fa-door-closed"; break; // 閉まった
}
doc += `<div class="tooltip"><i class="fa-solid ${icon} switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>MoveDetected: ${devState.moveDetected}`;
break;
case 'Ceiling Light':
case 'Ceiling Light Pro':
doc += `<div class="tooltip"><i class="fa-regular fa-lightbulb switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
case 'Plug Mini (US)':
case 'Plug Mini (JP)':
if (devState.power == 'on') {
control = `<button onClick="window.SwitchBotPlug(this);" value="${d.deviceId},turnOff">OFF</button>`;
icon = 'fa-plug-circle-bolt';
} else {
control = `<button onClick="window.SwitchBotPlug(this);" value="${d.deviceId},turnOn">ON</button>`;
icon = 'fa-plug';
}
doc += `<div class="tooltip"><i class="fa-solid ${icon} switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>`;
doc += `${control}<br>`;
doc += `${devState.voltage} [V] / ${devState.electricCurrent} [A]<br>`
doc += `${devState.weight} [W]<br>`;
doc += `Duration: ${devState.electricityOfDay} min<br>`;
break;
case 'Plug':
if (devState.power == 'on') {
control = `<button onClick="window.SwitchBotPlug(this);" value="${d.deviceId},turnOff">OFF</button>`;
icon = 'fa-plug-circle-bolt';
} else {
control = `<button onClick="window.SwitchBotPlug(this);" value="${d.deviceId},turnOn">ON</button>`;
icon = 'fa-plug';
}
doc += `<div class="tooltip"><i class="fa-solid ${icon} switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>${control}`;
break;
case 'Strip Light':
doc += `<div class="tooltip"><i class="fa-brands fa-strip-s switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
case 'Color Bulb':
switch (devState.power) {
case 'on': icon = 'fa-regular fa-lightbulb'; break;
case 'off': icon = 'fa-solid fa-lightbulb'; break;
}
doc += `<div class="tooltip"><i class="${icon} switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>brightness:${devState.brightness}<br>color:${devState.color}<br>colorTemperature:${devState.colorTemperature}`;
break;
case 'Robot Vacuum Cleaner S1':
case 'Robot Vacuum Cleaner S1 Plus':
doc += `<div class="tooltip"><i class="fa-solid fa-circle-notch switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
case 'Humidifier': // 加湿器
switch (devState.power) {
case 'on': subicon = 'fa-plug-circle-bolt'; break;
case 'off': subicon = 'fa-plug'; break;
}
doc += `<div class="tooltip"><i class="fa-solid fa-droplet switchBot-dev"></i><i class="fa-solid ${subicon} switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}<br>${devState.temperature} ℃ / ${devState.humidity}%<br>lackWater: ${devState.lackWater}`;
break;
case 'Indoor Cam':
doc += `<div class="tooltip"><i class="fa-solid fa-video switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
case 'Pan/Tilt Cam':
case 'Pan/Tilt Cam 2K':
doc += `<div class="tooltip"><i class="fa-solid fa-video switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
default:
// console.log('subSwitchBot, unknown device, d:', d );
doc += `<div class="tooltip"><i class="fa-solid fa-circle-nodes switchBot-dev"></i><div class="description">${d.deviceId}</div></div><br>${d.deviceName}`;
break;
}
doc += "</section> </div>"; // ボタン設置
}
divControlSwitchBot.innerHTML = doc;
};
//----------------------------------------------------------------------------------------------
/**
* @func
* @desc SwitchBot config
* @param {void}
* @return {void}
*/
window.btnSwitchBotConfigSet_Click = function () {
btnSwitchBotConfigSet.disabled = true;
btnSwitchBotConfigSet.textContent = '設定中...';
if (!inSwitchBotUse.checked || inSwitchBotToken.value == '' || inSwitchBotSecret.value == '') {
window.ipc.SwitchBotStop(inSwitchBotToken.value, inSwitchBotSecret.value); // SwitchBot の監視を stopする
renewFacilitiesSwitchBot(facilitiesSwitchBot);
return; // falseなら外すだけ
}
window.ipc.SwitchBotUse(inSwitchBotToken.value, inSwitchBotSecret.value);
};
/**
* @func
* @desc 設定完了通知で、設定ボタンの復活(連打防止)
* @param {void}
* @return {void}
*/
window.SwitchBotConfigSaved = function () {
btnSwitchBotConfigSet.disabled = false;
btnSwitchBotConfigSet.textContent = '設定';
window.addToast('Info', 'SwitchBot 設定を保存しました。');
};
let spanSwitchBotTime = document.getElementById('spanSwitchBotTime'); // abst
/**
* @func
* @desc mainプロセスから設定値をもらったので画面を更新
* @param {void}
* @return {void}
*/
window.renewSwitchBotConfigView = function (arg) {
// console.log('window.renewSwitchBotConfigView arg:', arg);
inSwitchBotUse.checked = arg.enabled;
inSwitchBotToken.value = arg.token;
inSwitchBotSecret.value = arg.secret;
btnSwitchBotConfigSet.disabled = false;
btnSwitchBotConfigSet.textContent = '設定';
if (arg.enabled) { // 利用する場合
H2ControlSwitchBot.style.display = 'block';
spanSwitchBotTime.innerHTML = moment().format("YYYY/MM/DD HH:mm:ss取得");
divControlSwitchBot.style.display = '-webkit-flex';
canRoomEnvChartSwitchBot.style.display = 'block';
divSwitchBotSuggest.style.display = 'none';
} else { // 利用しない場合
H2ControlSwitchBot.style.display = 'none';
divControlSwitchBot.style.display = 'none';
canRoomEnvChartSwitchBot.style.display = 'none';
divSwitchBotSuggest.style.display = 'block';
}
};
//----------------------------------------------------------------------------------------------
/**
* @func
* @desc SwitchBot control
* @param {void}
* @return {void}
*/
window.SwitchBotPlug = function (btn) {
let v = btn.value.split(',');
let c = { command: v[1] };
console.log('btn:', v[0], JSON.stringify(c));
window.ipc.SwitchBotControl(v[0], JSON.stringify(c));
};
//----------------------------------------------------------------------------------------------
// SwitchBot chart
let spanSwitchBotEnvTime = document.getElementById('spanSwitchBotEnvTime'); // env
let spanSwitchBotPowerTime = document.getElementById('spanSwitchBotPowerTime'); // power
/**
* @func
* @desc newLegendClickHandler
* @memberof subSwitchBot
* @param {void}
* @return {void}
*/
let newLegendClickHandler = function (e, legendItem) {
let index = legendItem.datasetIndex;
let ci = this.chart;
let meta = ci.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
ci.update(); // データセットを非表示にしました。チャートを再表示してください。
console.log('newLegendClickHandler() legendItem:', legendItem);
switch (legendItem.text) {
case "温度 [℃]":
if (legendItem.hidden) {
const switchBotDocTempSec = document.getElementById('switchBotDocTempSec');
switchBotDocTempSec.classList.add("temp_color");
switchBotDocTempSec.classList.remove("disabled_color");
} else {
const switchBotDocTempSec = document.getElementById('switchBotDocTempSec');
switchBotDocTempSec.classList.remove("temp_color");
switchBotDocTempSec.classList.add("disabled_color");
}
break;
case "湿度 [%RH]":
if (legendItem.hidden) {
const switchBotDocHumSec = document.getElementById('switchBotDocHumSec');
switchBotDocHumSec.classList.add("hum_color");
switchBotDocHumSec.classList.remove("disabled_color");
} else {
const switchBotDocHumSec = document.getElementById('switchBotDocHumSec');
switchBotDocHumSec.classList.remove("hum_color");
switchBotDocHumSec.classList.add("disabled_color");
}
break;
default:
break;
}
};
/**
* @func
* @desc newPowerLegendClickHandler
* @memberof subSwitchBot
* @param {void}
* @return {void}
*/
let newPowerLegendClickHandler = function (e, legendItem) {
let index = legendItem.datasetIndex;
let ci = this.chart;
let meta = ci.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
ci.update(); // データセットを非表示にしました。チャートを再表示してください。
console.log('newPowerLegendClickHandler() legendItem:', legendItem);
switch (legendItem.text) {
case "ワット [W]":
const switchBotDocWattSec = document.getElementById('switchBotDocWattSec');
if (legendItem.hidden) {
switchBotDocWattSec.classList.add("watt_color");
switchBotDocWattSec.classList.remove("disabled_color");
} else {
switchBotDocWattSec.classList.remove("watt_color");
switchBotDocWattSec.classList.add("disabled_color");
}
break;
case "ボルト [V]":
const switchBotDocVoltSec = document.getElementById('switchBotDocVoltSec');
if (legendItem.hidden) {
switchBotDocVoltSec.classList.add("vold_color");
switchBotDocVoltSec.classList.remove("disabled_color");
} else {
switchBotDocVoltSec.classList.remove("volt_color");
switchBotDocVoltSec.classList.add("disabled_color");
}
break;
case "アンペア [A]":
const switchBotDocAmpereSec = document.getElementById('switchBotDocAmpereSec');
if (legendItem.hidden) {
switchBotDocAmpereSec.classList.add("ampere_color");
switchBotDocAmpereSec.classList.remove("disabled_color");
} else {
switchBotDocAmpereSec.classList.remove("ampere_color");
switchBotDocAmpereSec.classList.add("disabled_color");
}
break;
default:
break;
}
};
// HTML内部とリンク
const ctxSwitchBot = canRoomEnvChartSwitchBot.getContext('2d');
const ctxSwitchBotPower = canRoomPowerChartSwitchBot.getContext('2d');
let myChartSwitchBot = null;
let myPowerChartSwitchBot = null;
// 複数軸用の、軸オプション
let complexChartOption = {
responsive: true,
plugins: {
legend: {
display: true,
position: 'top',
onClick: newLegendClickHandler
}
},
scales: {
"y-axis-left": {
type: "linear", // linear固定
position: "left", // どちら側に表示される軸か?
suggestedMax: 50,
min: 0,
title: { display: true, text: 'Temperature[℃]' },
grid: {
color: 'rgba(255,0,0,0.1)',
borderColor: 'rgba(255,0,0,1.0)'
}
},
"y-axis-right": {
type: "linear",
position: "right",
suggestedMax: 100,
min: 0,
title: { display: true, text: 'Humidity[%]' },
grid: {
borderColor: 'rgba(0,0,255,1.0)'
}
},
"x": {
type: 'time',
time: {
unit: 'minutes',
parser: 'HH:mm',
displayFormats: {
minute: 'HH:mm',
hour: 'HH:mm'
}
},
min: '00:00',
max: '24:00',
ticks: {
// autoSkip: false,
maxTicksLimit: 24 * 2 + 1, // 24h * 30min + 00:00
maxRotation: 90,
// stepSize: 120,
beginAtZero: true,
callback: function (value, index, ticks) {
return moment.tz(value, 'Asia/Tokyo').format('HH:mm');
// return ( index % 60 == 0 ? moment.tz(value, 'Asia/Tokyo').format('HH:mm') : '' );
}
},
grid: {
color: 'rgba(0,0,0,0.3)',
borderColor: 'rgba(0,0,0,1.0)'
}
}
}
};
// 複数軸用の、軸オプション (Power)
let complexPowerChartOption = {
responsive: true,
plugins: {
legend: {
display: true,
position: 'top',
onClick: newPowerLegendClickHandler
}
},
scales: {
"y-axis-left-w": { // watt
type: "linear", // linear固定
position: "left", // どちら側に表示される軸か?
suggestedMax: 3000,
min: 0,
title: { display: true, text: 'Watt [W]' },
grid: {
color: 'rgba(255,0,0,0.1)',
borderColor: 'rgba(255,0,0,1.0)'
}
},
"y-axis-left-a": { // ampere
type: "linear", // linear固定
position: "left", // どちら側に表示される軸か?
suggestedMax: 30,
min: 0,
title: { display: true, text: 'Ampere [A]' },
grid: {
color: 'rgba(255,0,0,0.1)',
borderColor: 'rgba(255,0,0,1.0)'
}
},
"y-axis-right": {
type: "linear",
position: "right",
suggestedMax: 110,
min: 0,
title: { display: true, text: 'Voltage [V]' },
grid: {
borderColor: 'rgba(0,0,255,1.0)'
}
},
"x": {
type: 'time',
time: {
unit: 'minutes',
parser: 'HH:mm',
displayFormats: {
minute: 'HH:mm',
hour: 'HH:mm'
}
},
min: '00:00',
max: '24:00',
ticks: {
// autoSkip: false,
maxTicksLimit: 24 * 2 + 1, // 24h * 30min + 00:00
maxRotation: 90,
// stepSize: 120,
beginAtZero: true,
callback: function (value, index, ticks) {
return moment.tz(value, 'Asia/Tokyo').format('HH:mm');
// return ( index % 60 == 0 ? moment.tz(value, 'Asia/Tokyo').format('HH:mm') : '' );
}
},
grid: {
color: 'rgba(0,0,0,0.3)',
borderColor: 'rgba(0,0,0,1.0)'
}
}
}
};
// 表示データ(動的)
let datasetsSwitchBot = []; //
let datasetsSwitchBotPower = [];
/**
* @func
* @desc renewCanvasSwitchBot
* @memberof subSwitchBot
* @param {void}
* @return {void}
*/
let renewCanvasSwitchBot = function () {
H3SwitchBot.style.display = 'block';
if (myChartSwitchBot) {
// すでにチャートがあればアップデートだけ
myChartSwitchBot.data.datasets = datasetsSwitchBot;
myChartSwitchBot.update();
} else {
// 初回起動はチャートオブジェクトを作る
myChartSwitchBot = new Chart(ctxSwitchBot, {
type: 'line',
data: {
// labels: LABEL_X,
datasets: datasetsSwitchBot
},
options: complexChartOption
});
}
};
/**
* @func
* @desc renewPowerCanvasSwitchBot
* @memberof subSwitchBot
* @param {void}
* @return {void}
*/
let renewPowerCanvasSwitchBot = function () {
H3SwitchBotPower.style.display = 'block';
if (myPowerChartSwitchBot) {
// すでにチャートがあればアップデートだけ
myPowerChartSwitchBot.data.datasets = datasetsSwitchBotPower;
myPowerChartSwitchBot.update();
} else {
// 初回起動はチャートオブジェクトを作る
myPowerChartSwitchBot = new Chart(ctxSwitchBotPower, {
type: 'line',
data: {
// labels: LABEL_X,
datasets: datasetsSwitchBotPower
},
options: complexPowerChartOption
});
}
};
const pointStyleList = ['circle', 'triangle', 'cross', 'rect', 'star', 'dash', 'rectRounded', 'crossRot', 'rectRot', 'line'];
//////////////////////////////////////////////////////////////////
/**
* @func
* @desc データをもらって画面更新
* @param {void}
* @return {void}
*/
window.renewRoomEnvSwitchBot = function (_envDataObj) {
let envDataObj = JSON.parse(_envDataObj);
datasetsSwitchBot = []; // データを一旦空に戻す env
let pointStyle = 0; // ポイントスタイル 0..9
for (const meter of envDataObj.meterList) {
let envDataArray = envDataObj[meter];
// console.log( 'window.renewRoomEnvSwitchBot() meter:', meter, ', envDataArray:', envDataArray );
spanSwitchBotEnvTime.innerHTML = moment().format("YYYY/MM/DD HH:mm:ss取得");
if (envDataArray) {
let oTemperature = new Array();
let oHumidity = new Array();
for (const d of envDataArray) {
oTemperature.push({ x: moment(d.time), y: d.temperature });
oHumidity.push({ x: moment(d.time), y: d.humidity });
}
datasetsSwitchBot.push(
{
label: meter + ':温度 [℃]', type: 'line', data: oTemperature, borderColor: "rgba(255,70,70,1.0)", backgroundColor: "rgba(255,178,178,1.0)",
radius: 4, borderWidth: 1, yAxisID: 'y-axis-left', xAxisID: 'x', pointStyle: pointStyleList[pointStyle]
},
{
label: meter + ':湿度 [%RH]', type: 'line', data: oHumidity, borderColor: "rgba(70,70,255,1.0)", backgroundColor: "rgba(178,178,255,1.0)",
radius: 4, borderWidth: 1, yAxisID: 'y-axis-right', xAxisID: 'x', pointStyle: pointStyleList[pointStyle]
}
);
pointStyle = pointStyle == 9 ? 0 : pointStyle += 1; // 9なら0に戻る、でなければ次のスタイルへ
}
}
renewCanvasSwitchBot();
datasetsSwitchBotPower = []// データを一旦空に戻す power
pointStyle = 0; // ポイントスタイル 0..9
for (const plug of envDataObj.plugMiniList) {
let envDataArray = envDataObj[plug];
// console.log( 'window.renewRoomEnvSwitchBot() plug:', plug, ', envDataArray:', envDataArray );
spanSwitchBotPowerTime.innerHTML = moment().format("YYYY/MM/DD HH:mm:ss取得");
if (envDataArray) {
let oWatt = new Array();
let oVoltage = new Array();
let oAmpere = new Array();
for (const d of envDataArray) {
oWatt.push({ x: moment(d.time), y: d.watt });
oVoltage.push({ x: moment(d.time), y: d.voltage });
oAmpere.push({ x: moment(d.time), y: d.ampere });
}
datasetsSwitchBotPower.push(
{
label: plug + ':電力 [W]', type: 'line', data: oWatt, borderColor: "rgba(255,70,70,1.0)", backgroundColor: "rgba(255,178,178,1.0)",
radius: 4, borderWidth: 1, yAxisID: 'y-axis-left-w', xAxisID: 'x', pointStyle: pointStyleList[pointStyle]
},
{
label: plug + ':電圧 [V]', type: 'line', data: oVoltage, borderColor: "rgba(70,70,255,1.0)", backgroundColor: "rgba(178,178,255,1.0)",
radius: 4, borderWidth: 1, yAxisID: 'y-axis-right', xAxisID: 'x', pointStyle: pointStyleList[pointStyle]
},
{
label: plug + ':電流 [A]', type: 'line', data: oAmpere, borderColor: "rgba(70,70,255,1.0)", backgroundColor: "rgba(178,178,255,1.0)",
radius: 4, borderWidth: 1, yAxisID: 'y-axis-left-a', xAxisID: 'x', pointStyle: pointStyleList[pointStyle]
}
);
pointStyle = pointStyle == 9 ? 0 : pointStyle += 1; // 9なら0に戻る、でなければ次のスタイルへ
}
}
renewPowerCanvasSwitchBot();
};
});