ふとGo言語のMQTTパッケージを試してみた


# はじめに

簡単に今回の経緯。
Go言語の楽しさに目覚めるもIoTへの憧れも捨てきれないので、とりあえずパッケージを探してみました。

***好きです。Go言語。***

# MQTTとは

一部では割と有名なTCP/IPプロトコルの一種です。
よくZigbeeとかと一緒に使われることが多い印象。
軽量かつ省電力なのでIoTと一緒に取り上げられることが多いです。
セキュリティ的に問題が。。。とかまれに耳にしますが、自分はPICで室温とか酸素濃度とか明るさとかを何かしらしてコネコネしたいので、あんまり気にしないことにします。

[ここが参考になります](https://qiita.com/marnie_ms4/items/ac14415e8ff6e90fbf64 "MQTTの基礎知識")

# 使用したMQTTのパッケージ

[github.com/jeffallen/mqtt](https://github.com/jeffallen/mqtt)

いろいろ見た中で一番実装がシンプルでした。
簡単なSampleもわかりやすく配置してくれていたので、仕事終わりにサクッと試すにはぴったりだと感じました。

## 実演
サクッと試したかったのでターミナルを９窓立ち上げて使ってみました。
ちなみにサンプルコードはHOSTを指定することもできますが、何も指定しなければLocalhost接続になるのでこのまま進めます。

<img width="1440" alt="スクリーンショット 2019-01-17 0.38.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/dd0fab7d-fdb5-b19d-287a-62a9f7b1deba.png">

(スマホだと画像が見辛い！)


まず真ん中の窓でブローカーと呼ばれる中継サーバを立ち上げます。

```

$ go run ./mqttsrv/main.go
```


<img width="493" alt="スクリーンショット 2019-01-17 1.35.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/1e7ba3a0-0bc6-c021-ac50-63d03621828f.png">

このブローカーに対しサブスクライバーが監視をし続け特定のトピックが更新されればそれを受信するような流れです。


次に、ブローカーを立ち上げている窓以外の下２列でサブスクライブします。
左真ん中から、反時計回りに以下のコマンドを打ちます。

```

$ go run ./sub/main.go "/house/room/+/brightness"  <- + は部分一致（+はワイルドカード）
$ go run ./sub/main.go "/house/room/light1/brightness"
$ go run ./sub/main.go "/house/room/light2/brightness"
$ go run ./sub/main.go "/house/room/light3/brightness"
$ go run ./sub/main.go "/house/room/#"  <- # は前方一致（#はワイルドカード）
```

<img width="1418" alt="スクリーンショット 2019-01-17 1.41.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/f2382b16-378e-34c4-786f-85fb4db950f4.png">

次にパブリッシュして各センサーノード（のふりをさせたコンソール）からブローカーに向けて値を発行してみます。

```
go run ./pub/main.go "/house/room/light1/brightness" 555
go run ./pub/main.go "/house/room/light1/temp" 28
go run ./pub/main.go "/house/room/light2/brightness" 777
go run ./pub/main.go "/house/room/light3/brightness" 999
```


`/house/room/`の中にある`light*`から何かしらの値が飛んできているようなイメージです。
こうすることで受信側では

- フルパスを指定したサブスクライバーはそれぞれ指定した値のみを
- 部分一致で監視させたサブスクライバーは全てのbrightnessを
- 前方一致で監視させたサブスクライバーは全ての値を

それぞれ受信できているはずです。


では順番にみていきます。

↓部分一致:light1~3のbrightnessの値を正しく受信しています。
<img width="481" alt="スクリーンショット 2019-01-17 0.58.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/249f7317-1293-cda0-0bcc-f075c3b3ae93.png">

↓フルパス:指定したlight1の値を正しく受信しています。
<img width="481" alt="スクリーンショット 2019-01-17 0.59.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/b35741db-f388-6007-bacb-68f080bb26f0.png">

↓フルパス:指定したlight2の値を正しく受信しています。
<img width="482" alt="スクリーンショット 2019-01-17 0.59.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/2e1e35c1-8957-897f-d727-38415f5dcb9f.png">

↓フルパス:指定したlight3の値を正しく受信しています。
<img width="482" alt="スクリーンショット 2019-01-17 1.00.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/224cbe37-ccbf-e35d-4aba-42f7293e4200.png">

↓前方一致:全ての値を取得しています。
<img width="482" alt="スクリーンショット 2019-01-17 0.58.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/179198/113307aa-7186-0bd9-f650-4819ee09be94.png">

思った通りになりました。
これで任意のセンサーノードの値を取ることができますね。
送信側が主導権を握っているので使うところは選びますが、定期的な値を必要とする定点観測などにはあっているんじゃないかなと思います。

# 結論

ここまで完了するのに

- 調査：１時間
- 実験：0.5時間
- Qiita執筆：1.5時間

くらいの時間配分でした。（筆が遅い）

導入のハードルが低いので「RaspberryPiZeroでお家IoT」とかにはいいんじゃないでしょうか？
自分は社内の酸素濃度と業務効率との相関図とか作りたいなと思っています。

とにかくいろんな人にGo言語を使ってもらいたい。
Goのインストールは[ここ](https://golang.org/dl/)からできます。RaspberryPiにGoをインストールする場合は「ARMv6アーキテクチャ」を選択してください。


[github.com/jeffallen/mqtt](https://github.com/jeffallen/mqtt)
上記のパッケージの中の動作には今回は触れませんでしたが、ソースも簡潔に書かれているので読んでみても理解が深まるかもしれません。



# 追記

動画でやるべきでした。