はじめに
このブログはスマートライト株式会社様でのインターン実習で行った活動内容を記述した内容である。
今回はNode-REDを使用してEnOceanの「Easyfit Single」スイッチからデータを受信する方法について紹介する。
Node-REDとは

Node-REDは、JavaScriptをベースにしたオープンソースのフロープログラミングツールである。IBMによって開発され、IoTデバイスやAPI、オンラインサービスなどを簡単に接続して、自動化ワークフローを構築することができる。ビジュアルエディタを使用して、ノードをドラッグ&ドロップすることで簡単にフローを作成することができる。
EnOceanとは

引用元:https://www.enocean-alliance.org/ja/
EnOceanは、無線通信を利用してエネルギーハーベスティング技術を採用したセンサーおよびスイッチソリューションを提供する企業である。EnOceanのデバイスは、バッテリーレスで長期間動作することが特徴である。「Easyfit Single」スイッチは、EnOceanの技術を使用したワイヤレススイッチで、エネルギーハーベスティングにより電力を供給する。
使用デバイス
EnOcean USBゲートウェイ USB400J

USB400Jは、EnOceanの無線通信をPCやゲートウェイに簡単に接続するためのUSBデバイスである。このデバイスを使用することで、EnOcean対応のセンサーやスイッチからのデータを受信し、それをPCや他のデバイスに転送することができる。
製品情報:https://www.switch-science.com/products/1845
Easyfit Single

Easyfit Singleスイッチは、EnOcean技術を使用したバッテリーレスのワイヤレススイッチである。
エネルギーハーベスティング技術により、ボタンを押す際のエネルギーで動作する。
製品情報:https://00m.in/NnbOS
準備
・シリアルポートのインストール
Node-REDでUSBドングルを使用する際はシリアルポートが必要となるため、
「node-red-node-serialport」をインストールする必要がある。
↓インストール方法は下記の通りである。
①右上のハンバーガーメニューを押す
➁パレットの管理を選択
➂ノードを追加のタブを選択
➃「node-red-node-serialport」を検索し、追加/インストールする


インストールに成功すると、ネットワークのノード欄にserial系のノードが追加される。

実装方法
①USBドングル挿入
「Easyfit Single」スイッチを使用するために、PCにUSBドングルを挿入する。

➁「serial in」ノードをドラッグ&ドロップし、フローに追加する。
この時、「serial in」から「serial」と表示されるが問題ない。

➂serialノードをダブルクリックしてノードの編集を行う。
・初めてポートを使用する際は「ペンマーク」をクリックし、プロパティの設定を行う。

・次に「虫眼鏡マーク」をクリックし、通信を行うUSBドングルが挿入されたシリアルポートを選択する。

この時、「COM~」または/dev/cu.usbserial~~が出てくるが、後者であればusbserialの方を選択、前者であれば挿入しているポート番号を選択する。ポート番号が分からない場合はデバイスマネージャーからポートの確認を行う。
更新→完了を押した後に、一度デプロイを行う。
ここまでのserialport設定が正常に行えていた場合、「接続済み」と表示される。

➃functionノードを加え、受信データをデコードするコードを書き込む。
var date = new Date();
//
var ESP3_Packet = msg.payload;
//
var Header = ESP3_Packet.slice(1, 5);
var DataLength = 256 * ESP3_Packet
+ ESP3_Packet
;
//
var RawData = ESP3_Packet.slice(6, 6 + DataLength);
var ERP2_Header = RawData.slice(0, 1).toString("hex");
var EEP = "RPS";
var OriginatorID = "00000000";
var Data1 = "00";
var Data4 = "00000000";
//
var OptionalData = ESP3_Packet.slice(6 + DataLength, 8 + DataLength);
var SubTelNum = OptionalData.slice(0, 1);
var dBm = OptionalData.slice(1, 2);
//
switch (ERP2_Header) {
//normal telegram
case "20"://RPS telegram
EEP = "RPS";
OriginatorID = RawData.slice(1, 5).toString("hex");
Data1 = RawData.slice(5, 6).toString("hex");
break;
case "21"://1BS normal telegram
EEP = "1BS";
OriginatorID = RawData.slice(1, 5).toString("hex");
Data1 = RawData.slice(5, 6).toString("hex");
break;
case "22"://4BS normal telegram
EEP = "4BS";
OriginatorID = RawData.slice(1, 5).toString("hex");
Data4 = RawData.slice(5, 9).toString("hex");
break;
//teach-in telegram
case "61"://1BS teach-in telegram
EEP = "1BS teach-in";
OriginatorID = RawData.slice(3, 7).toString("hex");
Data1 = RawData.slice(7, 8).toString("hex");
break;
case "62"://4BS teach-in telegram
EEP = "4BS teach-in";
OriginatorID = RawData.slice(3, 7).toString("hex");
Data4 = RawData.slice(7, 11).toString("hex");
break;
default:
break;
}
var SwitchState = global.get('buttonState_' + OriginatorID) || "OFF";
if (Data1 === "84" || Data1 === "88") { // ボタン押下時のデータ
SwitchState = (SwitchState === "OFF") ? "ON" : "OFF";
global.set('buttonState_' + OriginatorID, SwitchState); // 新しい状態を保存
} else if (Data1 === "00") {
return null;
}
msg.payload = {
Time: date.toString(),
OriginatorID: OriginatorID,
SwitchState: SwitchState,
EEP: EEP,
Data1: Data1,
Data4: Data4,
SubTelNum: SubTelNum,
dBm: dBm,
};
return msg;
参照:https://ermine.co.jp/2017/10/08/node-red_enocean/#google_vignette
このコードはアーミン株式会社の服部さんが公開しているものを参照し、
以下の処理を加えたものである。
グローバル変数を用いて、現在のスイッチの状態を取得。
最初の初期値をOFFとして設定している。
スイッチが押され、84もしくは88のデータが受信された場合に、
スイッチの状態がOFFであれば、ONにする。
変更されたスイッチの状態をグローバルコンテキストに保存する。
これにより、スイッチが押されるたびにスイッチの状態(ON/OFF)をトグルすることができる。
➄switchノードを加え、プロパティに「.OriginatorID」を追記する。
文字列に指定したID(OriginatorID)を追加する。

これにより、指定した通信結果のみを表示することができる。
➅最後にデバッグノードを追加し、それぞれのノードを繋ぐ。

⑦デプロイをした後、一回目にスイッチを押した時にON・OFF、二回目にスイッチを押した時に一回目と逆の結果がSwitchStateに表示される。
その後も、スイッチが押されるたびにONとOFFの状態がトグルすれば成功となる。
