Intern

EnOcean温湿度照度センサのデータをGrafanaで可視化させる(6日目)

はじめに

今回は「EnOcean IoTマルチセンサー EMSIJ」からデータを取得させているNode-REDの作成済みのフローの解析・解説と、そこから取得したデータをInfluxDBに格納後、Grafanaで可視化させる方法を紹介する。

使用デバイス

・EnOcean IoTマルチセンサーEMSIJ

製品情報:https://www.enocean-alliance.org/ja/product/emsij-iot-multisensor-928-mhz/
当社商品紹介サイト:https://smartlight.co.jp/product/enocean-iot-multi-sensor-emsij/

EMSIJはEnOcean(928MHz)無線規格に基づいて通信する太陽電池発電による無線IoTセンサー。主なアプリケーションは、「温度、湿度、照度、加速度/姿勢の測定」のための壁掛け型または機器取り付け型のセンサー。iOSやAndroid用のNFCアプリEnOceanToolで設定をすることが可能。

EnOcean USBゲートウェイ USB400J

製品情報:https://www.switch-science.com/products/1845

USB400Jは、EnOceanの無線通信をPCやゲートウェイに簡単に接続するためのUSBデバイスである。このデバイスを使用することで、EnOcean対応のセンサーやスイッチからのデータを受信し、それをPCや他のデバイスに転送することができる。

準備

セットアップ

 Node-RED、InfluxDB、Grafanaのセットアップと起動に関しては過去のブログを参照

スイッチのON/OFFをGrafanaで時系列表示(4・5日目) はじめに Easyfit SingleスイッチのON・OFFデータをNode-REDで取得し、InfluxDBでデータを格納...


➁ USBドングル挿入
「EnOcean IoTマルチセンサーEMSIJ」センサーを使用するために、PCにUSBドングルを挿入する。

フロー解説

① 「シリアル」ノード

 ・EnOceanデバイスからのシリアルデータをUSB400Jモジュールから受信するために使用される

➁「Function」ノード(変換用)

 ・このノードの目的は、受信した複雑なバイナリデータを人間やシステムが扱いやすい形式に変換すること。これにより、次のノードが必要な情報に簡単にアクセス可能となる。

// データそのもの
var buf = msg.payload;
// データのコピー(検証用)
var rawData = buf.slice(0, buf.length);
// 取り出しやすいようにhex変換したもの
var rawByte = buf.toString("hex");
// ESP3仕様のdataLengthを拾う
var dataLength = 255 * buf + buf;
// ESP3仕様のoptionalLengthを拾う
var optionalLength = buf;
// packetType
var packetType = buf;
// headerCRC
var headerCRC = buf[5];
// dataLengthに基づいたデータ部分の切り出し
var rawDataByte = buf.slice(7, 7 + dataLength + 2);

var id = rawDataByte.slice(0, 4).toString("hex");

// payloadに格納
msg.payload = {
    rawData: rawData,
    rawByte: rawByte,
    dataLength: dataLength,
    optionalLength: optionalLength,
    packetType: packetType,
    headerCRC: headerCRC,
    rawDataByte: rawDataByte,
    ID: id
}

return msg;

➂ 「Switch」ノード

 ・受信したメッセージのIDに基づいてメッセージを異なる出力ポートに振り分ける役割を果たす。具体的には、メッセージのIDが特定の値に一致するかどうかをチェックし、一致する場合は対応する出力ポートにメッセージを送る。

➃ 「Function」ノード(解析用)

 ・センサーから受信したデータを解析し、各種センサー値(温度、磁力、照度、湿度)を抽出してメッセージに格納する。また、グローバル変数を使って照度の最大値と最小値を追跡する。

const rawData = msg.payload.rawDataByte;

// Extract basic information
msg.id = rawData.slice(0, 4).toString('hex');
msg.dbm = rawData[15] * -1;
msg.stm550count = 1;
msg.type = 'STM550';

// Extract data bytes
const d0 = 4;
const data = Array.from({ length: 9 }, (_, i) => rawData[d0 + i].toString(2).padStart(8, '0'));

msg.data = {
    data_8: data[0],
    data_7: data,
    data_6: data,
    data_5: data,
    data_4: data,
    data_3: data[5],
    data_2: data[6],
    data_1: data[7],
    data_0: data[8]
};

// Calculate temperature
const temp = data[0] + data.slice(0, 2);
msg.temperature = Math.round((parseInt(temp, 2) / 10 - 40) * 100) / 100;

// Calculate magnet
msg.magnet = parseInt(data[8].slice(3, 4), 2);

// Calculate illumination
const illumination = data.slice(2) + data + data.slice(0, 3);
msg.illumination = parseInt(illumination, 2);

const IllValue = msg.illumination;
let IllmaxValue = global.get('maxIll2') || 0;
let IllminValue = global.get('minIll2') || 1000;

if (IllmaxValue < IllValue) {
    IllmaxValue = IllValue;
    global.set('maxIll2', IllmaxValue);
}
if (IllminValue > IllValue) {
    IllminValue = IllValue;
    global.set('minIll2', IllminValue);
}

global.set('Ill', IllValue);

// Calculate humidity
const humidity = data.slice(2, 6) + data.slice(0, 2);
msg.humidity = Math.round(parseInt(humidity, 2) * 20) / 10;

// Aggregate data
msg.payload = {
    id: msg.id,
    dbm: msg.dbm,
    stm550count: msg.stm550count,
    type: msg.type,
    temperature: msg.temperature,
    magnet: msg.magnet,
    illumination: msg.illumination,
    humidity: msg.humidity,
    time: Date.now()
};

return msg;

➄ 「MQTTブローカー」ノード

 ・指定されたMQTTブローカーに対して安全にデータを送信するように構成されている。これにより、解析されたEnOceanデータがリアルタイムで他のシステムやデバイスに配信される。

➄ 「デバッグ」ノード

 ・センサーのデータを正常に取得できているか確認するために使用

 ・以下の内容が取得、デバッグで表示される

1. dbm = 信号強度(値が低いほど信号が弱い)
2. temperature = 温度
3. magnet = 磁力
4. illumination = 照度(ルーメン(照度の値))
5. humidity = 湿度(%)
6. time = データが記録された時間

InfluxDBでデータを格納

① Node-REDのフロー変更

MQTT-OUT」ノード →「Influxdb out」ノード

➁ 「Influxdb out」ノード を編集(設定した内容を入力)

  1. Organization ・・・ 組織名
  2. Bucket ・・・ バケット名
  3. Measurement ・・・ 自身で指定
  4. URL ・・・ http://localhost:8086
  5. Token ・・・APIトークン

➂ InfluxDBのDataExplorerでデータの確認

  「フィールド」を変更することで確認したいデータ(照度・温度・湿度等)を確認することが可能

Grafanaでデータの可視化

① 左上のメニューから「Connections」→「Data Sources」→「influxdb
  バケットAPIトークンを変更した場合はここで編集する

➁ 左上のメニューから「Dashboards」→「+ Create Dashboard」 → 「ADD Visualization」 → 「influxdb」を選択

➂ 下記のコードをクエリに入力 → 「Apply

from(bucket: "mqtt")
  |> range(start: -30d) // 過去30日のデータを取得
  |> filter(fn: (r) => r._measurement == "mqtt_influx")
  |> filter(fn: (r) => r._field == "temperature" or r._field == "illumination" or r._field == "humidity" or r._field == "dbm" or r._field == "magnet")
  |> limit(n: 100) // 直近の100件を表示

→ このようなグラフが表示されれば可視化成功