部屋の湿度をそこそこ制御する SwitchBot × Dyson加湿器 

## はじめに
また気付けば加湿器を使う季節になった。Switchbotの温湿度計で湿度が分かるんだから自動で何かしてみようかという気になる。お留守番のネコ様も喜ぶかもしれない。

## 仕様
湿度50%以上になったら加湿器の電源OFFし、湿度30%以下になったら電源ONする。
ONとOFFの数字が違っててイマイチな仕様だが理由は後述

## Switchbotのアプリに加湿器を登録
Switchbot製品ではなくても赤外線リモコンなら家電はたいてい登録できる。
ポチポチやって登録
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/0566fdac-7eda-518e-b88d-01eb8cb66e3e.png">

ボタンもポチポチ登録
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625818/c95735a8-568d-b64b-2b4f-c8d822e35fab.png">

今回使うのは電源とタイマーだけ。
この記事とは関係ないけど、登録できるボタンって押す回数も含めて登録される・・！ 湿度UPボタンを10回押して登録すると、10回押したことになるボタンが登録できる！ちょっと感動

## 動作環境は前の記事
AmazonLinuxとpython3.9を使う。

https://qiita.com/dmackey_2128/items/7a7e01ea47e745913fcb

switchbotは前回同様にバージョン1.1を使う。

https://qiita.com/dmackey_2128/items/bdfe42a5a64994462871


# Switchbotで加湿器をON/OFFするプログラム

前の記事からちょっと変えただけ

```python:switchbot.py
import json
import time
import hashlib
import hmac
import base64
import uuid

import requests

TOKEN  = 'あなたのキー'
SECRET = 'あなたのキー'

TEMP_DEVICE_ID = 'あなたのキー'
DYSON_MIST_DEVICE_ID = 'あなたのキー'

# githubのリファレンスより、How to Sign
def create_header():

    # Declare empty header dictionary
    apiHeader = {}
    nonce = uuid.uuid4()
    t = int(round(time.time() * 1000))
    string_to_sign = '{}{}{}'.format(TOKEN, t, nonce)

    string_to_sign = bytes(string_to_sign, 'utf-8')
    secret = bytes(SECRET, 'utf-8')

    sign = base64.b64encode(hmac.new(secret, msg=string_to_sign, digestmod=hashlib.sha256).digest())

    #Build api header JSON
    apiHeader['Authorization']=TOKEN
    apiHeader['Content-Type']='application/json'
    apiHeader['charset']='utf8'
    apiHeader['t']=str(t)
    apiHeader['sign']=str(sign, 'utf-8')
    apiHeader['nonce']=str(nonce)

    return  apiHeader

# デバイス一覧取得
def deviceid_view():
    # ヘッダ作成
    header =create_header()
    response = requests.get("https://api.switch-bot.com/v1.1/devices", headers=header)
    print(response.text.replace('}', '}\n'))

# 温湿度計の情報取得
def get_temp_and_humidity():

    # ヘッダ作成
    header = create_header()

    url = 'https://api.switch-bot.com/v1.1/devices/' + TEMP_DEVICE_ID + '/status'
    res = requests.get( url, headers=header )
    return res.json()

# 加湿器への電源ON/OFF
def dyson_hygienic_mist(button):

    if button == 'on':
        cmd = '電源'
    elif button == 'off':
        # タイマーボタンを押すと15分後にOFFされる。現在状態に依存しないので信頼性が少し高い
        cmd = 'タイマー'
    else:
        return

    # ヘッダ作成
    header = create_header()

    list_body = {"command" : cmd, "comandType": "customize"}

    url = 'https://api.switch-bot.com/v1.1/devices/' + DYSON_MIST_DEVICE_ID + '/commands'
    print(requests.post( url, headers=header, data=json.dumps(list_body) ))

def main():
    # デバイス一覧取得
#    deviceid_view()

    get_temp_and_humidity()

if __name__ == "__main__":
    main()
```

## cronに登録する用のメインプログラム

```python:dyson_mist.py
import switchbot

# 自動でOFFにする湿度(%)閾値 (この値より大きければOFF)
AUTO_OFF_HUMIDITY = 50

# 自動でONにする湿度(%)閾値 (この値より小さければON)
AUTO_ON_HUMIDITY = 30

def main():
    # 温湿度計情報の取得
    meterplus = switchbot.get_temp_and_humidity()
    # 現在の湿度(%)取り出し
    situdo_pv = meterplus['body']['humidity']
    print(situdo_pv)

    # 自動OFF判定
    if situdo_pv > AUTO_OFF_HUMIDITY:
        switchbot.dyson_hygienic_mist('off')
    # 自動ON判定
    elif situdo_pv < AUTO_ON_HUMIDITY:
        switchbot.dyson_hygienic_mist('on')

if __name__ == "__main__":
    main()
```

## 自動実行
rootで「crontab -e」コマンド実行し、中身を以下にして１時間毎に起動させる。

```
# 毎日0時
0 * * * * cd /home/ec2-user/project/switchbot; python3 dyson_mist.py
```

## 終わりに

#### 電源状態(ON or OFF)は分からない
リモコンの電源ボタンはON/OFFが共通なので、プログラムからは明示的に電源操作できない。状態取得も出来ないのでON/OFFどちらの状態なのかも分からない。なので自動ON閾値と自動OFF閾値を分けてそれとなく意図した動作になればいいな・・という希望的プログラムにした。あとタイマーボタンを１度押すと15分後にタイマーセットされることを利用して、OFF操作するときはタイマーボタンを押すことにした。（=OFF状態で電源ボタン押すとONになるが、タイマーボタンならONにはならないから意図しない動作の抑止になる）

#### ５分だけ悩んだ仕様 
目標湿度値に何%足らなければ設定湿度を10%上げる、といった仕様にしようかと思ったけど止めた。だって設定60%にしてても45%でビタ止まりしてることとかよくある。あと電源状態同様に設定湿度値も分からないしね。ごちゃごちゃした仕様にしてもあまり意味ないかな～と思ったのでとりあえずシンプルな仕様。
理想は45%くらいをキープで、自動OFF機能は動かないこと。自動OFFが動くようなら閾値50を上げよう。


家庭用人型お手伝いロボットの普及はまだか・・