参考
概要
PC(Mac)でBroker(mosquitto)を立ち上げ、LEGO Mindstorms EV3とのMQTT通信を行った際に
少しつまずいたのでメモ
環境
PC
- macOS Catalina バージョン 10.15.7
- Homebrew 3.3.10
- Python 3.8.5(paho-mqtt使用)
- mosquitto version 2.0.14
EV3
- OS : ev3dev
- Python 3.5.3
内容
PCでBrokerを立ち上げPCからメッセージをEV3へ送信する
PC(Broker, publisher) → EV3(subscriber)
PC
- mosqittoをインストール
- paho-mqttインストール
- publish用のコード作成
EV3
- subscribe用のコード作成
実行手順
- PC: Broker(mosquito)起動
- EV3: subscribe用のコード実行 ←つまずいた箇所
- PC: publish用のコード実行
- EV3: 確認
PC
- mosqittoをインストール
% brew install mosquitto
初期状態だとパス が通っていないため以下でBroker起動できる
$ /usr/local/opt/mosquitto/sbin/mosquitto
mosquittoのパスを通すため .zshrc に以下の記述を追加
export PATH=/usr/local/opt/mosquitto/sbin:$PATH
export PATH=/usr/local/opt/mosquitto/bin:$PATH
% source .zshrc
パスが通っていれば以下のコマンドでBrokerを起動できる
% mosquitto
1642506173: mosquitto version 2.0.14 starting
1642506173: Using default config.
1642506173: Starting in local only mode. Connections will only be possible from clients running on this machine.
1642506173: Create a configuration file which defines a listener to allow remote access.
1642506173: For more details see https://mosquitto.org/documentation/authentication-methods/
1642506173: Opening ipv4 listen socket on port 1883.
1642506173: Opening ipv6 listen socket on port 1883.
1642506173: mosquitto version 2.0.14 running
2. paho-mqttインストール
問題なくインストールできればok
pip install paho-mqtt
3. publish用のコード作成
コードは以下の記事のコードを参考にしています
コードの内容としてはBrokerに対してトピックを指定した上で
"Hello_EV3!!"という文字列を5回送信
#!/usr/bin/env python3
# === プログラミング概要 ===#
# MQTTテスト用のプログラム
# Publisher
# =======================#
import paho.mqtt.client as mqtt
from time import sleep
MQTT_PORT = 1883
KEEP_ALIVE = 60
TOPIC = "topic/01/"
#Brokerに接続できたとき
def on_connect(client, userdata, flag, rc):
print("Connect Broker:" + str(rc))
#Brokerと切断したとき
def on_disconnect(client, userdata, rc):
if rc != 0:
print("disconnect broker")
#publishが完了したとき
def on_publish(client, userdata, mid):
print("publish Done")
#ログ
def on_log(client, userdata, level, buf):
print("log: ", buf)
client = mqtt.Client()
#コールバックを登録
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
client.on_log = on_log
client.connect("localhost", MQTT_PORT, KEEP_ALIVE)
for i in range(5):
client.publish(TOPIC,f"{i}Hello_EV3!!")
sleep(3)
client.disconnect()
EV3
- publish用のコード作成
コードの内容としてはBrokerに対して指定したトピックの内容を受信
#!/usr/bin/env python3
# === プログラミング概要 ===#
# MQTTテスト用のプログラム
# Subscriber
# =======================#
import paho.mqtt.client as mqtt
MQTT_PORT = 1883
KEEP_ALIVE = 60
TOPIC = "topic/01/"
#Brokerに接続できたとき
def on_connect(client, userdata, flag, rc):
print("connect broker:" + str(rc))
client.subscribe(TOPIC)
#Brokerと切断したとき
def on_disconnect(client, userdata, rc):
if rc != 0:
print("disconnect broker")
#メッセージ受信
def on_message(client, userdata, msg):
print("Received message '" + str(msg.payload) + "' on topic '" + msg.topic + "' with QoS " + str(msg.qos))
#ログ
def on_log(client, userdata, level, buf):
print("log: ", buf)
client = mqtt.Client()
#コールバックを登録
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.on_log = on_log
# IPアドレスは環境ごとに切り替える
client.connect("192.168.11.2", MQTT_PORT, KEEP_ALIVE)
#待ち受け
client.loop_forever()
##実行手順
- PC: Broker(mosquito)起動
% mosquitto
1642506173: mosquitto version 2.0.14 starting
1642506173: Using default config.
1642506173: Starting in local only mode. Connections will only be possible from clients running on this machine.
1642506173: Create a configuration file which defines a listener to allow remote access.
1642506173: For more details see https://mosquitto.org/documentation/authentication-methods/
1642506173: Opening ipv4 listen socket on port 1883.
1642506173: Opening ipv6 listen socket on port 1883.
1642506173: mosquitto version 2.0.14 running
2. EV3: subscribe用のコード実行
robot@ev3dev:~$ python3 mqtt_sub.py
Traceback (most recent call last):
File "mqtt_sub.py", line 36, in <module>
client.connect("192.168.11.2", MQTT_PORT, KEEP_ALIVE)
File "/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py", line 914, in connect
return self.reconnect()
File "/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py", line 1044, in reconnect
sock = self._create_socket_connection()
File "/usr/local/lib/python3.5/dist-packages/paho/mqtt/client.py", line 3685, in _create_socket_connection
return socket.create_connection(addr, timeout=self._connect_timeout, source_address=source)
File "/usr/lib/python3.5/socket.py", line 712, in create_connection
raise err
File "/usr/lib/python3.5/socket.py", line 703, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
Brokerから接続拒否されている
先ほどのBroker(mosquitto)起動時の表示を確認すると
ローカルのみ接続可能となっているためためmosquittoの設定の変更が必要
1642506173: Starting in local only mode. Connections will only be possible from clients running on this machine.
以下の設定ファイルに外部からのアクセスを許可する内容を追記
(省略)
listener 1883
allow_anonymous true
再度Broker(mosquitto)を起動
% mosquitto
1642506173: mosquitto version 2.0.14 starting
1642506173: Using default config.
1642506173: Starting in local only mode. Connections will only be possible from clients running on this machine.
1642506173: Create a configuration file which defines a listener to allow remote access.
1642506173: For more details see https://mosquitto.org/documentation/authentication-methods/
1642506173: Opening ipv4 listen socket on port 1883.
1642506173: Opening ipv6 listen socket on port 1883.
1642506173: mosquitto version 2.0.14 running
治ってない???
どうやらBroker起動時にオプション -c で設定ファイルを指定する必要がある
% mosquitto -c /usr/local/opt/mosquitto/etc/mosquitto/mosquitto.conf
1642509183: mosquitto version 2.0.14 starting
1642509183: Config loaded from /usr/local/opt/mosquitto/etc/mosquitto/mosquitto.conf.
1642509183: Opening ipv6 listen socket on port 1883.
1642509183: Opening ipv4 listen socket on port 1883.
1642509183: mosquitto version 2.0.14 running
再度EV3よりsubscribe用のコードを実行
robot@ev3dev:~$ python3 mqtt_sub.py
connect broker:0
3. PC: publish用のコード実行
% python3 mqtt_pub.py
publish Done
publish Done
publish Done
publish Done
publish Done
4. EV3: 確認
robot@ev3dev:~$ python3 mqtt_sub.py
connect broker:0
Received message 'b'0Hello!_EV3!!'' on topic 'topic/01/' with QoS 0
Received message 'b'1Hello!_EV3!!'' on topic 'topic/01/' with QoS 0
Received message 'b'2Hello!_EV3!!'' on topic 'topic/01/' with QoS 0
Received message 'b'3Hello!_EV3!!'' on topic 'topic/01/' with QoS 0
Received message 'b'4Hello!_EV3!!'' on topic 'topic/01/' with QoS 0
PC(publisher)より送信したデータをBrokerを介してEV3(subscriber)で受信することを確認した。
以上