ども。こんばんは。
codey rockyではメッセージキューWとしてMQTTWが実装されています。
せっかくなのでちょっと試してみます。
MQTTについては少し古いですがこの辺がわかりやすいです。
MQTTで始めるIoTデバイスの作り方 第1回:「MQTT」を知り「Mosquitto」を導入する (1/3)
まずはMQTTのブローカーとしてmosquittoをRaspberry Pi上にインストールします。
※そのうちRabbit MQも試したいなと思いますがまずは手軽そうなmosquittoで試します。
ブローカーの動作環境はRaspbian GNU/Linux 9.11 (stretch)で、2020/02/16時点最新のパッケージになっています。
・mosquittoのインストール
sudo apt install mosquitto
うちの環境ではlibev4とlibwebsockets8も合わせてインストールされました。
・続いてクライアントもインストールします。
sudo apt install mosquitto-clients
libmosquitto1が合わせてインストールされました。
・ブローカーの起動
sudo systemctl start mosquitto
sudo systemctl status mosquittoで確認して特に問題なく起動していました。
1883ポートでLISTENしているみたいですね。
・テスト
以下のコマンドでtestというトピックを購読(サブスクライブ)します。
mosquitto_sub -d -t test
実行結果はこんな感じ。
※lexはうちのラズパイのホスト名です。
Client mosqsub/6162-lex sending CONNECT
Client mosqsub/6162-lex received CONNACK
Client mosqsub/6162-lex sending SUBSCRIBE (Mid: 1, Topic: test, QoS: 0)
Client mosqsub/6162-lex received SUBACK
Subscribed (mid: 1): 0
・テストメッセージ送信
別のターミナルでSSHに接続してtestトピックに投稿(publish)します。
mosquitto_pub -d -t test -m “test 1”
すると、サブスクライバー側で以下のように表示されます。
Client mosqsub/6162-lex received PUBLISH (d0, q0, r0, m0, ‘test’, … (6 bytes))
test 1
これで最低限の動作はokですね。
続いてcodey側にこんなコードをアップしてみました。
以下のリファレンスからサンプルコードを流用していますが、リファレンス内のサンプルコードの「from mqtt import MQTTClient」は誤りで、正しくは「from cloud_message.mqtt import MQTTClient 」です。
■サンプルコード
#import mqtt package #リファレンスは"from mqtt import MQTTClient"となっているが実際はcloud.message.mqttが正しい #https://forum.makeblock.com/t/importerror-no-module-named-mqtt/15029 from cloud_message.mqtt import MQTTClient import codey, time, event import utime MQTTHOST = "mosquittoのサーバのIPアドレス" MQTTPORT = 1883 #なんでもいいらしいが重複はだめっぽい。 #https://qiita.com/egnr-in-6matroom/items/3aef4bd45857e75bb1d3 client_id = "101" # Example Path #ここの指定方法がまだわからない・・・。全部取得してみる。 Topic = "#" # ID / PWはオプション。今回はmosquitto側では指定していないので省略した。 #mqttClient = MQTTClient(client_id, MQTTHOST, port=MQTTPORT, user='test', password='test', keepalive=0, ssl=False) mqttClient = MQTTClient(client_id, MQTTHOST, port=MQTTPORT, keepalive=0, ssl=False) # Connect to the MQTT server def on_mqtt_connect(): mqttClient.connect() # publish a message def on_publish(topic, payload, retain=False, qos = 0): mqttClient.publish(topic, payload, retain, qos) # message processing function def on_message_come(topic, msg): #print(topic + " " + ":" + str(msg)) #b'test'みたいな表示になるので、文字列化して分割。なおメッセージ自体に'(シングルクォーテーション)がある場合は""で囲まれるが未対応 temp_msg = str(msg).split("'")[1] codey.display.show(temp_msg,wait=True) # subscribe message def on_subscribe(): mqttClient.set_callback(on_message_come) mqttClient.subscribe(Topic, qos = 1) @event.button_a_pressed def on_button_a_pressed(): codey.display.show("Start",wait=True) codey.wifi.start('SSID', 'パスワード', codey.wifi.STA) time.sleep(1) if codey.wifi.is_connected(): codey.emotion.smile() on_mqtt_connect() on_subscribe() codey.display.show("Ready!",wait=True) while True: #RTCがついてないので起動からの時間となる。 #nowtime = utime.time() #codey.display.show(nowtime,wait=True) #codey.display.show(codey.battery.get_percentage(),wait=True) # Blocking wait for message mqttClient.wait_msg() #ブロッキングしない方 #mqttClient.check_msg() time.sleep(1) else: codey.emotion.shiver() @event.button_b_pressed def on_button_b_pressed(): codey.display.show("Stopped",wait=True) codey.stop_all_scripts()
これをcodeyにアップロードすると、パブリッシュされたメッセージを表示するようになります。
だいぶ前に作ったbrouteから消費電力を取得するスクリプトを少し改変して、取得した結果を単純にmosquitto_pub -d -t test -m 値で投稿(publish)するようにしました。
#python上からosコマンドを実行しています。こういう移植性のないことしちゃだめですね。ちゃんとmqttをpythonから操作するように変更しないと・・・
動作の様子はこんな感じです。
エアコンを入れると消費電力がちゃんと上がってますね。
本当はメッセージが無い間は、時計にでもしようと思ったのですが、odey rockyにはRTCが搭載されていないようで、utime.time()で取得した値は、電源投入後からの起動時間(秒)となります。
mqttClient.wait_msg()はブロックされますが、mqttClient.check_msg() はブロックされないので、まぁバッテリーの残量を出すとかそういう感じのことはできそうですね。
あと、MQTTのトピックの指定の仕方がよくわかりませんでしたので”#”としています。一応トピックは「test」で来てるみたいですが、「/test/」とかにしてもうまく拾えないんですよね。
これはもうちょっと調べないと。
次は赤外線周りをなんかやってみようかな。
【バックナンバー】
ではでは。またの機会に。