Intel EdisonとIBM IoT Foundation & Bluemixの連携

Intel Edisonと[IBM IoT Foundation](http://www-03.ibm.com/software/products/ja/internet-of-things-foundation)をMQTTで接続し、EdisonからIoT Foundationにpublishされたデータを[IBM Bluemix](http://www-01.ibm.com/software/jp/info/bluemix/)で受け取る手順をまとめた。

> 以下のスクリーンショットは2015/07/01時点のもの。

# EdisonのMacアドレスからデバイスIDを特定

IoT Foundationにデータをpublishする際には、送信元デバイスのMACアドレスから生成したデバイスIDを登録しておかなければならない。
例えばEdisonのWi-Fi経由でIoT Foundationに接続する場合、wlan0に相当するデバイスIDを登録することになる。

```text:MACアドレス確認
root@edison:~# ip link show wlan0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether fc:c2:de:3d:1b:6e brd ff:ff:ff:ff:ff:ff
```

デバイスIDはMACアドレスをオクテットごとに16進数表記して文字列連結したものなので、今回テストしたEdisonの場合、**fcc2de3d1b6e**となる。

# BluemixでIoTアプリケーション作成

## IoTアプリケーション作成

まず最初に、Bluemixのボイラープレートを活用してIoTアプリケーションを作成することから始める。
IBM Bluemix Potal（ https://console.ng.bluemix.net/ ）からログインし、上部メニューバーの「カタログ」をクリックする。

![edison_bluemix_02.png](https://qiita-image-store.s3.amazonaws.com/0/37648/d8301de1-8709-20a1-d294-7dc0b768f5f0.png)

「Internet of Things Foundation Starter」を選択し、アプリケーション名とホスト名を入力して「CREATE」する。

> アプリケーション名やホスト名の名前空間は利用者全員で共用されるため、ユニークな名称にすること。

今回はアプリケーション名を**edison-bluemix-app-999**、ホスト名を**edison-bluemix-server-999**とした。

![edison_bluemix_03.png](https://qiita-image-store.s3.amazonaws.com/0/37648/c30f9a00-2bc0-6529-bbc8-a37df2b54eaf.png)

数分待つと、IoTアプリケーションが起動したことが通知される。

![edison_bluemix_04.png](https://qiita-image-store.s3.amazonaws.com/0/37648/68eb412d-5b78-91ed-86e5-011fa6c534be.png)

## IoTサービスの追加

左ペインの「概要」をクリックし、edison-bluemix-app-999の概要を表示する。

![edison_bluemix_05.png](https://qiita-image-store.s3.amazonaws.com/0/37648/ac9e5750-85ec-5b55-ab1d-dcd2a3894142.png)

「サービスまたはAPIの追加」をクリックしてBluemixサービスのカタログを表示し、「Internet of Things」を選択する。

![edison_bluemix_06.png](https://qiita-image-store.s3.amazonaws.com/0/37648/1c5805d5-b654-4f31-65e1-f029b78bb7ec.png)

「作成」をクリックして、edison-bluemix-app-999にIoTサービスを追加する。

![edison_bluemix_07.png](https://qiita-image-store.s3.amazonaws.com/0/37648/73dfc2cd-2ebe-1b6a-0372-f8c10c10eecb.png)

"アプリケーションの再ステージ"というメッセージウィンドウが表示されるので、「再ステージ」ボタンを押す。

# IoTサービスの設定

## IoT Foundationに追加されたIoTサービスの概要を表示

左ペインの「Internet of Things」サービスをクリックすると、IoT Foundationのスタートページが表示される。

![edison_bluemix_08.png](https://qiita-image-store.s3.amazonaws.com/0/37648/15ec08ce-b861-38ff-b8c1-68918ca7893c.png)

「Launch dashboard」をクリックして、IoT Foundation内に作成されたedison-bluemix-app-999用のIoTサービスのダッシュボードを表示する（今回は、**4n0ini**というIDのOrganizationでIoTサービス作成された。このOrganization IDはIoTサービスを作るごとに変わる）。

![edison_bluemix_09.png](https://qiita-image-store.s3.amazonaws.com/0/37648/b17aa378-c958-29f0-3069-b6605b4164fe.png)

## このIoTサービスを利用するアカウントを追加

「PEOPLE」をクリックしてアカウント管理画面を表示する。「Add Person」をクリックするとID入力欄が表示されるので、自分自身のBluemix IDを登録する。

![edison_bluemix_10.png](https://qiita-image-store.s3.amazonaws.com/0/37648/d96bdae2-0e5e-710f-61a0-6bedc46a7032.png)

## このIoTサービスに接続するデバイスを追加

「DEVICES」をクリックしてデバイス管理画面を表示する。「Add Device」をクリックするとデバイス入力欄が表示されるので、最初に調べたEdisonのデバイスIDを入力する。なおDevice Typeは任意の文字列で良い（今回はmyedisonと入力した）。

![edison_bluemix_11.png](https://qiita-image-store.s3.amazonaws.com/0/37648/e479e8d0-30ca-7bca-203d-da36d36a82f6.png)

「Continue」をクリックするとデバイスが登録され、以下のような接続設定情報が表示される。これらの情報はEdisonからIoT Foundationに接続する際に必要となるため、メモしておくこと。

```text:表示される認証トークン等の情報
org=4n0ini
type=myedison
id=fcc2de3d1b6e
auth-method=token
auth-token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

> 認証トークンは再表示することができないため、この情報を失った場合はデバイスを再登録しなければならない。

「Done」をクリックすると、デバイス管理画面が表示される。この時点ではEdisonとIoT Foundationの接続が確立していないため、登録したデバイス行の最初に灰色の◆マークが付いている。

![edison_bluemix_12.png](https://qiita-image-store.s3.amazonaws.com/0/37648/8a670fdc-5a01-df15-4139-45c09bf9cec6.png)

# Bluemix IoTアプリケーションの修正

## Node-REDビジュアルエディタを表示

Bluemixのダッシュボードに戻り、edison-bluemix-app-999の「概要」を表示する。「経路」として「edison-bluemix-server-999.mybluemix.net」が表示されているので、クリックするとNode-RED in Bluemixのスタートページが表示される。

![edison_bluemix_13.png](https://qiita-image-store.s3.amazonaws.com/0/37648/984a28cc-9561-d6ff-38b9-af861ab7f3ba.png)

「Go to your Node-RED flow editor」をクリックして、Node-REDのビジュアルエディタを表示する。

![edison_bluemix_14.png](https://qiita-image-store.s3.amazonaws.com/0/37648/8fcb8413-702f-4f2c-7ec4-0d237b5affcc.png)

## フローの修正

最初からサンプルのフローが登録されているが、今回はEdisonからデータが取得できることを確認するだけなので、「IBM IoT App In」と「device data」の２つのノードだけ残して他は全部削除する。

![edison_bluemix_15.png](https://qiita-image-store.s3.amazonaws.com/0/37648/d62067d9-dfc4-6775-80ea-14373603de81.png)

## 「IBM IoT App In」ノードにデバイス情報を登録

「IBM IoT App In」ノードをダブルクリックすると、パラメータ登録ウィンドウが開く。

![edison_bluemix_16.png](https://qiita-image-store.s3.amazonaws.com/0/37648/e3995ee5-f69c-c749-e891-43c32021cd44.png)

「Authentication」を"Bluemix Service"にし、Device Idに接続するEdisonのデバイスIDを記入して「OK」をクリックする。

![edison_bluemix_17.png](https://qiita-image-store.s3.amazonaws.com/0/37648/7bfd4a10-be4b-5792-0e20-165e0156c012.png)

## 修正したフローのデプロイ

最後に、右上の赤い「Deploy」ボタンをクリックする。フローが正しくデプロイされると、ボタンが灰色になる。
ここまでで、IoT FoundationとBluemixが接続された。

# Edisonからデータをpublishするプログラムの作成

次にEdisonからIoT Foundationへデータをpublishするプログラムを作成する。今回はpython 2.7でプログラムを記述し、MQTTクライアントライブラリとしてはeclipse.orgが公開している[paho](https://eclipse.org/paho/clients/python/docs/)を用いることにした。

## pipのインストール

まずはpipをインストールする。Edisonの **/** 以下は残容量に余裕が無いため、比較的余裕がある /home 以下にインストールする。

```text:.profileの設定
root@edison:~# echo 'export PATH=/home/root/.local/bin:$PATH' >> .profile
root@edison:~# echo 'export PYTHONPATH=/home/root/.local/lib/python2.7/' >> .profile
root@edison:~# source ~/.profile
```

```text:.pydistutils.cfgの設定
root@edison:~# echo -e "[install]\nuser=1" >> .pydistutils.cfg
```

```text:setuptoolsのインストール
root@edison:~# wget https://bootstrap.pypa.io/ez_setup.py --no-check-certificate -O - | python
```

```text:pipのインストール
root@edison:~# easy_install pip
```

## pahoのインストール

次にpipを用いてpahoをインストールする。

```text:pahoのインストール
root@edison:~# pip install paho-mqtt
```

下記のコマンドでエラーが表示された場合、pahoのインストールに失敗しているので、作業手順を見直すこと。

```text:インストールの確認
root@edison:~# python -c "import paho.mqtt.client"
```

## IoT Foundationへの接続設定ファイル作成

メモしておいた情報を元に、Edison上に接続設定ファイルを作成する。

```text:表示される認証トークン等の情報
root@edison:~# cat iotfoundation.conf 
org=4n0ini
type=myedison
id=fcc2de3d1b6e
auth-method=token
auth-token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

## pythonプログラムの作成

今回はEdisonとIoT Foundation & Bluemixの接続確認用に、-10〜10の間でランダムに生成した数値を1秒ごとにIot Foundationへ送りつける簡単なpythonプログラムを作成する。

下記プログラムでは、おおよそ以下のような処理を行っている。

1. 引数として指定された接続設定ファイルをパース
2. IoT Foundationから与えられた情報を元に、client_nameや接続先URL等を組み立て
3. ユーザー名を「use-token-auth」、パスワードを与えられた認証トークンとして、IoT Foundationに接続
4. 1秒ごとにランダムな数値を発生させてjsonでペイロードを組み立てpublish

```python:bluemix.py
#! /usr/bin/env python
# -*- conding: utf-8 -*-

import paho.mqtt.client as paho
import re
import sys
import time

import random


class BluemixMQTTClient(object):
    CLIENT_NAME_BASE = "d:%s:%s:%s"
    URL_BASE = "%s.messaging.internetofthings.ibmcloud.com"
    TOPIC = "iot-2/evt/status/fmt/json"
    PORT = 1883
    USER = "use-token-auth"

    def __init__(self, org, type, id, token):
        client_name = self.CLIENT_NAME_BASE % (org, type, id)
        url = self.URL_BASE % org

        self.mqttc = paho.Client(client_name)
        self.mqttc.username_pw_set(self.USER, token)
        self.mqttc.connect(url, self.PORT, 60)

    def publish(self, msg):
        self.mqttc.publish(self.TOPIC, self.__make_payload(msg))

    def __make_payload(self, msg):
        return "{\"d\":{\"val\":" + str(msg) + "}}"


def parse_conf(filename):
    def search(r):
        return next(y for y in [r.match(x) for x in confs] if y).group(1)

    rorg = re.compile(r"^org=(.+)$")
    rtype = re.compile(r"^type=(.+)$")
    rid = re.compile(r"^id=(.+)$")
    rtoken = re.compile(r"^auth-token=(.+)$")

    confs = [x.rstrip() for x in list(open(filename, "r"))]
    return (search(rorg), search(rtype), search(rid), search(rtoken))


def main(conf_filename):
    org, type, id, token = parse_conf(conf_filename)
    mqttc = BluemixMQTTClient(org, type, id, token)

    while True:
        val = random.randint(-10, 10)
        print val
        mqttc.publish(val)
        time.sleep(1)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print "Usage: %s config_file_name" % sys.argv[0]
        quit()

    try:
        print "start"
        main(sys.argv[1])
    except KeyboardInterrupt as err:
        print "end"
```

# EdisonとIoT Foundation & Bluemixの接続

では実際に、EdisonからIoT Foundation & Bluemixに接続してみる。

接続設定ファイルを引数にプログラムを起動すると、-10〜10の間のランダムな値が1秒に1回IoT Foundationにpublishされる。

```text:プログラム起動
root@edison:~# ./bluemix.py ./iotfoundation.conf 
start
-7
-3
0
3
```

Bluemix Node-REDのビジュアルエディタで「device data」ノードのデバッグウィンドウを確認すると、Edisonからpublishされた値を受け取っていることを確認できる。

![edison_bluemix_18.png](https://qiita-image-store.s3.amazonaws.com/0/37648/c0843b4b-8b21-5735-7e6d-763f635bd3da.png)

またIoT Foundationのデバイス管理画面を見ると、データを受信している最中は緑色の●が表示されていることも確認できる。

![edison_bluemix_19.png](https://qiita-image-store.s3.amazonaws.com/0/37648/f7c9b447-d69f-045a-3d5d-dd45aee37202.png)

# まとめ

MQTTライブラリを活用することで、EdisonからIoT Foundation & Bluemixに簡単に接続することができた。Bluemixが提供する様々なサービスとうまく組み合わせることで、より高度なIoTアプリケーションへ発展させることができるだろう。