EnOcean STM 550B マルチセンサーモジュール(BLE) を obniz の BLE で取得するメモ
EnOcean STM 550B マルチセンサーモジュール(BLE) を obniz の BLE で取得するメモです。
経緯
https://twitter.com/1ft_seabass/status/1291984409663438848
中畑さんから
を試させていただいてます。そして obniz で BLE でつないでみます。
データを初めて取得する

ここは結構ハマったのですが、ポイントを書いておきます。
- 開封したら太陽電池のところに光を当ててしばらく十分に充電する。
- 充電が不十分で検証するとデータが来なくて検証しにくい。
- 説明サイトではデータを見るために加速度を変化させて「振ってみる」と書いてあり確かにそれで動くけれど初見で分かりにくいので注意
- 私は最初うまくいかなくてハマったので以下のやり方を推奨
そのやり方とは「LEARNボタンを2回素早く押して」データを強制的にデータを送ることで検証する方法です。
EnOcean STM 550B マルチセンサーモジュール(BLE) のほうは定期実行を待つと検証しにくいので、意識してやりたいならボタンテスト(2回早押し)で即座に送られるもので試すとよいです!
— Tanaka Seigo (@1ft_seabass) August 8, 2020
ボタンはこちら!そして、その向かいの側面にあるLEDがデータ送信時に赤く光ります。#obniz #BLE #EnOcean pic.twitter.com/QfqbjuzQTH
こちらでデータが送られると、

赤く丸で囲んだあたりにあるLEDが赤く一瞬光ります。
https://twitter.com/1ft_seabass/status/1291986188333510658
おかげさまで、無事取得できました。
注意
ただし、これ、疎通チェックのみで使いましょう。LEARNボタン使用時の中身のペイロードは、通常のセンサーデータが送られてくるものとは違うようです。

センサーデータをちゃんと解析する場合は、磁気センサー部分に磁石を押し当てる方法がやりやすいです。(はじめからそのやり方のほうが良かったかもしれない)
データ解析
データ解析で参考にした記事はこちらです。ありがとうございます!
- 自宅の環境センサーを「EnOcean STM 550B」に入れ替えた話 - Qiita
- Node-REDのフローから、実際の計算式の確認まわりで使わさせていただきました!
- EnOceanのBLE環境センサー「STM550B」をNode-REDで受信して解析した話|デジタルライト(Digital-light.jp)
- 中畑さんの解析記事。とてもわかりやすく、全体を参考にしました。とくに実際の解析後のデータ配列でセンサーデータを取得するところが助かりました!
- EnOcean BLE環境センサー(STM550B)とスイッチ(PTM215B)を試してみた。 - Qiita
- BLEデータ(ペイロード)の仕様、素のRAWデータを見るところであったり、BLEでの疎通を参考にしました!
obnizでのソースコード

