(8/15)追記
この記事では1回のSCANで1デバイスから取得しているが1回のSCANで複数のデバイスからデータ取得できるのを記事にした(URL)。
--------------
「Bluetooth気温計のデータをラズパイで取得しrrdtoolで描画できるようにした。」のセンサ接続とrrdtoolに繋げた部分について
@c60evaporatorさんの記事
を参考にして作成。
まずはラズパイ3の1台に各記事ごとに設定して動作の確認。
「2」の方の記事ではまったのは、
sudo install libglib2.0-dev
との記載は「sudo apt-get install libglib2.0-dev」 かと。てっきりripが抜けているのかとか悩んだ(linux,Python初心者なので勘がきかない)。
あとメインスクリプトの部分でMacアドレスを渡さないといけないのと、Macアドレスを小文字で書かないと駄目なのにはまる。
同一ディレクトリに、「1」の記事の「omron_env_broadcast.py」と「2」の記事の「switchbot.py」を放り込んで、両記事のメインスクリプトを合体させ、scanして見つからなかった際の処理を追加して出力をrrdtoolに都合の良いものに書き換えたbluetoothsensor.pyを放り込む。
(scanを1回で両方のデータを取れるようにできそうだけど、後日頑張ろう)
bluetoothsensor.py
#!/usr/bin/python3 from bluepy import btle from omron_env_broadcast import ScanDelegate from switchbot import SwitchbotScanDelegate import datetime import time while True: dt_now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') sb_meter = { "kitchen":"c9:43:c3:xx:xx:xx"} #omron_env_broadcast.pyのセンサ値取得デリゲートを、スキャン時実行に設定 scanner = btle.Scanner().withDelegate(ScanDelegate()) #スキャンしてセンサ値取得(タイムアウト5秒) scanner.scan(5.0) if scanner.delegate.sensorValue is not None: #print(dt_now + "," + "OM, " + "update /home/XXXX/RRD/wxbeacon2.rrd " print("update /home/XXXX/RRD/wxbeacon2.rrd " + str(int(time.time())) + ":" + str(scanner.delegate.sensorValue['BatteryVoltage']) + ":" + str(scanner.delegate.sensorValue['Temperature']) + ":" + str(scanner.delegate.sensorValue['Humidity']) + ":" + str(scanner.delegate.sensorValue['Light']) + ":" + str(scanner.delegate.sensorValue['UV']) + ":" + str(scanner.delegate.sensorValue['Pressure']) + ":" + str(scanner.delegate.sensorValue['Noise']) + ":" + str(scanner.delegate.sensorValue['Discomfort']) + ":" + str(scanner.delegate.sensorValue['WBGT']), flush=True) ######SwitchBotの値取得###### for key in sb_meter: #switchbot.pyのセンサ値取得デリゲートを、スキャン時実行に設定 scanner = btle.Scanner().withDelegate(SwitchbotScanDelegate(sb_meter[key])) #スキャンしてセンサ値取得(タイムアウト5秒) scanner.scan(5.0) if scanner.delegate.sensorValue is not None: #print(dt_now + "," + "SW, " + "update /home/XXXXX/RRD/swbot.rrd " print("update /home/XXXX/RRD/swbot.rrd " + str(int(time.time())) + ":" + str(scanner.delegate.sensorValue['Temperature']) + ":" + str(scanner.delegate.sensorValue['Humidity']) + ":" + str(scanner.delegate.sensorValue['BatteryVoltage']), flush=True) time.sleep(50)
$ ./bluetoothsensor.py update /home/xxxxx/RRD/wxbeacon2.rrd 1628919666:2.92:21.5:99.0:76:0.02:999.7:35.89:70.63:24.46 update /home/xxxxx/RRD/swbot.rrd 1628919671:27.0:59:100 update /home/xxxxx/RRD/wxbeacon2.rrd 1628919726:2.92:21.5:99.03:81:0.02:999.8:31.58:70.63:24.46 update /home/xxxxx/RRD/swbot.rrd 1628919731:27.0:58:100
のようなものが1分ごとに出てきます。ラズパイ側にデータをためるつもりはないのでデータ保存兼画像作成のサーバ側でrrdcachedを立ち上げラズパイから渡します。
サーバはNetBSD 9.2なので、「pkgin install rrdtool 」して「usr/pkg/bin/rrdcached -p /var/run/rrdcached/rrdcached.pid -l xxx.xxx.xxx.xxx:42217 -U rrdcached -w 60」(-lの後のxxxの部分は自サーバのIFについているIPv4アドレス)で立ち上げる。
ラズパイ側から疎通確認のために「telnet xxx.xxx.xxx.xxx 42217」で繋いで、「HELP」とか打ち込んで、
$ telnet XXX.XXX.XXX.XXX 42217 Trying XXX.XXX.XXX.XXX... Connected to XXX.XXX.XXX.XXXX. Escape character is '^]'. HELP 22 Command overview UPDATE <filename> <values> [<values> ...] FLUSH <filename> FLUSHALL PENDING <filename> FORGET <filename> ....と出れば接続OK.QUITで抜ける。あとはラズパイ側でNC(NetCat)を利用して、「./bluetoothsensor.py |nc xxx.xxx.xxx.xxx 42217 &」とかで直接投げ込めば更新完了。 うまく行かない際はサーバ側のRRDファイルのパーミッションがユーザ「rrdcached」での書き込み権限があるか確認。 サーバ側で更新されているか確認は「rrdtool last RRDファイル名」などで最終更新日を確認する。以下にrrdtoolでのRRDの作成と画像のパラーメータを載せておく。 細かいオプションは「RRDtool 1.2系を使う」を参照の事。
rrdtool create wxbeacon2.rrd --start "00:00 07/01/2021" \ --step 60 \ --no-overwrite \ DS:Battery:GAUGE:600:0:U \ DS:Temperature:GAUGE:600:U:U \ DS:Humidity:GAUGE:600:0:100 \ DS:Light:GAUGE:600:0:U \ DS:UV:GAUGE:600:0:U \ DS:Pressure:GAUGE:600:0:U \ DS:Noise:GAUGE:600:0:U \ DS:Discomfort:GAUGE:600:U:U \ DS:HeatStrokeRisk:GAUGE:600:U:U \ RRA:MAX:0.5:1:5256000 rrdtool create swbot.rrd --start "00:00 07/01/2021" \ --step 60 \ --no-overwrite \ DS:Temperature:GAUGE:600:U:U \ DS:Humidity:GAUGE:600:0:100 \ DS:BatteryVoltage:GAUGE:600:0:U \ RRA:MAX:0.5:1:5256000 /usr/pkg/bin/rrdtool graph temp-2week.png -h 300 -w 500 -s 'now - 2weeks' \ DEF:a=/XXXX/RRD/usbrh.rrd:Temperature:MAX \ DEF:b=/XXXX/RRD/wxbeacon2.rrd:Temperature:MAX \ DEF:c=/XXXX/RRD/swbot.rrd:Temperature:MAX \ LINE2:a#FF0000:"usbrh(室内)\n" \ LINE2:b#00FF00:"wx2(庭)\n" \ LINE2:c#00FFFF:"SWbot(台所)" -t "気温" -v "degC" /usr/pkg/bin/rrdtool graph temp-2day.png -h 300 -w 500 -s 'now - 172800' \ DEF:a=/XXXX/RRD/usbrh.rrd:Temperature:MAX \ DEF:b=/XXXX/RRD/wxbeacon2.rrd:Temperature:MAX \ DEF:c=/XXXX/RRD/swbot.rrd:Temperature:MAX \ LINE2:a#FF0000:"usbrh(室内)\n" \ LINE2:b#00FF00:"wx2(庭)\n" \ LINE2:c#00FFFF:"SWbot(台所)" -t "気温" -v "degC" /usr/pkg/bin/rrdtool graph temp-60min.png -h 300 -w 500 -s 'now - 3600' \ DEF:a=/XXXX/RRD/usbrh.rrd:Temperature:MAX \ DEF:b=/XXXX/RRD/wxbeacon2.rrd:Temperature:MAX \ DEF:c=/XXXX/RRD/swbot.rrd:Temperature:MAX \ LINE2:a#FF0000:"usbrh(室内)\n" \ LINE2:b#00FF00:"wx2(庭)\n" \ LINE2:c#00FFFF:"SWbot(台所)" -t "気温" -v "degC"