sony meshがいろんなセンサついていて便利なんですが、プログラム書かないといないのがネックだ・・!と言う声を聞くので、node-red上で使ってみました。
MESHのボタンを押したらMESHのLEDが光る、というものを作ります。
大枠方針
obniz初期セットアップノードではbleでデバイスを見つけて接続し続けるプログラムを書く
- ひたすらscanしてブロックを探す
- 見つけたらブロックリスト変数に入れる
- ブロックリスト変数に入っているブロックがconnectedになるように監視する
obniz repeat/functionノードではMESH Blockが接続されていない可能性も考慮してプログラムを書く
- ブロックリスト変数に入っているもののうち、接続済みのブロックから使いたいものを探す
- 接続済みじゃなかったら利用は諦める
obniz初期ノード
ひたすらにScan!Scan!Scan!します
node.warn("obniz connected")
const sleep = (ms) => new Promise((res) => setTimeout(res, ms));
const sessionId = Math.random();
obniz.sessionId = sessionId
obnizParts.meshblocks = {};
await obniz.ble.initWait();
node.warn("ble inited")
const MESH_100AC = obniz.constructor.getPartsClass("MESH_100AC");
const MESH_100BU = obniz.constructor.getPartsClass("MESH_100BU");
const MESH_100GP = obniz.constructor.getPartsClass("MESH_100GP");
const MESH_100LE = obniz.constructor.getPartsClass("MESH_100LE");
const MESH_100MD = obniz.constructor.getPartsClass("MESH_100MD");
const MESH_100PA = obniz.constructor.getPartsClass("MESH_100PA");
const MESH_100TH = obniz.constructor.getPartsClass("MESH_100TH");
const targetBlockTypes = [
// MESH_100AC,
MESH_100BU,
// MESH_100GP,
MESH_100LE,
// MESH_100MD,
// MESH_100PA,
// MESH_100TH,
];
while (obniz.sessionId === sessionId && obniz.connectionState === 'connected') {
// Step1 scanして見つけたブロックをlistに入れていく
node.warn("scan starting...")
await obniz.ble.scan.startWait(
{ localNamePrefix: "MESH-100" },
{ duration: 15 }
);
obniz.ble.scan.onfind = async (peripheral) => {
if (!!obnizParts.meshblocks[peripheral.localName]) {
//もうリストに入っている
return;
}
const blockTypeClass = targetBlockTypes.find(b => b.isMESHblock(peripheral));
if (!blockTypeClass) {
return;
}
node.warn("found new MESH Block :" + peripheral.localName);
obnizParts.meshblocks[peripheral.localName] = new blockTypeClass(peripheral);
await obniz.ble.scan.endWait();
};
// scan停止まち
while (obniz.ble.scan.state !== 'stopped') {
await sleep(100);
}
node.warn("scan stopped")
// Step2 リストを順番に接続していく
for (let blockName in obnizParts.meshblocks) {
const block = obnizParts.meshblocks[blockName];
if (!block.peripheral.connected) {
node.warn("connecting to " + block.peripheral.localName);
try {
await block.connectWait();
node.warn("connected to " + block.peripheral.localName);
} catch (e) {
node.warn("connect failed to " + block.peripheral.localName);
}
}
}
}
こちらを”初期化処理”の方に入れます。
obniz repeat/functionノード
ほしいBlockのインスタンスをobnizPartsから持ってきます
const MESH_100BU = obniz.constructor.getPartsClass("MESH_100BU");
const buttonBlock = Object.values(obnizParts.meshblocks).find((b) => b instanceof MESH_100BU && b.peripheral.connected);
あとはこの buttonBlock
をつかってプログラムを書くだけです
ボタンブロックの使い方ドキュメントを見ながら作ります。
node.send(msg)
あたりがnode-redっぽいですね
if (buttonBlock){
buttonBlock.onSinglePressed = (() => {
msg.payload = "single";
node.send(msg);
});
buttonBlock.onDoublePressed = (() => {
msg.payload = "double";
node.send(msg);
});
buttonBlock.onLongPressed = (() => {
msg.payload = "long";
node.send(msg);
});
}
LEDの方も同じようにつなげてあげればokです!
const MESH_100LE = obniz.constructor.getPartsClass("MESH_100LE");
const ledBlock = Object.values(obnizParts.meshblocks).find((b) => b instanceof MESH_100LE && b.peripheral.connected);
if (ledBlock) {
if(msg.payload === 'single'){
const colors = {
red: 15, // Set LED-Red in the range of 0 to 127.
green: 63, // Set LED-Green in the range of 0 to 127.
blue: 0 // Set LED-Blue in the range of 0 to 127.
};
const totalTime = 1000; // Set the total control time in the range of 0 to 65,535[ms].
const cycleOnTime = 1000; // Set the light on time in cycle in the range of 0 to 65,535[ms].
const cycleOffTime = 500; // Set the light off time in cycle in the range of 0 to 65,535[ms].
const pattern = MESH_100LE.Pattern.FIREFLY; // Set the blinking pattern to blink or firefly.
// Write
ledBlock.setLed(colors, totalTime, cycleOnTime, cycleOffTime, pattern);
} else if (msg.payload === 'double') {
const colors = {
red: 0, // Set LED-Red in the range of 0 to 127.
green: 0, // Set LED-Green in the range of 0 to 127.
blue: 127 // Set LED-Blue in the range of 0 to 127.
};
const totalTime = 3000; // Set the total control time in the range of 0 to 65,535[ms].
const cycleOnTime = 1000; // Set the light on time in cycle in the range of 0 to 65,535[ms].
const cycleOffTime = 500; // Set the light off time in cycle in the range of 0 to 65,535[ms].
const pattern = MESH_100LE.Pattern.BLINK; // Set the blinking pattern to blink or firefly.
// Write
ledBlock.setLed(colors, totalTime, cycleOnTime, cycleOffTime, pattern);
} else if (msg.payload === 'long') {
const colors = {
red: 127, // Set LED-Red in the range of 0 to 127.
green: 0, // Set LED-Green in the range of 0 to 127.
blue: 0 // Set LED-Blue in the range of 0 to 127.
};
const totalTime = 3000; // Set the total control time in the range of 0 to 65,535[ms].
const cycleOnTime = 3000; // Set the light on time in cycle in the range of 0 to 65,535[ms].
const cycleOffTime = 500; // Set the light off time in cycle in the range of 0 to 65,535[ms].
const pattern = MESH_100LE.Pattern.FIREFLY; // Set the blinking pattern to blink or firefly.
// Write
ledBlock.setLed(colors, totalTime, cycleOnTime, cycleOffTime, pattern);
}
}
サンプルの全フローはこちら↓
[{"id":"dc2aa5752f56ddf0","type":"obniz-function","z":"56ff5f1b106b752a","obniz":"22b6be5b760eef74","name":"obniz/mesh LED","code":"\nconst MESH_100LE = obniz.constructor.getPartsClass(\"MESH_100LE\");\nconst ledBlock = Object.values(obnizParts.meshblocks).find((b) => b instanceof MESH_100LE && b.peripheral.connected);\n\nif (ledBlock) {\n\n if(msg.payload === 'single'){\n const colors = {\n red: 15, // Set LED-Red in the range of 0 to 127.\n green: 63, // Set LED-Green in the range of 0 to 127.\n blue: 0 // Set LED-Blue in the range of 0 to 127.\n };\n const totalTime = 1000; // Set the total control time in the range of 0 to 65,535[ms].\n const cycleOnTime = 1000; // Set the light on time in cycle in the range of 0 to 65,535[ms].\n const cycleOffTime = 500; // Set the light off time in cycle in the range of 0 to 65,535[ms].\n const pattern = MESH_100LE.Pattern.FIREFLY; // Set the blinking pattern to blink or firefly.\n\n // Write\n ledBlock.setLed(colors, totalTime, cycleOnTime, cycleOffTime, pattern);\n\n } else if (msg.payload === 'double') {\n const colors = {\n red: 0, // Set LED-Red in the range of 0 to 127.\n green: 0, // Set LED-Green in the range of 0 to 127.\n blue: 127 // Set LED-Blue in the range of 0 to 127.\n };\n const totalTime = 3000; // Set the total control time in the range of 0 to 65,535[ms].\n const cycleOnTime = 1000; // Set the light on time in cycle in the range of 0 to 65,535[ms].\n const cycleOffTime = 500; // Set the light off time in cycle in the range of 0 to 65,535[ms].\n const pattern = MESH_100LE.Pattern.BLINK; // Set the blinking pattern to blink or firefly.\n\n // Write\n ledBlock.setLed(colors, totalTime, cycleOnTime, cycleOffTime, pattern);\n\n } else if (msg.payload === 'long') {\n const colors = {\n red: 127, // Set LED-Red in the range of 0 to 127.\n green: 0, // Set LED-Green in the range of 0 to 127.\n blue: 0 // Set LED-Blue in the range of 0 to 127.\n };\n const totalTime = 3000; // Set the total control time in the range of 0 to 65,535[ms].\n const cycleOnTime = 3000; // Set the light on time in cycle in the range of 0 to 65,535[ms].\n const cycleOffTime = 500; // Set the light off time in cycle in the range of 0 to 65,535[ms].\n const pattern = MESH_100LE.Pattern.FIREFLY; // Set the blinking pattern to blink or firefly.\n\n // Write\n ledBlock.setLed(colors, totalTime, cycleOnTime, cycleOffTime, pattern);\n\n }\n\n \n}","x":600,"y":220,"wires":[[]]},{"id":"22b6be5b760eef74","type":"obniz","obnizId":"70463008","deviceType":"obnizboard1y","name":"","accessToken":"","code":"node.warn(\"obniz connected\")\n\nconst sleep = (ms) => new Promise((res) => setTimeout(res, ms));\nconst sessionId = Math.random();\nobniz.sessionId = sessionId\nobnizParts.meshblocks = {};\nawait obniz.ble.initWait();\n\nnode.warn(\"ble inited\")\n\nconst MESH_100AC = obniz.constructor.getPartsClass(\"MESH_100AC\");\nconst MESH_100BU = obniz.constructor.getPartsClass(\"MESH_100BU\");\nconst MESH_100GP = obniz.constructor.getPartsClass(\"MESH_100GP\");\nconst MESH_100LE = obniz.constructor.getPartsClass(\"MESH_100LE\");\nconst MESH_100MD = obniz.constructor.getPartsClass(\"MESH_100MD\");\nconst MESH_100PA = obniz.constructor.getPartsClass(\"MESH_100PA\");\nconst MESH_100TH = obniz.constructor.getPartsClass(\"MESH_100TH\");\n\nconst targetBlockTypes = [\n // MESH_100AC,\n MESH_100BU,\n // MESH_100GP,\n MESH_100LE,\n // MESH_100MD,\n // MESH_100PA,\n // MESH_100TH,\n];\n\nwhile (obniz.sessionId === sessionId && obniz.connectionState === 'connected') {\n\n // Step1 scanして見つけたブロックをlistに入れていく\n node.warn(\"scan starting...\")\n await obniz.ble.scan.startWait(\n { localNamePrefix: \"MESH-100\" },\n { duration: 15 }\n );\n obniz.ble.scan.onfind = async (peripheral) => {\n\n if (!!obnizParts.meshblocks[peripheral.localName]) {\n //もうリストに入っている\n return;\n }\n const blockTypeClass = targetBlockTypes.find(b => b.isMESHblock(peripheral));\n if (!blockTypeClass) {\n return;\n }\n node.warn(\"found new MESH Block :\" + peripheral.localName);\n obnizParts.meshblocks[peripheral.localName] = new blockTypeClass(peripheral);\n await obniz.ble.scan.endWait();\n };\n\n // scan停止まち\n while (obniz.ble.scan.state !== 'stopped') {\n await sleep(100);\n }\n node.warn(\"scan stopped\")\n\n // Step2 リストを順番に接続していく\n for (let blockName in obnizParts.meshblocks) {\n const block = obnizParts.meshblocks[blockName];\n if (!block.peripheral.connected) {\n node.warn(\"connecting to \" + block.peripheral.localName);\n try {\n await block.connectWait();\n node.warn(\"connected to \" + block.peripheral.localName);\n } catch (e) {\n node.warn(\"connect failed to \" + block.peripheral.localName);\n }\n }\n }\n\n}"}]
動かしてみる