温湿度計のデータをraspberry piで5分おきに取得

switchbotの温湿度計、家に4個あります。
1週間ぐらい経って、グラフを見てみたい！と思って、データをアプリからエクスポートしてgoogle spread sheetにはりつけてみてみたところ、4個のデータのtimestampがバラバラでうまくグラフ化できませんでした。

ぐぐったら、raspberry piがあれば同じ時刻で記録できそうだったので、やってみました。
温湿度計のローカルからデータをバックアップしておくという意味でも、やっておきたいなと思いました。

実は、ひとりでは全然進められなくて嫌になりかけていたんですが、ココナラというサービスでわからんから助けてくれと依頼をしてみたところ一晩で解決しました。それから、スマートホーム化はココナラを使いながらやることで、ストレスが少なく進められています（ココナラの回し者ではないです笑）

ラズベリーパイで5分おきにbluetoothでswitchbotの温湿度計にアクセスして、google spread sheetへAPIでデータを書き込んでいます。
※ この記事では、データの取得までです。その先は↓の記事を参照。

https://qiita.com/tosshie/private/0b6a93a8e351cd801321

#### 前提

- switchbotの温湿度計があること
- Raspberry piの初期設定が終わっていること

https://qiita.com/tosshie/items/d06c9f57ceb340f2d589


#### 事前準備
- 基本的に以下のページを参照して実施しました

https://qiita.com/c60evaporator/items/7c3156a6bbb7c6c59052

- raspberry piのBluetoothが動いているか確認
    - 以下コマンド

```
# bluetoothctl
[bluetooth]# scan on
```

- ここで、ものすごくはまりました。原因はOSの問題でした。詳細は以下リンク。
    
https://qiita.com/tosshie/items/cbd1c885e4a28a960d90

- 温湿度計のMAC addressを確認
    - switchbotアプリから温湿度計を選択→右上の設定ボタン→右上のメニューボタン→MAC Addressを確認
    - MAC addressがbluetoothのscanで出てくるか確認

- パッケージのインストール
    
```
sudo apt-get -y install python3-pip libglib2.0-dev
pip3 install bluepy
```
- 以下のコマンドではうまくいかなかったとメモが残っていた

```
sudo install libglib2.0-dev
```

- bluepyに権限を付与 (実際にインストールしたフォルダで実行)

```
cd ~.pyenv/versions/3.7.6/lib/python3.7/site-packages/bluepy
sudo setcap 'cap_net_raw,cap_net_admin+eip' bluepy-helper
```

#### スクリプト作成
- スクリプトは、2種類作ります
    - 1. bluetooth で受信したデータを読み出すスクリプト(switchbot.py)
    - 2. データをファイルに出力するスクリプト(switchbot_toSpreadSheet1.py)
- 1. bluetooth で受信したデータを読み出すスクリプトは、参照したページのものをそのまま使っています


``` switchbot.py
from bluepy import btle
import struct

class SwitchbotScanDelegate(btle.DefaultDelegate):
    def __init__(self, macaddr):
        btle.DefaultDelegate.__init__(self)
        self.sensorValue = None
        self.macaddr = macaddr

    def handleDiscovery(self, dev, isNewDev, isNewData):
        if dev.addr == self.macaddr:
            for (adtype, desc, value) in dev.getScanData():
                if desc == '16b Service Data':
                    self._decodeSensorData(value)

    def _decodeSensorData(self, valueStr):
        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
        self.sensorValue = {
            'SensorType': 'SwitchBot',
            'Temperature': temp,
            'Humidity': humid,
            'BatteryVoltage': batt
        }
```

- 2. データをファイルに出力するスクリプト
    - MAC addressは小文字で入れないとだめでした
    - 私は4個の温湿度計のデータを取得したかったので、4個の温湿度計のMAC addressを指定しています
    - 4個の温度、湿度、バッテリー残量を取得しています
    - テストのため、出力ファイルは/root/data.csv, 実行ファイルは/root直下に置いています 

```switchbot_toSpreadSheet1.py
import requests
import datetime
import csv
import pprint
from bluepy import btle
from switchbot import SwitchbotScanDelegate

scanner1 = btle.Scanner().withDelegate(SwitchbotScanDelegate("aa:aa:aa:aa:aa:aa(ここにMAC addressを入れてください)"))
scanner1.scan(10.0)

Humidity_1F = scanner1.delegate.sensorValue['Humidity']
Battery_1F = scanner1.delegate.sensorValue['BatteryVoltage']
Temperature_1F = scanner1.delegate.sensorValue['Temperature']

scanner2 = btle.Scanner().withDelegate(SwitchbotScanDelegate("aa:aa:aa:aa:aa:aa(ここにMAC addressを入れてください)"))
scanner2.scan(10.0)

Humidity_2F = scanner2.delegate.sensorValue['Humidity']
Battery_2F = scanner2.delegate.sensorValue['BatteryVoltage']
Temperature_2F = scanner2.delegate.sensorValue['Temperature']

scanner3 = btle.Scanner().withDelegate(SwitchbotScanDelegate("aa:aa:aa:aa:aa:aa(ここにMAC addressを入れてください)"))
scanner3.scan(10.0)

Humidity_3F = scanner3.delegate.sensorValue['Humidity']
Battery_3F = scanner3.delegate.sensorValue['BatteryVoltage']
Temperature_3F = scanner3.delegate.sensorValue['Temperature']

scanner4 = btle.Scanner().withDelegate(SwitchbotScanDelegate("aa:aa:aa:aa:aa:aa(ここにMAC addressを入れてください)"))
scanner4.scan(10.0)

Humidity_LOFT = scanner4.delegate.sensorValue['Humidity']
Battery_LOFT = scanner4.delegate.sensorValue['BatteryVoltage']
Temperature_LOFT = scanner4.delegate.sensorValue['Temperature']

dt_now = datetime.datetime.now()


path = '/root/data.csv'

with open(path,"a") as f:
    writer = csv.writer(f)
    writer.writerow([dt_now, Humidity_1F, Battery_1F, Temperature_1F,Humidity_2F, Battery_2F, Temperature_2F,Humidity_3F, Battery_3F, Temperature_3F,Humidity_LOFT, Battery_LOFT, Temperature_LOFT])

f.close()

```

#### cronの設定
- 以下の設定をしています
    - 5分おきにスクリプトを実行

```
*/5 * * * * python3 /<実際に保存した場所>/switchbot_toSpreadSheet1.py
```


-------
2021年3月から始めたスマートホーム化はこちらに一覧化しています（2021年5月時点）

https://qiita.com/tosshie/private/738a85184d6cdaf20b3e