Node-Redでスマート電力量メーターと通信してみる

Raspberry PiにNode-Redを導入すると、簡単にシリアル通信を行えます。
シリアル通信ができるということは、USBにシリアルポートが乗っかっているこんなのも動かせるということです。

https://www.tessera.co.jp/rl7023stick-d_ips.html

Raspberry Piに挿してスマート電力量メーターから家の消費電力を読んだりできたりする奴です。
多くの先達の方々のお知恵とおコードを拝借することで、私のRaspberry Piにもなんとか導入することができました。

今回は、手元にあるHEMS用 Wi-SUNモジュール RL7023（以下、HEMS）をRaspberry Piに挿してNode-Redのシリアル通信を使い、スマート電力量メーターと通信して瞬間電力を取得するところまでやってみます。

なお、次の記事などを参考にさせていただきました。

https://qiita.com/rukihena/items/82266ed3a43e4b652adb

https://github.com/shakemid/hems-bp35a1

https://netlog.jpn.org/r271-635/2020/11/echonet-smartmeter-serialaccess.html

通信仕様であるECHONET Liteの規格書はこちらです。

https://echonet.jp/spec_g/

>アプリケーション通信インターフェース仕様書 > 低圧スマート電力量メータ・HEMSコントローラ間

:::note warn
HEMS機器の安易な取り扱いやデータの読み間違いは意図しない重大な結果につながるので要注意です。
:::

#目次
[1.必要なもの](#1-必要なもの)
[2.シリアル通信をためす](#2-シリアル通信をためす)
[3.フローの説明](#3-フローの説明)
[4.実行してみる](#4-実行してみる)
[5.おわりに](#5-おわりに)

#1. 必要なもの

+ HEMS用 Wi-SUNモジュール RL7023
+ Raspberry Pi
+ Node-Red
+ 電力会社に発行してもらったBルートのIDとパスワード

#2. シリアル通信をためす

##serialportノードのインストール

まずは、Node-Redにserialportノードをインストールします。
右上のハンバーガー > パレットの管理 > ノードを追加で`node-red-node-serialport`を検索、追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/c6795f2d-d748-e243-a1c0-7dd20d62f04a.png)

インストールできたら左側のパレットにserialportノードが追加されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/d1686f9b-a733-72d5-03f3-deb8d77ac2a4.png)

##serialportノードを使ってみる

こんな感じに組み立てます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/0ad7326f-f38e-4e6d-5c54-4383bed500f1.png)

###"SKVER"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/6b8f9a98-0b4f-2670-ac77-618306d8a6de.png)

このノードのプロパティです。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/df803f16-92d8-168b-1d9b-26ae052824b6.png)

文字列"SKVER"を作ります。

###"payload & "\r""changeノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/934d7c3f-5f79-df8d-ada0-7323ecfa6805.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/86ba8f73-ff96-04de-290c-0699a519b5af.png)

上流から来るコマンド文字列にコントロール文字"\r"を付加するノードです。

###"HEMSシリアル OUT"serial outノード


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/52c00c26-261c-1835-f355-414848ee8ff6.png)

HEMSにシリアル送信を行うノードです。
固有名を`HEMSシリアル OUT`に変えてあります。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/00c21430-f448-7419-d9c8-219a1bb3a939.png)

鉛筆ボタンを押して新しくプロパティを作ります。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/7926f1c2-1808-96e7-9d82-2293a2166215.png)

###"HEMSシリアル IN"serial inノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/9dc5f847-30ce-38b4-b6dd-c70970e6469e.png)

HEMSからシリアル受信を行うノードです。

プロパティは"HEMSシリアル OUT"ノードで設定したものを選択します。

###`debug`ノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/90106593-75e9-b8e0-9d7f-4199c4e4addb.png)

上流から流れてくる`msg.payload`、つまりHEMSの吐き出すレスポンスを受けて、デバッグ欄に表示します。

###実行
ではこのフローを実行してみましょう。

デプロイして、injectノードのボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5e8f2e6e-e1c3-f125-dd44-de34d0fd4a85.png)

Pythonでの結果と同じになりました。

こんな感じで最後までコマンドを並べていきます。

