MQTTで亀を操る

辻 真吾(@tsjshg)

みんなのPython勉強会#8

2016/1/8

自己紹介

  • 1975年8月3日生まれ(今年は大厄)
  • 東京大学先端科学技術研究センターゲノムサイエンス分野(来週失業予定)
  • Pythonを使ったデータ解析が結構得意
  • 勢いのあるPythonの普及を、さらに加速させたい!

まずはデモから

In [ ]:
# 指揮官側(送信側)
import paho.mqtt.client as mqtt
import time
import random
import struct

client = mqtt.Client()
client.connect("test.mosquitto.org", 1883)

def move():
	cmd = random.choice(['forward','backward','circle'])
	arg = random.choice([10,20,40])
	return '{}:{}'.format(cmd, arg)

def rotate():
	cmd = random.choice(['left','right'])
	arg = random.randint(0,360)
	return '{}:{}'.format(cmd, arg)

def cmd_gen():
	return random.choice([move, rotate])()

while client.loop() == 0:
	client.publish("/tsjshg.info/kame_cmd", cmd_gen(), 0, False)
	time.sleep(2)
In [ ]:
# カメ側(受け手側)
import paho.mqtt.client as mqtt
import turtle

def on_message(client, userdata, msg):
	print(msg.payload)
	cmd = msg.payload.decode('utf-8').split(':')
	getattr(client.kame, cmd[0])(int(cmd[1]))

def make_kame():
	turtle.setup(400,400)
	kame = turtle.Turtle()
	kame.shape('turtle')
	kame.shapesize(2,2,3)
	return kame

client = mqtt.Client()
client.on_message = on_message
client.connect("test.mosquitto.org", 1883)
client.subscribe('/tsjshg.info/kame_cmd')
client.kame = make_kame()

while client.loop() == 0:
	pass

MQTTとは?

  • publish/subscribe型の軽量なメッセージングプロトコル
  • IoT、M2Mの分野で注目されている(と思う)

MQTTについてもう少し

準備

$ pip install paho-mqtt

コード解説(指揮官側)

publish側

In [ ]:
# クライアントのインスタンスを生成して、Brokerに接続
client = mqtt.Client()
client.connect("test.mosquitto.org", 1883)
# 無料で誰でも利用できるBrokerが公開されている
In [ ]:
# 送信するpayload
# メソッド名と引数を:で繋いだ文字列を作る
def move():
	cmd = random.choice(['forward','backward','circle'])
	arg = random.choice([10,20,40])
	return '{}:{}'.format(cmd, arg)
In [ ]:
# 作成したpayloadをpublishして2秒待つを繰り返す
while client.loop() == 0:
	client.publish("/tsjshg.info/kame_cmd", cmd_gen(), 0, False)
	time.sleep(2)

コード解説(カメ側)

subscribe側

In [ ]:
# Pythonスタートブックでお馴染みの
# turtleモジュールを使ってカメを用意
def make_kame():
	turtle.setup(400,400)
	kame = turtle.Turtle()
	kame.shape('turtle')
	kame.shapesize(2,2,3)
	return kame
In [ ]:
# クライアントのインスタンスを生成
client = mqtt.Client()
# 後で解説
client.on_message = on_message
# 接続は、publish側と同じ
client.connect("test.mosquitto.org", 1883)
# subscribeするtopicを指定
client.subscribe('/tsjshg.info/kame_cmd')
# インスタンス変数にturtle.Turtleのインスタンスを格納(Python便利)
client.kame = make_kame()
In [ ]:
# メッセージをsubscribeしたときに呼び出される関数
def on_message(client, userdata, msg):
	print(msg.payload)
	cmd = msg.payload.decode('utf-8').split(':')
	getattr(client.kame, cmd[0])(int(cmd[1]))
In [6]:
# 組み込み関数getattrを使うと、文字列でメソッド(属性)を呼び出せる
s = 'ABC{}'
# 以下の2つは同じ意味
s.format('D')
getattr(s, 'format')('D')
Out[6]:
'ABCD'

時間があれば2匹のランデブー

おしまい

ご質問ありましたらご遠慮なく