0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

夏、留守番ネコのためにエアコンを自動で付ける

Posted at

はじめに

猫は寒さには強いが、暑さには弱いそうな。
いつも留守番させてごめんね。
SwitchBotで部屋の温度が分かるから、暑くなったらエアコン自動で付けるくらいはしてあげたい。
あとどうせならエアコン操作時はLINEで通知を受けたいし、LINE Notifyの使い方の記事も書いときたい。

環境

AWSのAmazon Linux2023を使う。(私の記事は全部いっしょ!)

つまり配置は以下(図を書くほどの記事じゃない)
プログラム・・AWS
通知・・スマホのLINE
家・・SwitchBot製品の温湿度計とシーリングライト(ミニHUB代わり)

LINE作業

まずは普通にスマホを使ってグループを作る
image.png

バッチリ決めた写真をアイコンに設定
image.png

LINE Notifyをグループに参加させる (LINE Notifyは友だち登録しておく)
image.png

ちなみに、グループに参加させない状態で後述のプログラム使ってメッセージ送ろうとすると、こんなメッセージが来るのでLINE Notifyはちゃんと招待してあげる
image.png

パソコン作業

ブラウザでLINE Notify (https://notify-bot.line.me/ja/) にログインして、
マイページをクリック
image.png

アクセストークンの発行をクリック
image.png

「通知を送信するトークルーム」にさっき作ったグループを指定する。
トークン名はお好みで決める。ここでは「!」にした。(トークン名は後から変更できないっぽい!)
image.png

発行するボタンを押したら、次のようにトークンが表示されるのでメモする。
image.png

LINE Notifyを利用するプログラム

まずは単独で動かしてみて、通知が来るか確認しよう

line_notify.py
import requests

YOUR_TOKEN = 'あなたのトークン'

# LINEにメッセージ送信
def send_message(text_message):

    url  = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization' : 'Bearer ' + YOUR_TOKEN}
    payload = {'message' : text_message }

    response = requests.post( url, headers = headers, params=payload)
    if response.status_code != 200:
        print('失敗!', response.status_code)

def main():

    send_message('test')

if __name__ == '__main__':
    main()

SwitchBotを利用するプログラム

SwitchBotの使い方は前の記事に書いた

今回はエアコンをON/OFFする関数を作る。
詳しいことは公式リファレンスを読む。
https://github.com/OpenWonderLabs/SwitchBotAPI

switchbot.py
import json
import time
import hashlib
import hmac
import base64
import uuid

import requests

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

TEMP_DEVICE_ID = '温湿度計のデバイスID'
EAKON_DEVICE_ID = 'エアコンのデバイス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()

# 寝室のエアコン
def shinshitu_eakon(temperature = 25, power='on'):

    # ヘッダ作成
    header = create_header()

    # he unit of temperature is in celsius;
    # modes include 0/1 (auto), 2 (cool), 3 (dry), 4 (fan), 5 (heat);
    # fan speed includes 1 (auto), 2 (low), 3 (medium), 4 (high);
    # power state includes on and off
    # 設定温度、冷房、ファン速度:中、on or off で要求
    body = {
        "command" : "setAll",
        "parameter" : f"{temperature},2,3,{power}",  # 温度,モード,ファン速度,電源状態
        "comandType": "command"                      # モード 1:自動 2:冷房 3:乾燥 4:ファン 5:加熱
    }                                                # ファン速度 1:自動 2:低 3:中 4:高

    # 寝室のエアコン操作!
    url = 'https://api.switch-bot.com/v1.1/devices/' + EAKON_DEVICE_ID + '/commands'
    requests.post( url, headers=header, data=json.dumps(body) )

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

if __name__ == "__main__":
    main()

メイン関数

SwitchBotとLINE Notifyを組み合わせたメインプログラムを書く。
ざっくり仕様は
・温度が28℃以上になったらエアコンを冷房 26℃ でON
・温度が24℃以下になったらエアコンをOFF
・エアコン操作時にLINE通知
・ついでに温度と湿度が異常な場合もLINE通知
・一応、夏(5~8月)っぽくて日中(10~18時)と限定させておく。誤検知されても嫌なので、明らかに不要な時はなるべく排除しておきたいという心

main.py
from datetime import datetime
import line_notify
import switchbot

# 温度のLINE通知判定閾値
TEMP_MAX = 30
TEMP_MIN = 18

# 湿度のLINE通知判定閾値
HUMIDITY_MAX = 70
HUMIDITY_MIN = 35

# エアコンON/OFF 閾値
EAKON_ON  = 28
EAKON_OFF = 24

# 設定温度をON閾値の何℃マイナスにするか
SET_TEMP  = 2

# 室温と湿度をチェックし、異常ならLINEにて通知
def check_temp():

    # 温湿度計情報の取得
    meterplus = switchbot.get_temp_and_humidity()
    temp = meterplus['body']['temperature']
    humidity = meterplus['body']['humidity']

    print( '温度=', temp, '湿度=', humidity )

    # 温度/湿度に異常があればライン送信
    if temp >= TEMP_MAX or\
       temp <= TEMP_MIN or \
       humidity >= HUMIDITY_MAX or \
       humidity <= HUMIDITY_MIN:

        msg = '  温度/湿度が異常\n\n温度 ' + str(temp) + '\n湿度 ' + str(humidity) + '%\n\n'
        msg = msg + '次の条件でお知らせします\n'
        msg = msg + '温度 {:}℃以上 or {:}℃以下\n'.format( TEMP_MAX, TEMP_MIN )
        msg = msg + '湿度 {:}%以上 or {:}%以下'.format( HUMIDITY_MAX, HUMIDITY_MIN )
        line_notify.send_message(msg)
    # 温度を返す
    return temp

# 夏の暑い時に、寝室のエアコンをつける
def summer_eakon(temp):

    # 現在時刻取得
    dt_now = datetime.now()

    # 夏(5~8月)の日中
    if (dt_now.month >= 5  and dt_now.month <= 8) and \
       (dt_now.hour  >= 10 and dt_now.hour  <= 18):

        # 暑そうならエアコンON
        if temp >= EAKON_ON:
            switchbot.shinshitu_eakon(temperature = EAKON_ON - SET_TEMP, power = 'on')
            msg = f'暑そうなのでエアコンONしました!\n' \
                  f'条件   : {EAKON_ON}℃ 以上\n' \
                  f'設定温度 : {EAKON_ON - SET_TEMP}'
            line_notify.send_message(msg)

        # 涼しくなったらエアコンOFF
        elif temp <= EAKON_OFF:
            switchbot.shinshitu_eakon(power = 'off')
            msg = f'涼しそうなのでエアコンOFFしました!\n' \
                  f'条件 : {EAKON_OFF}℃ 以下'
            line_notify.send_message(msg)

def main():

    # 室温と湿度をチェックし、異常ならLINEにて通知
    temp = check_temp()

    # 夏の暑い時に、寝室のエアコンをつける
    summer_eakon(temp)

if __name__ == "__main__":
    main()

cronに登録

これをcronに登録しておく。
「crontab -l」コマンド結果は以下。1時間毎に起動するようにしている。

MAILTO=""
# 1時間毎
0 9-18 * * * cd /home/ec2-user/project/switchbot; python3 main.py

実際のLINE画面

ちゃんと通知された。
image.png

ちなみに最初に書いた記事と同じLINEグループにしてるので、ネコが動いても通知がくる。

実はこんなプログラム書かなくても実現できる

「Switchbot エアコン 自動」 でググると分かるけどSwitchBotのスマホアプリだけで実現できるみたい!(笑)
なので普通はプログラム書かない気もする

おわりに

仕組み自体は去年に作ってたけど、自分の中でまとめるためにも記事にした。
1度やったはずなのに戸惑うところもあって、やっぱりちゃんと残しておくのって大事だな~と実感

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?