MQTTを使って、自動化(暗くなったら、OFF)

準備中の箇所もあるけど、とりあえず

PlatformIOを使って、ソフトウェアをOTAでアップデートすることもできるようになったし、Homie準拠のプロトコルで話すESP8266のノードも完成しました。

自動化!

そのそろ自動化して、その恩恵を楽しんでみたい。

まずは、以下に着手してみましょう。

  • 人がいなくなったら、加湿器をOFF
  • 湿度が一定以上になったら加湿器をOFF
  • 人がいて、湿度が一定以下になったら、加湿器ON

安全側に倒したいので、自動でONは、最後に試す予定で、さらに「人がいること」を前提に。

どこで動かす?

もちろん、ノードの中に組み込むこともできるけど、そうすると、ちょっとしたロジック変更が手間に感じそう。
サーバー上で動かすこともできるけど、まずは、自分のMac上で動かして動作を確認していきたい。

ということで、将来的にサーバーで動かすことも視野に入れつつ、Macで動かすという方向性で。
つまり、以下の方向性で作ってみよう。

  • Python等の"様々なOS上で動く"環境で動作するものを作る

Python向けMQTTライブラリ

ちょっと調べてみたところ、MQTTクライアント開発用ライブラリのPahoを使ってみようかと。

Paho インストール方針検討

インストールしようとして、Pythonのバージョン調べたら、インストールされているのは、2.7でした。
ただ、3への移行を激しく推奨すると出てきて、びっくり。
Python3とタイプすると、Python3.7.3も動いたので、新しくPythonをインストールする必要はないみたい。
ライブラリの依存関係とか気にしたくないので、個別環境を作ってすすめることにしましょう。

環境構築

方向性が決まったら、さっそくインストール。
venvの使い方はここ

適当なディレクトリを作成する
% mkdir hogehoge
venv使って、環境構築
% cd hogehoge
% python3 -m mqtt
環境に入る
% . mqtt/bin/activate
Pahoのインストール
(mqtt) pip install paho-mqtt
Pahoの確認
% python
>>> import paho
でエラーが起こらないことを確認

これで、venv環境(上記では、mqttと命名)上のPahoが使える環境が準備できた。
環境を抜ける時は、(mqtt) deactivate でOK。
不要になったら、指定したvenv環境の名前のついたフォルダを削除するだけ。
ちなみに、中を覗くと、どうやってvenv環境が構築されているかわかって興味深かったです。

自分は、Xcodeと並行して、AppCodeを使っていることもあり、PyCharmで開発することに。

少し驚いたのが、PyCharmを使って新しいプロジェクトを作ると、最初からvenvオプションみたいなものがあって、上記を自動で行ってくれました。名前は、venvとするのがデフォルトみたい。

また、PyCharmを使うと、pipでのインストールもGUIを使ってできます。

  • 「PyCharm」ー「Preferences」でウィンドウを開く。
  • 開いたウィンドウでProject: プロジェクトネーム のタブを開く。
  • "project Interpreter"を選択する。
  • インストールされているライブラリが表示されるので、表示されていなければ、(左下の)"+"を押す。
  • 検索フィールドに、ライブラリ名を入力すると、インストール可能なライブラリが表示されるので、インストール

こんどこそ、開発環境構築完了!

明るさをチェックして、OFF

ここまでできたら、簡単。自分の興味あるTopicをSubscribeして、変化をチェックして、必要なメッセージを適切なTopicに送るだけ。

#import context  # Ensures paho is in PYTHONPATH
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish

def on_connect(mqttc, obj, flags, rc):
    print("rc: "+str(rc))

def on_message(mqttc, obj, msg):
    if (msg.topic == "homie/sensor-tomoroom/properties/brightness"):
        brightness = int(msg.payload.decode('utf-8'))
        print(brightness)
        if ( brightness > 500 ):
            # room is dark, no one
            print("send turn OFF")
            mqttc.publish("topic/ac100relay/set", "false")

        #print(str(msg.payload))

    #print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload))

def on_publish(mqttc, obj, mid):
    print("mid: "+str(mid))

def on_subscribe(mqttc, obj, mid, granted_qos):
    print("Subscribed: "+str(mid)+" "+str(granted_qos))

def on_log(mqttc, obj, level, string):
    print(string)

# If you want to use a specific client id, use
# mqttc = mqtt.Client("client-id")
# but note that the client id must be unique on the broker. Leaving the client
# id parameter empty will generate a random id for you.
#mqttc = mqtt.Client(transport="websockets")
mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
# Uncomment to enable debug messages
# mqttc.on_log = on_log
mqttc.connect("server", 1883, 60)
mqttc.subscribe("topic/brightness", 0)
#mqttc.connect("mqtt.eclipse.org", 1883, 60)
#mqttc.subscribe("#", 0)


mqttc.loop_forever()

自分の環境では、ローカルのMQTTサーバーにダイレクトにアクセスできるので、Websocket経由での接続は不要でした。

あとは、これをどこかのサーバー上の環境で動作するようにすればOKのはず。(でもそんなアプリって、どこかにありそうな・・・)

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です