Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9314

SwitchBot温湿度計からBluetoothで気温と湿度を取得する

$
0
0
SwitchBot温湿度計 から Bluetooth 通信で現在値を取得するメモ。 動作確認環境 macOS 12.1 node v17.3.0 npm v8.3.0 SwitchBot温湿度計 node-switchbot で値を取る OpenWonderLabsが公開しているnode-switchbotを使うと、非常に楽。 必要なモジュールをインストールして、 npm install @abandonware/noble npm install node-switchbot Quick Start のコードをapp.js等に保存して実行するだけで、値が取得できる。 // Load the node-switchbot and get a `Switchbot` constructor object const Switchbot = require('node-switchbot'); // Create an `Switchbot` object const switchbot = new Switchbot(); (async () => { // Start to monitor advertisement packets await switchbot.startScan(); // Set an event hander switchbot.onadvertisement = (ad) => { console.log(JSON.stringify(ad, null, ' ')); }; // Wait 10 seconds await switchbot.wait(10000); // 10秒だと受信しないことがあるので、受信確認用に60秒くらいにしておくと良い // Stop to monitor switchbot.stopScan(); process.exit(); })(); こんな感じのデータが受信できる。 { "id": "11d6e84dd3e18b4e3aab47da4aecb60a", "address": "XX:XX:XX:XX:XX:XX", "rssi": -54, "serviceData": { "model": "T", "modelName": "WoSensorTH", "temperature": { "c": 21.7, "f": 71.1 }, "fahrenheit": false, "humidity": 53, "battery": 100 } } serviceData.temperature.c が気温(℃) serviceData.humidity が湿度(%) serviceData.address が対象端末のMACアドレスなので、これで個体を識別する ・データタイプ(modelName)には、  Bot, Meter, Curtain があるようで、  温湿度計はMeterに属する。  https://github.com/OpenWonderLabs/node-switchbot#advertisement-data ・データの受信はプログラム実行直後にくるとは限らず、  実行から30秒くらいかかることもある。 ・アパートの一部屋で実行すると、ご近所さんのSwitchBotからも ガンガン データを受信する Bluetooth API で値を取る SwitchBot温湿度計は、Bluetooth通信規格に BLE(Bluetooth Low Energy)を採用しているので、とってもエコ。 通信データの内容が公開されているので、任意のBLE通信APIからアクセスしてデータを活用できる。 手元では、abandonware/nobleを使ってデータを取得することもできた。 abandonware/noble nodeのBLE通信モジュールとしてnobleが有名みたいだが、本家は更新が止まっているので、 abandonwareさん?がそういった有益なOSSを引き継いで開発保守をしてくれているらしい。 BLEでは、[親機(central module)] 1 対 [子機(peripheral)] 多 で通信が行われ、 nobleは親機の実装用モジュールとなる。 雑にデータを取りに行くだけならこんな感じ。 const UUIDs = ['cba20d00224d11e69fb80002a5d5c51b']; const noble = require('@abandonware/noble'); noble.on('stateChange', state => { // nobleの初期stateはUnknown. poweredOn になってからスキャンを開始しなければいけない if (state == 'poweredOn'){ // UUIDsで指定された対象だけが、スキャンの対象となる。 // ここで設定している値は、SwitchBot機器用に公開されているUUID // 第2引数は duplicate. 同端末からは1回のみデータを受け取るならば false にする noble.startScanning(UUIDs, true); } }); noble.on('discover', peripheral => { console.log('' + peripheral); }); こんな感じにデータが取れる { "id": "11d6e84dd3e18b4e3aab47da4aecb60a", "address": "", "addressType": "unknown", "connectable": true, "advertisement": { "manufacturerData": { "type": "Buffer", "data": [ 89, 0, 220, 48, 188, 73, 157, 176 ] }, "serviceData": [ { "uuid": "0d00", "data": { "type": "Buffer", "data": [ 84, 16, 100, 8, 148, 54 ] } } ], "serviceUuids": [ "cba20d00224d11e69fb80002a5d5c51b" ] }, "rssi": -55, "mtu": null, "state": "disconnected" } Meter BLE open API abandonware/nobleでデータ取得ができるようになったら、 Meter BLE open APIで公開されているデータ仕様を参考にして必要な値を取得する。 ※ここにUUIDについての記載もある UUID: cba20d00-224d-11e6-9fb8-0002a5d5c51b and fee7 温湿度計用には(New) Broadcast Messageのあたりが直接参考になるので、コードにおこすとこんな感じになる。 noble.on('discover', peripheral => { const sd = peripheral.advertisement.serviceData[0].data; const md = peripheral.advertisement.manufacturerData; const temperatureAboveZero = (sd[4] & 0b10000000) != 0; const data = { 'type': sd[0] & 0b01111111, 'battery': sd[2] & 0b01111111, 'temperature': ((sd[3] & 0b00001111) / 10 + (sd[4] & 0b01111111)) * (temperatureAboveZero?1:-1), 'humidity': sd[5] & 0b01111111, 'rssi': peripheral.rssi, 'address': `${md[2].toString(16)}:${md[3].toString(16)}:${md[4].toString(16)}:${md[5].toString(16)}:${md[6].toString(16)}:${md[7].toString(16)}` }; console.log(JSON.stringify(data)); });

Viewing all articles
Browse latest Browse all 9314

Trending Articles