BluemixでRaspberryPi2を制御する (2)アクチュエータを動かす　光編　RasPi2のオンボードLED

#<i class="fa fa-cubes" style="font-size:1em;"></i>概要
[BluemixのRaspberryPi登録レシピ](https://developer.ibm.com/recipes/tutorials/raspberry-pi-4/)に登場する[デバイス用のsampleプログラム](https://github.com/ibm-messaging/iot-raspberrypi/releases/tag/1.0.2)は、Bluemixからのデータの受信によってシステム停止(Linuxのshutdownコマンド)のみ行える作りになっている。

Raspberry Pi 2にアクチュエータを付け加えてBluemixからアクチュエータを制御するには、[sampleプログラムのソースコード](https://github.com/ibm-messaging/iot-raspberrypi/blob/master/samples/c/)を修正してビルドすれば良い。その方法を整理する。

※以下でやったことの反対方向(Bluemix→Raspberry Pi 2)をやってみる。
[BluemixでRaspberryPi2のセンサーデータを拾う (1)仕組みの理解](http://qiita.com/getapojim/items/b76ea2cfadaff6dfd159)
[BluemixでRaspberryPi2のセンサーデータを拾う (2)センサーを付けてデータを拾う　温度センサーデジタル編](http://qiita.com/getapojim/items/0f2b5178bfaddafcde9f)
[BluemixでRaspberryPi2のセンサーデータを拾う (3)センサーを付けてデータを拾う　温度センサーアナログ編](http://qiita.com/getapojim/items/12e5cb64a8046ab033e9)
[BluemixでRaspberryPi2のセンサーデータを拾う (4)センサーを付けてデータを拾う　温度センサーデジタル編（リベンジ）](http://qiita.com/getapojim/items/0ea4c7369d342d5b00d5)
[BluemixでRaspberryPi2のセンサーデータを拾う (5)センサーを付けてデータを拾う　温度・湿度・気圧まとめて採取編](http://qiita.com/getapojim/items/dfa526ece3af603b981e)
番外編 [『ムック「日経Linux ラズパイマガジン 2015年春号 」電子工作入門キット パーツセット』に入っていたもの](http://qiita.com/getapojim/items/c90edd38c0ad9d5eb379)


これから整理するにあたりきっとまた長い道のりになりそうなので、(1)Sampleプログラムの仕組みの整理と(2)どこをどのように変更すればよいのかを分けることにした。

[(1)　仕組みの理解](http://qiita.com/getapojim/items/8fffa73100292665eebc)
(2)　アクチュエータを動かす　光編　RasPi2のオンボードLED　　(これ)
[(3)　アクチュエータを動かす　光編　外付けのLED](http://qiita.com/getapojim/items/b8028d1aeb975432afda)
[(4)　アクチュエータを動かす　音編](http://qiita.com/getapojim/items/9440de8ee37e6d8e7e63)

#<i class="fa fa-cube" style="font-size:1em;"></i>前提
RaspberryPi2がBluemixのIoTFサービスに[「レシピ」](https://developer.ibm.com/recipes/tutorials/raspberry-pi-4/)を使って接続済みであること。

#<i class="fa fa-cube" style="font-size:1em;"></i>手始めに
RasPi2オンボードのLEDを制御できる（らしい）ので、まずは何も付けずにこれ↓をやってみる。
http://blog.livedoor.jp/victory7com/archives/43512294.html


#<i class="fa fa-cube" style="font-size:1em;"></i>Raspberry Pi 2上でオンボードLEDを制御してみる。

##LEDのモード確認
念のため最初に確認しておく。

`$ cat /sys/class/leds/led0/trigger`
none **[mmc0]** timer oneshot heartbeat backlight gpio cpu0 cpu1 cpu2 cpu3 default-on input

`$ cat /sys/class/leds/led1/trigger`
none mmc0 timer oneshot heartbeat backlight gpio cpu0 cpu1 cpu2 cpu3 default-on **[input]**

"led0"(ACT LED)が"mmc0"、"led1"(PWR LED)が"input"になっていることが分かる。

##shellスクリプト作成
[上記のサイト](http://blog.livedoor.jp/victory7com/archives/43512294.html)の内容を参考にshellスクリプトを作成する。
そのままだと再起動するまで点滅しっぱなしなので、後片付けの処理も入れた。
`$ cd ~/bin`
`$ vi ctlLedRPi.sh`
`$ chmod 755 ctlLedRPi.sh`

```bash:/home/pi/bin/ctlLedRPi.sh
#!/bin/bash
# ACT LEDを0.5秒間隔で、PWR LEDを2秒間隔で点滅させる

echo timer > /sys/class/leds/led0/trigger         # ACT LEDである"led0"を"timer"モードにする
echo 250 > /sys/class/leds/led0/delay_on          # ACT LEDを250ミリ秒点灯する
echo 250 > /sys/class/leds/led0/delay_off         # ACT LEDを250ミリ秒消灯する
echo timer > /sys/class/leds/led1/trigger         # PWR LEDである"led1"を"timer"モードにする
echo 1000 > /sys/class/leds/led1/delay_on         # PWR LEDを250ミリ秒点灯する
echo 1000 > /sys/class/leds/led1/delay_off        # PWR LEDを250ミリ秒消灯する

# 10秒続けたらLEDのモードを元に戻してから終了する。
sleep 10
echo mmc0 > /sys/class/leds/led0/trigger          # ACT LEDである"led0"を"mmc0"モードに戻す
echo input > /sys/class/leds/led1/trigger         # PWR LEDである"led1"を"input"モードに戻す

exit 0
```

##shellスクリプト実行
root権限が必要
`$ cd ~/bin/`
`$ sudo ./ctlLedRPi.sh`
![ctlLedRPi実行.png](https://qiita-image-store.s3.amazonaws.com/0/85506/61d9f6b1-4950-701e-bafc-757a4b9b5876.png)

動画を撮ってみた。
<blockquote class="twitter-video" lang="ja"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/RaspberryPi?src=hash">#RaspberryPi</a> <a href="https://twitter.com/hashtag/Bluemix?src=hash">#Bluemix</a> <a href="https://twitter.com/hashtag/IoT?src=hash">#IoT</a> <a href="https://twitter.com/hashtag/MQTT?src=hash">#MQTT</a> <a href="https://t.co/8yw7k1YqFA">pic.twitter.com/8yw7k1YqFA</a></p>&mdash; m (@getapojim) <a href="https://twitter.com/getapojim/status/658959181056053249">2015, 10月 27</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

#<i class="fa fa-cube" style="font-size:1em;"></i>プログラムの改修内容

[BluemixのRaspberryPi登録レシピに登場するデバイス用のsampleプログラム](https://github.com/ibm-messaging/iot-raspberrypi/releases/tag/1.0.2)を次の通り修正する。
[修正前のソースコードはこちらで参照可能](https://github.com/ibm-messaging/iot-raspberrypi/tree/master/samples/c)

|修正するファイル|新規で追加するファイル|
|:--|:--|
|iotmain.c<br>mqttPublisher.c|なし|

追加・修正内容は以下の通り。

修正内容1

```c:iotmain.c(修正前　30行目)
char subscribeTopic[MAXBUF] = "iot-2/cmd/reboot/fmt/json";
```
```c:iotmain.c(修正後)
char subscribeTopic[MAXBUF] = "iot-2/cmd/ledrpi/fmt/json";
```

修正内容2
ソースコードのファイル名が「Publisher」になっていて紛らわしいが、下記の抜粋はSubscribe時の処理。

```c:mqttPublisher.c(修正前　126～130行目)
		sprintf(command,"sudo /sbin/shutdown -r %d", time_delay);
		syslog(LOG_INFO, "Received command to restart in %d minutes.",time_delay);
```

```c:mqttPublisher.c(修正後)
		sprintf(command,"sudo /home/pi/bin/ctlLedRPi.sh");
		syslog(LOG_INFO, "Received command to control LED onboard);
```

#<i class="fa fa-cube" style="font-size:1em;"></i>プログラムの改修手順
作業はRaspberryPi2にログインして行う。
実行時ユーザは次の通り
$ : pi
\# : root

1. 設定ファイルの退避
`# cd /etc/iotsample-raspberrypi/`
``# cp -p device.cfg device.cfg.`date +%Y%m%d`_1``
※これで、アンインストール(dpkg -P)してもフォルダとバックアップファイルが残るので安心。

2. 必要パッケージのインストール
`# apt-get install dpkg-dev build-essential devscripts`
`# apt-get install libssl-dev`

3. ソースコード一式を入手
`$ cd ~`
`$ git clone https://github.com/ibm-messaging/iot-raspberrypi.git`

4. ソースコード修正・追加
`$ cd ~/iot-raspberrypi/samples/c/`
`$ vi iotmain.c`
`$ vi mqttPublisher.c`

5. ビルド
`$ debuild -b`
署名のエラーは無視する。

#<i class="fa fa-cube" style="font-size:1em;"></i>iotサービスの再インストール

1. アンインストール（古いのを）
`# dpkg -P iot`

2. インストール
`# cd /home/pi/iot-raspberrypi/samples/`
`# dpkg -i ./iot_1.0-1_armhf.deb`

3. サービスの確認
`# service iot status`
※起動している(okが表示される)こと。

4. 設定ファイル作成
`# cd /etc/iotsample-raspberrypi/`
``# cp -p device.cfg.`date +%Y%m%d`_1 device.cfg``
※1.でいったん削除されてしまうので、1.で退避したファイルで復元

5. サービスの再起動
`# service iot restart`
※起動している(okが表示される)こと。

6. 起動モードの確認
`# service iot getdeviceid`
※registerd mode で起動している(registerd modeが表示される)こと。

#<i class="fa fa-cube" style="font-size:1em;"></i>BluemixからMQTTプロトコルでJSONデータを送信
##MQTTの構成

BluemixのNode-REDアプリからMQTTプロトコルでpublishし、Raspberry Pi 2上のsampleプログラムからsubscribeする。
　MQTTブローカー　　　　：　Bluemixの[IoT Foundataionサービス](https://internetofthings.ibmcloud.com/)
　MQTTクライアント(pub)　：　Bluemixの[Node-RED](http://nodered.org/)アプリ　※Node-REDでなくても良い。
　MQTTクライアント(sub)　：　[デバイス用のsampleプログラム](https://github.com/ibm-messaging/iot-raspberrypi/releases/tag/1.0.2)
　MQTTのトピック　　　　　：　iot-2/cmd/ledrpi/fmt/json
　MQTTのメッセージ　　　　：　`{"delay":1}`

##MQTTクライアント(publish)の構成
今回はNode-REDアプリとする。
「inject」ノードと「ibmiot out」ノードを使う。
![Node-RED_MQTT_pub_001.png](https://qiita-image-store.s3.amazonaws.com/0/85506/5b6867a2-4b43-f221-4a27-bf9378d9d9b1.png)

injectノードの中身
着火するだけなので空っぽでよい。
![Node-RED_MQTT_pub_002.png](https://qiita-image-store.s3.amazonaws.com/0/85506/01955da7-8847-38ef-4eb1-a25c6b3ff7c2.png)

ibmiot outノードの中身
![Node-RED_MQTT_pub_ledrpi_001.png](https://qiita-image-store.s3.amazonaws.com/0/85506/d9f1047c-6502-f221-ec1e-a012fbf55aa1.png)

|項目名|設定値|備考|
|:--|:--|:--|
|Output Type|Device Command||
|Device Type|iotsample-raspberrypi|IoT Foundationで登録した通りに。<br>IoTFダッシュボードで確認可能|
|Device Id|xxxxxxxxxxxx|RasPi上で以下のコマンドの出力する値<br>`# service iot getdeviceid`<br>IoTFダッシュボードで確認可能|
|Command Type|ledrpi|トピックの一部になるため固定|
|Format|json|トピックの一部になるため固定|
|Data|{"delay":1}|数字は何でもよい|
|Name|IoTF|Node-RED上の表示名なだけなので何でもよい|

上記2つのノードを線でつないだら、右上の「Deploy」ボタンを押してデプロイする。
![Node-RED_MQTT_pub_004.png](https://qiita-image-store.s3.amazonaws.com/0/85506/82b4339e-41fa-b597-914a-236d1d336a83.png)

injectノードをポチッとすると、RasPi上でシェル(/home/pi/bin/ctlLedRpi.sh)が実行される。
![Node-RED_MQTT_pub_005.png](https://qiita-image-store.s3.amazonaws.com/0/85506/a8a9343a-861c-0a73-5cd1-8457215b3126.png)

すぐにLEDの点滅が始まる。（動画を再掲）
<blockquote class="twitter-video" lang="ja"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/RaspberryPi?src=hash">#RaspberryPi</a> <a href="https://twitter.com/hashtag/Bluemix?src=hash">#Bluemix</a> <a href="https://twitter.com/hashtag/IoT?src=hash">#IoT</a> <a href="https://twitter.com/hashtag/MQTT?src=hash">#MQTT</a> <a href="https://t.co/8yw7k1YqFA">pic.twitter.com/8yw7k1YqFA</a></p>&mdash; m (@getapojim) <a href="https://twitter.com/getapojim/status/658959181056053249">2015, 10月 27</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


<!--
#<i class="fa fa-cube" style="font-size:1em;"></i>続き
<font color=red>(2)　センサーを付けてデータを拾う　温度センサーデジタル編　（これから書く）</font>
-->

#<i class="fa fa-cube" style="font-size:1em;"></i>環境

[Raspberry Pi 2 Model B](https://www.raspberrypi.org/products/raspberry-pi-2-model-b/)
[Raspbian](https://www.raspberrypi.org/downloads/raspbian/)
[Bluemix IoT Foundation](https://internetofthings.ibmcloud.com/)
[Node-RED](http://nodered.org/)

#<i class="fa fa-book" style="font-size:1em;"></i>参考
BluemixのRaspberryPi登録レシピ
https://developer.ibm.com/recipes/tutorials/raspberry-pi-4/

BluemixのRaspberryPi登録レシピに登場するデバイス用のsampleプログラム
(Linux用のdaemonになっている)
https://github.com/ibm-messaging/iot-raspberrypi/blob/master/samples/c/

https://github.com/ibm-messaging/iot-raspberrypi/tree/master/samples/c#command-support

[コラム] Raspberry Pi 2のオンボードLEDを自由に光らせよう
http://blog.livedoor.jp/victory7com/archives/43512294.html