MQTT Publisher ボックスを作る


## はじめに
* MQTT とは
詳細は以下のサイト等で確認して頂ければと思いますが、簡単な説明としては Pub/Sub メッセージングモデルの軽量なプロトコルです。IoT, WoT で繋がるような非力なデバイスで動かすことを想定しているため、色々と低コストでの処理が可能です。
 * [MQTT](http://mqtt.org/)
 * [MQTTについてのまとめ](http://tdoc.info/blog/2014/01/27/mqtt.html)

* Pepper 君でも使えるのではないかと思い、ちょっと試してみます。
* MQTT 勉強中です。


### MQTT Publisher ボックス

MQTT の Python 用ライブラリとして、以下のライブラリを使用します。

* [Paho - Open Source messaging for M2M](https://eclipse.org/paho/)

ますは Python ボックスを作り、入力の Type を「バン」から「文字列」に変更します。

![2015032101.png](https://qiita-image-store.s3.amazonaws.com/0/20418/5c4049df-b090-3af9-a5fa-fcb389a7574f.png "2015032101.png")


#### 設定項目

設定項目はこんな感じにします。

MQTT のブローカのホスト、ポート、KeepAlive 値と、メッセージ送信するトピック、QOS 値、Retain 値を指定できるようにします。

![2015032102.png](https://qiita-image-store.s3.amazonaws.com/0/20418/50a724a0-0e48-df1f-f859-6a3fed97d4bb.png "2015032102.png")


#### Python コード

コードはこんな感じにします。各種パラメータを取得して、MQTT ブローカに接続・メッセージを送信します。

ボックス内でのライブラリの使用方法は、以下の記事を参考にさせて頂きました。

* [Pepper用Tweetボックスをつくる](http://qiita.com/yacchin1205/items/3422b5066dcbfca63def)

```python
class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        self.framemanager = ALProxy("ALFrameManager")
        self.folderName = None
        
    def onUnload(self):
        import sys
        
        if self.folderName and self.folderName in sys.path:
            sys.path.remove(self.folderName)
        self.folderName = None

    def onInput_onStart(self, payload):
        import sys, os
        
        self.folderName = os.path.join(
            self.framemanager.getBehaviorPath(self.behaviorId), "../lib")
        if self.folderName not in sys.path:
            sys.path.append(self.folderName)
            
        import paho.mqtt.client as paho

        host       = self.getParameter("Broker Host")
        port       = self.getParameter("Broker Port")
        keep_alive = self.getParameter("KeepAlive")
        topic      = self.getParameter("Topic")
        qos        = self.getParameter("Qos") 
        retain     = self.getParameter("Retain")
        
        mqttc = paho.Client()
        mqttc.connect(host, port, keep_alive)
        mqttc.publish(topic, payload, qos, retain)

    def onInput_onStop(self):
        self.onUnload()
        self.onStopped()
```


#### Choregraphe で接続

メッセージ内容を設定するための「Text Edit」ボックスと、作成した「MQTT」ボックスを接続します。

![2015032103.png](https://qiita-image-store.s3.amazonaws.com/0/20418/5f51a604-4423-30e3-872b-2cff7a73c357.png "2015032103.png")


### Subscriber 側

MQTT Publisher 側から送信するメッセージを受け取る側になる Subscriber を用意します。Pub 側と同じ Paho ライブラリを使用しています。

```sub.py
import paho.mqtt.client as paho

def on_message(mqttc, obj, msg):
    print("topic: " + msg.topic + ", payload: " + str(msg.payload) + ", qos: \
" + str(msg.qos) + ", retain: " + str(msg.retain))

if __name__ == '__main__':
    mqttc = paho.Client()

    mqttc.on_message = on_message
    mqttc.connect("test.mosquitto.org", 1883, 60)
    mqttc.subscribe("my/topic/pepper", 0)

    mqttc.loop_forever()
```


### 動作確認

#### Subscriber を実行

PC 上で実行し、トピックに対するメッセージを受け取るために待機します。

```bash
$ python sub.py
```


#### Publisher を実行

Choregraphe でプログラムを実行し、メッセージを送信します。


#### 結果表示

Publisher -> Broker -> Subscriber とメッセージが伝わり、Subscriber 側で表示されました。

```bash
$ python sub.py
topic: my/topic/pepper, payload: Hello World from Pepper, qos: 0, retain: 0
```


## 感想

* Publisher 側のほうが使いようがあるかと思って試してみたのですが、Subscriber 側としても面白そうな気がしてきました。