【SwitchBot】ラズパイで複数台の温湿度計のセンサーの値を受け取ってみる。冷蔵庫に入れてみたよ。
- 2022.03.15
- IT
複数台の温湿度計の値をラズパイで受け取りたいと思ったので、試してみました。
複数台の温湿度計を使って冷蔵庫と冷凍庫内の温度を受け取りたかったのです笑
ネット上には温湿度計1台の記事はあったのですが複数台の記事は見つからなかったので。
環境
- Raspberry pi 4 8GB
- Raspbian 10.11( cat /etc/debian_version)
- Python3 : 3.7.3
- pip3: pip 22.0.4
- SwitchBot 温湿度計x3台
- 冷蔵庫の中に1台
- 冷凍庫の中に1台
- PCの上に1台
実行前の準備
こちらの記事 を参考にします。
Raspberry Piの準備
1 2 3 4 5 6 7 8 9 10 11 12 |
# まずはPythonのパッケージがインストールされるであろう場所に移動します。 cd /usr/local/lib/python3.7/dist-packages/ # まだBlupyはないのを確認します。 ls -l # BlupyをSudo権限で入れます。Sudoないと使えません。 sudo pip3 install bluepy ls # インストールが確認できたら、有効化します。 cd bluepy sudo setcap 'cap_net_raw,cap_net_admin+eip' bluepy-helper |
SwitchBot側
スマホから各温湿度計のMacアドレスを確認します。(右端)
実行するコード
ラズパイの適当なディレクトリにこれをコピペして、sudo権限で実行します。
sudo python3 switchbot.py
みたいな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
import struct import sys from bluepy.btle import Scanner, DefaultDelegate #Broadcastデータ取得用デリゲート #class SwitchbotScanDelegate(btle.DefaultDelegate): class SwitchbotScanDelegate(DefaultDelegate): #コンストラクタ def __init__(self, macaddr): #btle.DefaultDelegate.__init__(self) DefaultDelegate.__init__(self) #センサデータ保持用変数 self.sensorValue = None self.macaddr = macaddr # スキャンハンドラー def handleDiscovery(self, dev, isNewDev, isNewData): # 対象Macアドレスのデバイスが見つかったら if dev.addr == self.macaddr: # アドバタイズデータを取り出し for (adtype, desc, value) in dev.getScanData(): #環境センサのとき、データ取り出しを実行 if desc == '16b Service Data': #センサデータ取り出し self._decodeSensorData(value) # センサデータを取り出してdict形式に変換 def _decodeSensorData(self, valueStr): #文字列からセンサデータ(4文字目以降)のみ取り出し、バイナリに変換 valueBinary = bytes.fromhex(valueStr[4:]) #バイナリ形式のセンサデータを数値に変換 batt = valueBinary[2] & 0b01111111 isTemperatureAboveFreezing = valueBinary[4] & 0b10000000 temp = ( valueBinary[3] & 0b00001111 ) / 10 + ( valueBinary[4] & 0b01111111 ) if not isTemperatureAboveFreezing: temp = -temp humid = valueBinary[5] & 0b01111111 #dict型に格納 self.sensorValue = { 'SensorType': 'SwitchBot', 'MacAddr': self.macaddr, 'Temperature': temp, 'Humidity': humid, 'Battery': batt } def send_temp_data(macaddr): # macaddr指定した温湿度センサの値を取得 macaddr = str.lower(macaddr) scanner = Scanner().withDelegate( SwitchbotScanDelegate(macaddr) ) #スキャン(timeout2s) scanner.scan( 2.0 ) temp=0 #出力 try: temp = str(scanner.delegate.sensorValue['Temperature']) except TypeError as e: print("Temporarily lost communication with Bluetooth temperature device.",e) except: import traceback traceback.print_exc() return temp if __name__ == '__main__': i=0 while True: print(i, "times") # MACアドレスの入力 print("thermo1 temp is : ",send_temp_data('EA:EE:EE:EE:90:CE')) print("thermo2 temp is : ",send_temp_data('E6:AA:AA:AA:AA:83')) print("thermo3 temp is : ",send_temp_data('CA:BB:BB:BB:BB:7C')) print("-"*20) i+=1 |
結果
こんな感じで値が取れます!
と言っても、取れない時も多々ありますね。
ちなみに、thermo1が冷蔵庫、thermo2がPCの上、thermo3が冷凍庫の中です。
scanner.scan( 2.0 )の値を適宜調整すると結果が良くなるかもしれません!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
0 times thermo1 temp is : 9.9 Temporarily lost communication with Bluetooth temperature device. 'NoneType' object is not subscriptable thermo2 temp is : 0 thermo3 temp is : -9.5 -------------------- 1 times Temporarily lost communication with Bluetooth temperature device. 'NoneType' object is not subscriptable thermo1 temp is : 0 thermo2 temp is : 30.3 thermo3 temp is : -9.6 -------------------- 2 times Temporarily lost communication with Bluetooth temperature device. 'NoneType' object is not subscriptable thermo1 temp is : 0 thermo2 temp is : 30.3 thermo3 temp is : -9.7 -------------------- |
タイムアウトを5秒にしてみた。
安定してきましたね。
そして冷凍庫って想像以上に寒いんですね笑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
-------------------- 321 times thermo1 temp is : 6.5 thermo2 temp is : 35.5 thermo3 temp is : -21.9 -------------------- 322 times thermo1 temp is : 6.5 thermo2 temp is : 35.3 thermo3 temp is : -21.9 -------------------- 323 times thermo1 temp is : 6.5 thermo2 temp is : 35.1 thermo3 temp is : -21.9 -------------------- 324 times thermo1 temp is : 6.4 thermo2 temp is : 35.1 thermo3 temp is : -21.9 |
まとめ
冷蔵庫とか冷凍庫って金属っぽいので通信できなくなるのかな?と思いきや普通に通信できて驚きました!
ぜひ遊んでみてください〜