#3. フローの説明

###完成形
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/47961725-fdb4-99cf-1906-b6ab000b4dae.png)

上から順にフローを説明します。
なお、"HEMSシリアル IN"ノードと"HEMSシリアル OUT"ノードは前述のものをそのまま使います。

なお、このフローはPythonプログラムのコードやログを参考にして作ったハリボテのようなものなので、違う環境ではうまく作動しないかもしれません。たとえば、本来ならコマンドの戻り値から取得すべき電力量の桁数を勝手に固定したりしています。

###"ここにプロパティを設定する"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/bf2a5105-a92f-91b0-8dd9-6f53b0b9f220.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/898110b6-ea65-0571-7548-bffd4e15da12.png)

電力会社が発行したBルートのIDとパスワードをここに入力します。

###"ローカル変数 to フロー変数"changeノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/1f935f30-4a5b-e4dd-7801-4e4cafed85d6.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/ed35cdf4-b5cf-1675-bb38-7b6cca78213e.png)

上のノードで設定したIDとパスワードを、このタブ内をスコープとするフロー変数に代入します。

###"SKSETPWD C **********"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5926ee14-d121-5506-a324-a38a03412798.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/2afd159c-0c61-2858-18fc-80bab8422d8d.png)

Bルートのパスワードをセットするコマンド文字列を作ります。
パスワードはフロー変数に代入した文字列を使います。

###"SKSETRBID ********************************"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/51e8a650-4a5d-7255-2c58-79064e7436c1.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/c5bc5ce8-035d-a83b-4dd3-2407aed38c25.png)

同じくBルートのIDをセットするコマンド文字列を作ります。

###"SKSCAN 2"injectノード群

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/faf9e8c4-15c4-e3d4-a316-a55c76710575.png)

各ノード名のコマンド文字列を作ります。
名前と中身は同じです。

###"SKSREG S2 **"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/8b04d38d-24e7-adb1-ae61-547e1b81b7a3.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/cc61b814-bd1e-5048-6640-438e19415f9e.png)

"SKSCAN 2"ノード群のコマンドのレスポンスに含まれる"  Channel:"に続く文字列を使い、コマンド文字列を作ります。

###"SKSREG S3 ****"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/3dc914f5-e9f2-f0e2-e75f-0bd9ca65e489.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/a12d4c48-e374-5bf9-6f06-5b7a6d34dcdf.png)

"SKSCAN 2"ノード群のコマンドのレスポンスに含まれる"  Pan ID:"に続く文字列を使い、コマンド文字列を作ります。

###"SKLL64 ****************"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/6b3c82eb-d6f2-eae2-4aef-cb7aa1d6f782.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5ba461f1-7236-5f41-e84a-20bd1da1ef81.png)

"SKSCAN 2"ノード群のコマンドのレスポンスに含まれる"  Addr:"に続く文字列を使い、コマンド文字列を作ります。

###"SKJOIN ****:****:****:****:****:****:****:****"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/49d9aeff-9c39-8b5d-71a0-d5cc24147a2c.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/0258e9ba-14d4-7c0b-413c-7e31b10382e8.png)

"SKLL64 ****************"ノードのコマンドのレスポンスに含まれるIPv6アドレス文字列を使い、コマンド文字列を作ります。

###"ipv6Addr"injectノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5b43d3f7-1731-a851-9e1b-e30bfad68fa7.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/deabc427-18f6-a77e-90ca-b8aa94e30a4a.png)

"SKLL64 ****************"ノードのコマンドのレスポンスに含まれるIPv6アドレス文字列を使い、コマンド文字列を作ります。

###"SKSENDTO"functionノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5a322f7b-9c9c-bfb2-531d-f691648ea540.png)

```js:"SKSENDTO"functionノードのプロパティ
//"SKSENDTO 1 "
var buf1 = Buffer.from("SKSENDTO 1 ",'ascii');

//ipv6Addr
var buf2 = Buffer.from(msg.ipv6Addr,'ascii');

//" 0E1A 1 000E "
var buf3 = Buffer.from(" 0E1A 1 000E ",'ascii');

//echonetLiteFrame
var buf4 = new Buffer([16,129,0,1,5,255,1,2,136,1,98,1,231,0]);

//結合
msg ={payload: Buffer.concat([buf1,buf2,buf3,buf4])};

return msg;
```
"SKSENDTO"コマンドを組み立てます。
このコマンドだけは、文字列＋バイナリの組み合わせなので、文字列の部分を一度バイナリに変換してから結合します。