実際に取得できたコードはこちらです。
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/obniz@3.7.0/obniz.js" crossorigin="anonymous"></script>
</head>
<body>
<!-- <div id="obniz-debug"></div> -->
<div class="container">
<div>
<h2>EnOcean STM 550B マルチセンサーモジュール(BLE)</h2>
</div>
<div>
<h3>[raw advertise data]</h3>
<div id="valueSTM550B">--</div>
<h3>[raw advertise data 16進数]</h3>
<div id="valueSTM550B2">--</div>
<h3>[Temperature]</h3>
<div id="temperature">--</div>
<h3>[Illumination_Sensor]</h3>
<div id="illumination">--</div>
<h3>[Humidity]</h3>
<div id="humidity">--</div>
<h3>[Magnet]</h3>
<div id="magnet">--</div>
</div>
</div>
<script>
let loopCount = 0;
const settings = {
duration: null
}
const obniz = new Obniz("Obniz_ID");
obniz.onconnect = async function () {
obniz.display.print("obniz BLE");
obniz.display.print(" ↑ ↓");
obniz.display.print("EnOcean");
await obniz.ble.initWait();
obniz.ble.scan.onfind = async function(peripheral){
if( peripheral.address === "XXXXXXXXXXXX"){ // 取得したいEnOcean STM 550B マルチセンサーモジュールのアドレスを記述
console.log("EnOcean STM 550B connect!" + new Date().getTime());
// 通常のアドバタイズデータ
const adv_data = peripheral.adv_data;
// 読解用。アドバタイズデータを16進法で表記することで Manufacturer ID の 0x03DA といった値が分かりやすくなります。
const adv_data16 = adv_data.map(
function(value){
return value.toString(16);
}
);
$('#valueSTM550B').text(adv_data.toString());
$('#valueSTM550B2').text(adv_data16.toString());
// 温度センサー
const temperature = ( adv_data[9] + adv_data[10] * 256 ) * 0.01;
$('#temperature').text(temperature);
// 湿度センサー
const humidity = adv_data[12] * 0.5;
$('#humidity').text(humidity);
// 照度センサー
const illumination = adv_data[14] + adv_data[15] * 256;
$('#illumination').text(illumination);
// 磁気センサー
const magnet = adv_data[22];
if( magnet === 1 ){
$('#magnet').text("ON");
} else if( magnet === 2 ){
$('#magnet').text("OFF");
}
// データを受信するたびに再スキャン
// 再スキャンは endWait を走らせると onfinish が発動するのでそこで再開させる
await obniz.ble.scan.clearAdvertisementFilter();
await obniz.ble.scan.endWait();
}
};
obniz.ble.scan.onfinish = async function(peripherals, error){
loopCount++;
console.log("scan timeout! [" + loopCount + "]");
// 再スキャンは endWait を走らせると onfinish が発動するのでそこで再開させる
await obniz.ble.scan.startWait(settings);
};
// 初回スタート
await obniz.ble.scan.startWait(settings);
}
</script>
</body>
</html>
取得したいEnOcean STM 550B マルチセンサーモジュールのアドレス
if( peripheral.address === "XXXXXXXXXXXX"){ // 取得したいEnOcean STM 550B マルチセンサーモジュールのアドレスを記述
こちらは、ifで絞り込む前に、何度かLEARNボタンをおして peripheral.address を console.log で確かめてキャッチできるようにしましょう。
センサー取得
こちらは EnOceanのBLE環境センサー「STM550B」をNode-REDで受信して解析した話 を参考にしましたが、Node-REDで取得するアドバタイズデータの配列と、今回の obniz で取得できる adv_data では、完全に位置が一致するわけではなく、ちょっとズレるのでそこは読み替えています。
計算式も、試行錯誤の末、こちらの記事と同じアプローチになっていたので大丈夫だと思います。検証でくる対象があるのはとってもありがたいです。
// 温度センサー
const temperature = ( adv_data[9] + adv_data[10] * 256 ) * 0.01;
$('#temperature').text(temperature);
// 湿度センサー
const humidity = adv_data[12] * 0.5;
$('#humidity').text(humidity);
// 照度センサー
const illumination = adv_data[14] + adv_data[15] * 256;
$('#illumination').text(illumination);
// 磁気センサー
const magnet = adv_data[22];
if( magnet === 1 ){
$('#magnet').text("ON");
} else if( magnet === 2 ){
$('#magnet').text("OFF");
}
スキャンし続ける流れ
obniz.ble.scan.onfind = async function(peripheral){
if( peripheral.address === "XXXXXXXXXXXX"){ // 取得したいEnOcean STM 550B マルチセンサーモジュールのアドレスを記述
console.log("EnOcean STM 550B connect!" + new Date().getTime());
// ~~~~~~~~~~~ 略 ~~~~~~~~~~~
// データを受信するたびに再スキャン
// 再スキャンは endWait を走らせると onfinish が発動するのでそこで再開させる
await obniz.ble.scan.clearAdvertisementFilter();
await obniz.ble.scan.endWait();
}
};
obniz.ble.scan.onfinish = async function(peripherals, error){
loopCount++;
console.log("scan timeout! [" + loopCount + "]");
// 再スキャンは endWait を走らせると onfinish が発動するのでそこで再開させる
await obniz.ble.scan.startWait(settings);
};
途中省略していますが、データを受信するたびに再スキャンしています。
この理由は、同じスキャン中だと同じアドレスが下りてこないケースがあり、それを愚直に回避するためです。読むたびに endWait で終了させています。そして、onfinish が発動するのでstartWaitで再開させています。
どうも settings の設定値 BleScanSetting | obniz をうまく使えば解決しそうですが、今回は動かせなかったので上記のようなアプローチをしています。
設定値でうまくいかないときも、処理で同じように作れることを知っておくことは大事。
動かしてみる
実際に動かしてみます。

obnizクラウドで実行してみます。

磁気センサーに磁石を押し当てて強制的にセンサーを反応させます。

実際に受け取ることができました!