今回は、SwitchBot の CO2センサーを使用して同じネットワーク内で動作しているNodeREDにデータをを送信する方法をまとめます。
SwitchBot CO2センサー
使用するセンサーです。製品対応のアプリをインストールして様々なデータを見ることができます。
準備するもの
・CO2センサー本体
・SwitchBotアプリ
・Node RED(今回は Raspberry pi 上で実行させています。)
※アプリはセンサーのMACアドレスを確認するため使用します。
他の方法でセンサーのMACアドレスを確認できれば不要です。
デバイスの登録
1.アプリをインストールしアカウントを登録します。
ios: https://apps.apple.com/jp/app/switchbot/id1087374760
Android: https://play.google.com/store/apps/details?id=com.theswitchbot.switchbot&hl=ja&pli=1
2.デバイスを追加 をタップ
3.指示に従い、検出されたセンサーをタップ
4.デバイス名とグループ(ルーム)を選択
5.登録されたセンサをタップ
MACアドレスを確認する
6.センサ情報右上の歯車をタップ
7.デバイス情報をタップ
8.MACアドレスを確認できます。
NodeREDの設定と実行
BLE Beacon Scanner を使用してBLEを受信します。
このノードを動作させるにはドライバのインストールが必要です。
また、NodeREDは管理者権限で実行させるようにしてください。
Switch ノードではデバイスのMACアドレスでフィルターをかけています。
ダッシュボードで可視化
このようにダッシュボード上にデータを解析し、可視化させてみます。
受信データ
実際にBLEで受信したデータです。
こちらの記事を参考にさせていただき解析したところ、
受信したデータの msg.payload.other[9] から先のデータがCO2濃度などのデータを意味しているそうです。
データ処理
参考元のコードから、受信したデータは2進数として符号ビットなどを考えて処理する必要がありました。
フロー全体の書き出しデータです。
[{"id":"64654ab83f05d72e","type":"BLE Beacon Scanner","z":"62c033373ef9fe3e","name":"","x":380,"y":160,"wires":[["8429ab232cc51230"]]},{"id":"5061e3772d68be45","type":"debug","z":"62c033373ef9fe3e","name":"debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":160,"wires":[]},{"id":"8429ab232cc51230","type":"switch","z":"62c033373ef9fe3e","name":"MacAddressでfilter","property":"payload.address","propertyType":"msg","rules":[{"t":"eq","v":"b0:e9:fe:54:4e:b4","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":650,"y":160,"wires":[["5061e3772d68be45","20acb4b52f7e6402"]]},{"id":"20acb4b52f7e6402","type":"function","z":"62c033373ef9fe3e","name":"function","func":"//温度が0℃以上かどうか->最上位ビット(符号ビット)を抽出。\nconst isOverZero = (msg.payload.other[11] & 0b10000000);\nvar result = -1;\nif(isOverZero){\n result += 2;\n}\n\n//バッテリー->符号ビット以外を抽出\nmsg.battery = msg.payload.other[9] & 0b01111111;\n\n//CO2濃度->上位下位バイトの合算値\nmsg.co2 = msg.payload.other[15] * 256 + msg.payload.other[16];\n\n//湿度->符号ビット以外を抽出\nmsg.humid = msg.payload.other[12] & 0b01111111;\n\n//温度データ->上位バイト(小数部分)の下位4ビットを抽出、下位バイト(整数部分)の上位7ビットを抽出\nmsg.temp = ((msg.payload.other[10] & 0b00001111) / 10 + (msg.payload.other[11] & 0b01111111)) * result;\n\nmsg.payload = {\n \"Battery\": msg.battery,\n \"CO2\": msg.co2,\n \"humid\": msg.humid,\n \"temp\": msg.temp\n}\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":750,"y":300,"wires":[["a089eba40c2d3fdc","95eb22c19ce3b620","8529d543d4f14628","1748b10b3b6f4b53"]]},{"id":"95eb22c19ce3b620","type":"ui_text","z":"62c033373ef9fe3e","group":"89221ddd3b672093","order":3,"width":0,"height":0,"name":"","label":"Humid","format":"{{msg.humid}}%","layout":"row-spread","className":"","style":false,"font":"","fontSize":16,"color":"#000000","x":1010,"y":380,"wires":[]},{"id":"a089eba40c2d3fdc","type":"ui_gauge","z":"62c033373ef9fe3e","name":"","group":"89221ddd3b672093","order":1,"width":0,"height":0,"gtype":"gage","title":"CO2 Density","label":"PPM","format":"{{msg.co2}}","min":0,"max":"2000","colors":["#00b500","#e6e600","#ca3838"],"seg1":"1000","seg2":"1501","diff":false,"className":"","x":1030,"y":300,"wires":[]},{"id":"8529d543d4f14628","type":"ui_text","z":"62c033373ef9fe3e","group":"89221ddd3b672093","order":2,"width":0,"height":0,"name":"","label":"Temperature","format":"{{msg.temp}}℃","layout":"row-spread","className":"","style":false,"font":"","fontSize":16,"color":"#000000","x":1030,"y":340,"wires":[]},{"id":"1748b10b3b6f4b53","type":"ui_text","z":"62c033373ef9fe3e","group":"89221ddd3b672093","order":3,"width":0,"height":0,"name":"","label":"Battery","format":"{{msg.battery}}%","layout":"row-spread","className":"","style":false,"font":"","fontSize":16,"color":"#000000","x":1020,"y":420,"wires":[]},{"id":"89221ddd3b672093","type":"ui_group","name":"CO2 Senser","tab":"12a35266cb7aeb9e","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"12a35266cb7aeb9e","type":"ui_tab","name":"Switch Bot Test","icon":"dashboard","disabled":false,"hidden":false}]