###"HEMSシリアル OUT(binary)"serial outノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/192526f5-b261-915d-50e7-ee4b3ea1a54f.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/efd82627-01a9-ec62-7779-e1c0d0012ef4.png)

SKSENDTOはバイナリとして送信するので、バイナリ用のserial outノードを用意します。
プロパティもバイナリ用にします。

ここで、自動で付与されるプロパティ名が前のものと同じになってしまい、順番でしか区別できなくなってしまいました。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/14bed144-986b-585a-733d-85caeae7a119.png)

これが原因なのかは分かりませんが、バイナリで送ったはずが文字列で届いたりその逆になったりすることがあります。そのようなときは、Raspberry Piを再起動すれば直ります。
(追記)最初からシリアル送受信を素直にバイナリで統一すればいいだけですね。

###"戻り値?"switchノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/a6076e9c-a54e-1874-e113-5290db5f952f.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5ccf4bec-7b21-ebf6-0347-75a634fc11ec.png)

HEMSが返す戻り値に応じて出力先ノードを分岐させます。

###changeノード群

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/e87f3bca-0b88-858e-4fb1-b5bfd9e95709.png)
 
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/3abcc0cc-49df-6dcc-590f-9539f4d1c7cb.png)
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5a78a890-2ed5-094a-d757-13f342b0bed8.png)
 
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/b7399201-a034-d9aa-2bb6-d4b1cfac6d46.png)
 
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/ef04939a-f535-fc2b-4650-98d27444c437.png)
 
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/01e9eb6a-8099-da52-080a-8a78721796c2.png)
 
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/5b3720d0-d6ad-6cf3-f50b-402f42631203.png)

コマンドを構成するのに必要な目的の文字列を抽出し、フロー関数に代入しているだけです。
なお、うちの環境では、channel以外の文字列は毎回同じです。

###"プロパティがセットされました"changeノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/eb5afe4b-8997-b9dc-65e5-ca6a4921665c.png)

フロープロパティのセットを通知する文字列を作ります。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/e2e10d47-3770-3143-466c-2f0ed119ca55.png)

###"ERXUDP type E7?"switchノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/1bf12c29-e4f1-6ece-68c7-a7f7bdd2cb1e.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/1a4dfdc4-09f9-db2a-a68e-5c1b4414c105.png)

"ERXUDP"に続く所定の位置に戻り値"E7"(瞬間電力に対応する)が含まれている場合に処理を続行します。

###"E7 瞬間電力"changeノード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/b2cdac0c-c149-a366-4e4b-40fa00394835.png)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/fc090b0f-1186-fff7-7a55-1874ec77b38d.png)

バイナリを文字情報に整形します。

#4. 実行してみる

一番上の"ここにプロパティを設定する"ノードから、一番下の"ipv6Addr"ノードまで、順次injectノードのボタンを押していきます。
ボタンを押すたびに、"OK"や"EVENT"などの文字列が、デバッグサイドバーに流れてくるはずです。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/92082b08-3c90-9689-2d87-82cd06ff4381.png)

最後の"ipv6Addr"injectノードを押すと、

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495297/d13c8a8a-9bff-3110-a877-e832722173df.png)

瞬間電力が表示されました。ゴール。

#5. おわりに

Node-Redなので、グラフ化するなりGoogle Homeに電気の使い過ぎを叱らせるなり簡単にできますね。
今回作ったフローは下に置いておきます。

<details><summary><b>HEMSフロー(折りたたみ)</b></summary><div>

