2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

obnizAdvent Calendar 2023

Day 1

node-red上でobnizとsony meshを繋いでみた

Last updated at Posted at 2023-11-30

sony meshがいろんなセンサついていて便利なんですが、プログラム書かないといないのがネックだ・・!と言う声を聞くので、node-red上で使ってみました。

MESHのボタンを押したらMESHのLEDが光る、というものを作ります。

obnizノードは0.7.0が最新です。こちらのノードを入れた前提でのプログラムになります
ss.png

大枠方針

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);
            }
        }
    }

}

こちらを”初期化処理”の方に入れます。

ss.png

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}"}]

動かしてみる

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?