```js
[
    {
        "id": "49beefd0eaaf4a6a",
        "type": "tab",
        "label": "HEMS",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "4004cb5a58699790",
        "type": "group",
        "z": "49beefd0eaaf4a6a",
        "name": "送信",
        "style": {
            "label": true
        },
        "nodes": [
            "2676c4e4fe9a5cda",
            "088e6715e70f860b",
            "4298251172f4c4c3",
            "568a2a591ea46393",
            "f98f4db8cd3fa410",
            "04ba53300916f691",
            "fb0ec04ac6017b63",
            "b5b896577e1dfb6e",
            "bd3b1ed9c465bd25",
            "a3676484db745daf",
            "1b2d3525c7d2b087",
            "586161e167f95ec3",
            "121e6c6caf8f860d",
            "a907cc6497817aba",
            "f71e06ec28f4697e",
            "540cf633b17078cf",
            "cbd2a4b12cf35653",
            "f537dfd40e07e6bd"
        ],
        "x": 14,
        "y": 139,
        "w": 712,
        "h": 622
    },
    {
        "id": "c4ce45e52323bd56",
        "type": "group",
        "z": "49beefd0eaaf4a6a",
        "name": "受信",
        "style": {
            "label": true
        },
        "nodes": [
            "ddf19b92b483e25e",
            "ab5a9c17d4c8836b",
            "503cce7c41dea089",
            "d2e6294be1e3a289",
            "654ef31eb665b02f",
            "6c3fa15c620fc0f9",
            "929eac3f8def68a5",
            "c808eac7e16ce186",
            "b3e040a515863bd0",
            "346d61d741e5286d",
            "96f4a4f19d93331a",
            "cf825221ed020904",
            "39362c73fd180a16"
        ],
        "x": 14,
        "y": 779,
        "w": 712,
        "h": 422
    },
    {
        "id": "2676c4e4fe9a5cda",
        "type": "serial out",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "HEMSシリアル OUT",
        "serial": "92c4fb6c.c8bcd8",
        "x": 600,
        "y": 180,
        "wires": []
    },
    {
        "id": "088e6715e70f860b",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKVER",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SKVER",
        "payloadType": "str",
        "x": 110,
        "y": 180,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "4298251172f4c4c3",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "payload & \"\\r\"",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload & \"\\r\"",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 450,
        "y": 420,
        "wires": [
            [
                "2676c4e4fe9a5cda",
                "f71e06ec28f4697e"
            ]
        ]
    },
    {
        "id": "568a2a591ea46393",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKSETPWD C **********",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"SKSETPWD C \" & $flowContext(\"pwd\")",
        "payloadType": "jsonata",
        "x": 160,
        "y": 220,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "f98f4db8cd3fa410",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKSETRBID ********************************",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"SKSETRBID \" & $flowContext(\"rbid\")",
        "payloadType": "jsonata",
        "x": 210,
        "y": 260,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "04ba53300916f691",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SKSCAN 2 FFFFFFFF 4",
        "payloadType": "str",
        "x": 180,
        "y": 360,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "fb0ec04ac6017b63",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SKSCAN 2 FFFFFFFF 5",
        "payloadType": "str",
        "x": 180,
        "y": 400,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "b5b896577e1dfb6e",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SKSCAN 2 FFFFFFFF 6",
        "payloadType": "str",
        "x": 180,
        "y": 440,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "bd3b1ed9c465bd25",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKSREG S2 **",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"SKSREG S2 \" & $flowContext(\"channel\")",
        "payloadType": "jsonata",
        "x": 140,
        "y": 500,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "a3676484db745daf",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKSREG S3 ****",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"SKSREG S3 \" & $flowContext(\"panid\")",
        "payloadType": "jsonata",
        "x": 140,
        "y": 540,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "1b2d3525c7d2b087",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKLL64 ****************",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"SKLL64 \" & $flowContext(\"addr\")",
        "payloadType": "jsonata",
        "x": 160,
        "y": 580,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "586161e167f95ec3",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKJOIN ****:****:****:****:****:****:****:****",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "\"SKJOIN \" & $flowContext(\"ipv6addr\")",
        "payloadType": "jsonata",
        "x": 210,
        "y": 620,
        "wires": [
            [
                "4298251172f4c4c3"
            ]
        ]
    },
    {
        "id": "121e6c6caf8f860d",
        "type": "comment",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "以下3個のどれかで\"EVENT 20\"が出ればよい。（時間がかかる）",
        "info": "",
        "x": 270,
        "y": 320,
        "wires": []
    },
    {
        "id": "a907cc6497817aba",
        "type": "serial out",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "HEMSシリアル OUT(binary)",
        "serial": "5205cde260160cea",
        "x": 475,
        "y": 660,
        "wires": [],
        "l": false
    },
    {
        "id": "f71e06ec28f4697e",
        "type": "debug",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 220,
        "wires": []
    },
    {
        "id": "540cf633b17078cf",
        "type": "debug",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 720,
        "wires": []
    },
    {
        "id": "cbd2a4b12cf35653",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "ipv6Addr",
        "props": [
            {
                "p": "ipv6Addr",
                "v": "$flowContext(\"ipv6addr\")",
                "vt": "jsonata"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 120,
        "y": 660,
        "wires": [
            [
                "f537dfd40e07e6bd"
            ]
        ]
    },
    {
        "id": "f537dfd40e07e6bd",
        "type": "function",
        "z": "49beefd0eaaf4a6a",
        "g": "4004cb5a58699790",
        "name": "SKSENDTO",
        "func": "//\"SKSENDTO 1 \"\nvar buf1 = Buffer.from(\"SKSENDTO 1 \",'ascii');\n\n//ipv6Addr\nvar buf2 = Buffer.from(msg.ipv6Addr,'ascii');\n\n//\" 0E1A 1 000E \"\nvar buf3 = Buffer.from(\" 0E1A 1 000E \",'ascii');\n\n//echonetLiteFrame\nvar buf4 = new Buffer([16,129,0,1,5,255,1,2,136,1,98,1,231,0]);\n\n//結合\nmsg ={payload: Buffer.concat([buf1,buf2,buf3,buf4])};\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 310,
        "y": 660,
        "wires": [
            [
                "a907cc6497817aba",
                "540cf633b17078cf"
            ]
        ]
    },
    {
        "id": "3bd5c618626c1fdf",
        "type": "inject",
        "z": "49beefd0eaaf4a6a",
        "name": "ここにプロパティを設定する",
        "props": [
            {
                "p": "rbid",
                "v": "IDBルートのID",
                "vt": "str"
            },
            {
                "p": "pwd",
                "v": "Bルートのパスワード",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 180,
        "y": 100,
        "wires": [
            [
                "b8a00d9096f95b6c"
            ]
        ]
    },
    {
        "id": "2668e4f95c526673",
        "type": "debug",
        "z": "49beefd0eaaf4a6a",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 100,
        "wires": []
    },
    {
        "id": "b8a00d9096f95b6c",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "name": "ローカル変数 to フロー変数",
        "rules": [
            {
                "t": "set",
                "p": "rbid",
                "pt": "flow",
                "to": "rbid",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "pwd",
                "pt": "flow",
                "to": "pwd",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 440,
        "y": 100,
        "wires": [
            [
                "2668e4f95c526673"
            ]
        ]
    },
    {
        "id": "088f905780f0c11b",
        "type": "comment",
        "z": "49beefd0eaaf4a6a",
        "name": "上のinjectノードから順に押す",
        "info": "",
        "x": 140,
        "y": 40,
        "wires": []
    },
    {
        "id": "ddf19b92b483e25e",
        "type": "serial in",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "HEMSシリアル IN",
        "serial": "92c4fb6c.c8bcd8",
        "x": 130,
        "y": 820,
        "wires": [
            [
                "ab5a9c17d4c8836b",
                "929eac3f8def68a5"
            ]
        ]
    },
    {
        "id": "ab5a9c17d4c8836b",
        "type": "debug",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 610,
        "y": 820,
        "wires": []
    },
    {
        "id": "503cce7c41dea089",
        "type": "debug",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 610,
        "y": 1160,
        "wires": []
    },
    {
        "id": "d2e6294be1e3a289",
        "type": "switch",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "ERXUDP type E7?",
        "property": "type",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "E7",
                "vt": "str"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 230,
        "y": 1160,
        "wires": [
            [
                "6c3fa15c620fc0f9"
            ],
            []
        ],
        "outputLabels": [
            "E7",
            ""
        ]
    },
    {
        "id": "654ef31eb665b02f",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "ERXUDP",
        "rules": [
            {
                "t": "set",
                "p": "type",
                "pt": "msg",
                "to": "$substring(payload,145,2)",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "$substring(payload,149)",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "byte",
                "pt": "msg",
                "to": "$substring(payload,147,2)",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 320,
        "y": 880,
        "wires": [
            [
                "d2e6294be1e3a289"
            ]
        ]
    },
    {
        "id": "6c3fa15c620fc0f9",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "E7 瞬間電力",
        "rules": [
            {
                "t": "set",
                "p": "watt",
                "pt": "msg",
                "to": "$parseInteger($string(\"0x\"&payload),'0')",
                "tot": "jsonata"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "\"E7 瞬間電力 \"& watt &\" [W]\"",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 430,
        "y": 1160,
        "wires": [
            [
                "503cce7c41dea089"
            ]
        ]
    },
    {
        "id": "929eac3f8def68a5",
        "type": "switch",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "戻り値?",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "cont",
                "v": "ERXUDP",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "  Channel:",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "  Pan ID:",
                "vt": "str"
            },
            {
                "t": "cont",
                "v": "  Addr:",
                "vt": "str"
            },
            {
                "t": "regex",
                "v": "^....:....:....:....:....:....:....:....\\r\\n$",
                "vt": "str",
                "case": false
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 6,
        "x": 140,
        "y": 940,
        "wires": [
            [
                "654ef31eb665b02f"
            ],
            [
                "346d61d741e5286d"
            ],
            [
                "b3e040a515863bd0"
            ],
            [
                "96f4a4f19d93331a"
            ],
            [
                "c808eac7e16ce186"
            ],
            []
        ]
    },
    {
        "id": "c808eac7e16ce186",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "ipv6addr",
        "rules": [
            {
                "t": "set",
                "p": "ipv6addr",
                "pt": "flow",
                "to": "$substringBefore(msg.payload,\"\\r\\n\")",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 500,
        "y": 1040,
        "wires": [
            [
                "39362c73fd180a16"
            ]
        ]
    },
    {
        "id": "b3e040a515863bd0",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "  Pan ID:",
        "rules": [
            {
                "t": "set",
                "p": "panid",
                "pt": "flow",
                "to": "$substring(payload,9,4)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 500,
        "y": 960,
        "wires": [
            [
                "39362c73fd180a16"
            ]
        ]
    },
    {
        "id": "346d61d741e5286d",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "  Channel:",
        "rules": [
            {
                "t": "set",
                "p": "channel",
                "pt": "flow",
                "to": "$substring(payload,10,2)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 500,
        "y": 920,
        "wires": [
            [
                "39362c73fd180a16"
            ]
        ]
    },
    {
        "id": "96f4a4f19d93331a",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "  Addr:",
        "rules": [
            {
                "t": "set",
                "p": "addr",
                "pt": "flow",
                "to": "$substring(payload,7,16)",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 490,
        "y": 1000,
        "wires": [
            [
                "39362c73fd180a16"
            ]
        ]
    },
    {
        "id": "cf825221ed020904",
        "type": "debug",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 610,
        "y": 1100,
        "wires": []
    },
    {
        "id": "39362c73fd180a16",
        "type": "change",
        "z": "49beefd0eaaf4a6a",
        "g": "c4ce45e52323bd56",
        "name": "\"プロパティがセットされました\"",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "\"プロパティがセットされました \" & msg.payload",
                "tot": "jsonata"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 380,
        "y": 1100,
        "wires": [
            [
                "cf825221ed020904"
            ]
        ]
    },
    {
        "id": "92c4fb6c.c8bcd8",
        "type": "serial-port",
        "serialport": "/dev/ttyUSB0",
        "serialbaud": "115200",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "\\n",
        "bin": "false",
        "out": "char",
        "addchar": "",
        "responsetimeout": "1000"
    },
    {
        "id": "5205cde260160cea",
        "type": "serial-port",
        "serialport": "/dev/ttyUSB0",
        "serialbaud": "115200",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "100",
        "bin": "bin",
        "out": "time",
        "addchar": "",
        "responsetimeout": "10000"
    }
]
```