日時: | 2016-04-09 |
---|---|
作: | 時雨堂 |
バージョン: | 5.1.1 |
url: | https://shiguredo.jp/ |
Contents
いろいろな場所で説明されてるので省略します
時雨堂では無料で使える MQTT as a Service 提供中です。
時雨堂では商用の MQTT ブローカーを販売中です。
- 時雨堂が開発している MQTT ゲートウェイ Fuji の開発ログです
- 興味がある方は contact at shiguredo.jp まで
この定義は時雨堂独自の解釈です
センサーからのデータを受信して MQTT ブローカーに送る仕組みです。
構成:
<センサー> -> ZigBee -> +------------+ <センサー> -> EnOcean -> シリアル -> |ゲートウェイ| -> MQTT -> <MQTT ブローカー> <センサー> -> USB -> +------------+
MQTT ゲートウェイは送受信機にインストールして使用することを想定しています。
URL: | http://fuji.shiguredo.jp |
---|
MQTT サービス、MQTT ブローカーと開発をしてきましたが、センサーなどのデータを気軽に MQTT ブローカーへ送る仕組みの決定打がなく、 MQTT を使ったサービスを動かすまでの距離を感じていました。
そこで今まで培った MQTT のノウハウを凝縮したセンサー送受信機向けのシンプルな MQTT ゲートウェイを開発し、オープンソースで公開とすることで気軽に使って貰えないだろうかと考えました。
リリース: | 2015-04-22 |
---|---|
ライセンス: | Apache License, Version 2.0 |
著者: | Shiguredo Inc. |
コピーライト: | Shiguredo Inc. |
GitHub: | https://github.com/shiguredo/fuji |
ソースコードから自分でバイナリを作成することも可能です
ダウンロード: | https://github.com/shiguredo/fuji/releases |
---|
Edison と Raspberry Pi に対してはパッケージを提供します。
- センサーデータを生データのまま MQTT ブローカーへ送信する
- センサーデータの処理は全て MQTT ブローカーの先で行う思想
- ゲートウェイのカスタマイズをなるべく減らす
- センサーからのデータはシリアルポート経由であれば TOML ファイルに設定するだけで MQTT ブローカーへ送信可能
- MQTT ブローカーへの接続に対して細かい設定が可能
- MQTT ブローカーを複数設定できる
- MQTT ブローカーの冗長構成に対応
- MQTT ブローカーへ送信するデータは QoS の設定や Retain を設定できる
- MQTT ブローカーからメッセージを受信し、センサーへ送ることが出来る
- アプリからセンサーへメッセージを送ることが出来る
- 送受信機の状態を $SYS/gateway で取得する事ができる
時雨堂 MQTT ゲートウェイの設定ファイル例です。
この設定ファイルは検討中のものを含みます
- バイナリを指定する場合は \x00\x01\x02 のように記述します
- payload = \x00\x01\x02
- name
- topic に使用できる文字は全て使用可能
[gateway]
name = "fuji"
- ブローカーは複数指定できます
- ブローカーは冗長構成に対応します
- 優先順位は上からの順番となります
- 個々のブローカーに対して無限に再接続を行います
- 切り替え
- ブローカーごとに、パケットのリトライ回数とリトライインターバルを指定出来ます
- 指定回数リトライを行っても接続ができない場合、送信先を次のブローカーに切り替えます
- リトライ回数の最大値の設定を可能にします
- リトライ間隔の最大値の設定を可能にします
- 次の切り替え先ブローカーが存在しない場合はパケットを破棄します
- will message をブローカー単位で指定出来る
- will message を定義することで有効になる
- topic は固定で <Gateway-Name>/will に送られる
- 未実装
- will_topic でトピックを設定可能にする
- subscribe
- デバイスに対してメッセージを配信できるようになる
- topic は固定で <Gateway-Name>/<Device-Name> に送られます
- 切り戻し
- 未実装
- 一定時間過ぎた後、優先順位が高い方に接続を切り戻します
[[broker."sango"]]
host = "192.0.2.10"
port = 1883
username = "sayo"
password = "123"
topic_prefix = "[email protected]"
retry_count = 7
# 秒
retry_interval = 3
# will の動作は固定する
will_message = "hello world"
[[broker."sango"]]
host = "192.0.2.11"
port = 1883
username = "sayo"
password = "123"
topic_prefix = "[email protected]"
retry_count = 7
# 秒
retry_interval = 3
[[broker."akane"]]
host = "192.0.2.20"
port = 8883
tls = true
# PEM 形式
cacert = "/path/to/cacert"
username = "sayo"
password = "456"
シリアルポートからの通信を前提として、デバイス単位で MQTT ブローカーを指定出来ます
TOML ファイルに設定するだけで対応が可能です。
- broker
- [[broker.""]] で指定しているものが無ければエラー
- qos
- 0,1,2 で対応 SUBSCRIBE したタイミングで 0x80 が帰ってきたらエラーログを出力する
- retain
- true / false でデフォルトは false
- type
- seiral を指定します
- subscribe
- true / false でデフォルトは false
- baud
- 必要な値を指定
- size
- 取得するデータサイズ
[device."spam"]
type = "serial"
broker = "sango"
qos = 0
retain = true
subscribe = true
serial = "/dev/tty.ble"
baud = 9600
size = 4
[device."beacon"]
type = "serial"
broker = "sango"
qos = 2
serial = "/dev/tty.enocean"
baud = 115200
size = 8
検討中
EnOcean は USB の無線受信機があり、さらにシリアル通信で気軽に扱うことが出来ます。
Fuji ではさらに EnOcean パケットの CRC チェックを行う事により、より安全に MQTT ブローカーにぱけっとを送れるような仕組みを追加する予定です。
これ以外にも EnOcean との相性をよりよくしていく方向で進めています。
[device."yaki"]
type = "EnOcean"
broker = "spam"
qos = 2
retain = true
serial = "/dev/tty.enocean"
crc8 = true
テスト用ダミーデバイスを作る事ができます。
このダミーデバイスは名前がかぶらない限り、好きなだけ増やすことが可能です。
[device."dora"]
type = "dummy"
broker = "spam"
qos = 2
retain = true
interval = 10
payload = "Hello world."
- 送受信機の状態を定期的に MQTT ブローカーに投げることができます
- interval を 0 に設定した場合はサーバからの PUBLISH を契機として状態を PUBLISH します
- $SYS/gateway/<Gateway-Name>/cpu/cpu_times/user
- $SYS/gateway/<Gateway-Name>/cpu/cpu_times/system
- $SYS/gateway/<Gateway-Name>/cpu/cpu_times/idle
- $SYS/gateway/<Gateway-Name>/memory/virtual_memory/total
- $SYS/gateway/<Gateway-Name>/memory/virtual_memory/available
- $SYS/gateway/<Gateway-Name>/ip_address/interface/all
- $SYS/gateway/<Gateway-Name>/ip_address/interface/en0
[status]
broker = "sango"
# qos は 0 固定
interval = 3600
[status."cpu"]
cpu_times = [ "user", "system", "idle", "nice", "iowait", "irq", "softirq", "guest"]
[status."memory"]
# interval を上書きできる
interval = 200
virtual_memory = [ "total", "available", "percent", "used", "free" ]
[status."ip_address"]
interface = ["eth0"]
[status."process"]
# https://github.com/fukata/golang-stats-api-handler からそのまま
go = [ "version", "os", "arch", "gc_num", "gc_last", "gc_next", "cgo_call_num", "gomaxprocs", "goroutine_num" ]
memory = [ "lookups", "sys", "total_alloc", "alloc", "mallocs", "frees" ]
heap = [ "alloc", "sys", "idle", "inuse", "released", "objects" ]
MQTT Publish Topic は 自動的に 生成されます。ゲートウェイ名とデバイス名から自動で生成されます。
たとえばゲートウェイ名が spam で、デバイス名が egg だとします。
その場合の Topic は spam/egg/publish です。 payload はセンサーがから送られてきた値そのままが送られます。
Topic 固定:
<Gateway-Name>/<Device-Name>/publish
データ送信トピックは基本的に固定しますが、プレフィックスを付けられる仕組みを考えています。
topic_prefix 例
[[broker."sango"]]
topic_prefix = "sayo@github"
topic_prefix 適用後の Topic:
sayo@github/<Gateway-Name>/<Device-Name>/publish
MQTT ブローカーはマルチテナントでの使用を考えられることが多いと考えられます。さらにパーミッションは topic ベースがほとんどではないかと考え、この機能を用意しました。
MQTT Subscribe Topic は 自動的に 生成されます。Gateway-Name や Device-Name や topic_prefix については publish と同一なので省略します。
Topic 固定:
<Gateway-Name>/<Device-Name>/subscribe
subscribe を true にするとデバイスは <Gateway-Name>/<Device-Name>/subscribe に対して SUBSCRIBE を行います。
[device."spam"]
type = "serial"
broker = "sango"
qos = 0
retain = true
subscribe = true
Broker を経由して <Gateway-Name>/<Device-Name>/subscribe にメッセージを送ると MQTT-GW は指定したデバイスに対して受け取った Payload を書き込みます。
MQTT Payload はセンサーから受信した値そのものを使用します。
そのため何かしら処理を MQTT ブローカーの先で行う必要があります。
- シリアルから受け取ったバイナリそのままを MQTT の PUBLISH の Payload へ入れて転送する
- [x] Model B+ | Raspberry Pi
- 動作確認済み
- [x] Raspberry Pi 2 Model B | Raspberry Pi
- 動作確認済み
- [x] Armadillo-IoT | 組み込みLinuxのArmadilloサイト
- 動作確認済み
- [x] インテル® Edison モジュール
- 動作確認済み
- [x] OpenBlocks IoT BX1 - OpenBlocks
- 動作確認済み
- [x] GX110 | 概要 | サン電子
- 動作確認済み
未実装
MQTT ブローカーに接続出来ない場合ローカルのファイルに書き出します。
ファイル最大サイズや、ログローテーションサイズなどが指定できる予定です。
また、バッファリングしたデータを送信する場合は通常のトピックの後ろに buffering などの topic を設定して送信することができるようになる。
1.1.0 で実装予定
Fuji は HTTP リクエストを代理で送信してくれる機能を持っています。
決められたTopic に対して、決められた JSON フォーマットで HTTP リクエスト要求を送ることが出来ます。 また、その HTTP リクエストの戻り値を SUBSCRIBE することで受け取ることもできます。
HTTP リクエスト依頼用の JSON
{
"id": "<UUID>",
"url": "http://127.0.0.1:5000/spam",
"method": "POST",
"body": {"msg": "spam"}
}
- body は JSON である必要があります
- response を false にすると戻り値が返ってきません
- method はデフォルトが "POST" です
- body はデフォルトが空です
- headers が必要?
{
"id": "<UUID>",
"status": 200,
"body": {"result": "bacon"}
}
この JSON を <Gateway-Name>/http/request に対して投げます。 Fuji は送られてきた JSON を使って HTTP を指定された URL に送ります。 もし JSON では無い場合は 502 を返します。
Fuji に対して HTTP リクエストの依頼を出すための Topic:
<Gateway-Name>/http/request
Fuji が MQTT Broker にたいして SUBSCRIBE する Topic:
<Gateway-Name>/http/request
Fuji が HTTP リクエストの戻り値を MQTT Broker に PUBLISH する Topic:
// id を設定して送ってくる <Gateway-Name>/http/response/<リクエストに含まれる id>
[http]
enabled = true
MQTT For Sensor Networks (MQTT-SN)
MQTT の派生で MQTT-SN というセンサーネットワーク向けのプロトコルも定義されています。
このプロトコルは UDP/NoIP での使用が想定されています。
基本的には MQTT-SN -> MQTT-SN Gateway -> MQTT という流れになります。
URL: | http://git.eclipse.org/c/paho.incubator/smidge.git/ |
---|
このライブラリに貢献しつつ時雨堂なりの MQTT-SN の使い方を提案していきます。
- MQTT-SN を MQTT に変換して送る
MQTT-SN は Gateway の先が対応している必要があるため、何かしらの仕組みが必要です。
リリース: | 未定 |
---|
MQTT-SN 対応
- [ ] MQTT-SN 1.2 対応
- Golang 版 MQTT-SN ライブラリへの貢献、または公開を含む
- APL2.0 で公開予定
- [ ] MQTT-SN over BLE 対応
- [ ] MQTT-SN over ZigBee 対応
- [ ] MQTT-SN over ZigBee on Arduino サンプル
- Arduino によるサンプルコードを用意する
- [ ] 英語ドキュメント
- BUILD.rst の英語化
- [ ] type = EnOcean 対応
- [ ] テスト自動化
- ブローカー冗長構成切り替え
- リトライ回数
- リトライ間隔
- 複数ブローカー
- will
- retain
- [ ] HTTP リクエスト機能
リリース: | 2016-02-29 |
---|
- Golang 1.6 を使用する
リリース: | 2016-02-15 |
---|
安定化と仕様固定
- [x] Golang 1.5.3 を使用する
- [x] クライアント認証
- client_cert/client_key で証明書を設定できるようにする
- [x] 設定ファイルを TOML に変更する
- 下位互換なし
- [x] デバイスの種類をセクションから type に変更する
- [device "spam/serial"] は [device."spam"] と type = serial に変更する
- [x] publish 時の topic 変更
- 下位互換なし
- <Gateway-Name>/<Device-Name>/publish に変更する
- [x] subscribe 時の topic 変更
- 下位互換なし
- <Gateway-Name>/<Device-Name>/subscribe に変更する
- [x] will_topic の設定
- [x] [status."ip_address"] にて IP アドレスの配信を追加
リリース: | 2015-10-08 |
---|
- [x] Paho ライブラリのアップデート
- [x] gopsutil ライブラリのアップデート
- [x] Golang 1.5.1 対応
OSS にて公開
サポートとカスタマイズ受付開始
リリース: | 2015-04-22 |
---|
- [x] MQTT 3.1.1 対応
- Paho Golang への貢献を含む
- [x] MQTT over TLS 対応
- [x] 送受信機情報の取得
- gopsutil を使用する
- CPU とメモリを取得可能
- インターバルを指定可能
- [x] will メッセージの対応
- will_message = ""
- topic_prefix にも対応
- <Gateway-Name>/will に送られる
- [x] Retain の対応
- retain = true
- [x] バイナリメッセージ
- \x00\x12 を指定することでバイナリで送信が可能になる
- [x] Armadillo-IoT での動作検証
- 3G 回線での MQTT over TLS の検証
- [x] インテル Edison モジュールでの動作検証
- センサー類は確認せず、起動のみ
- [x] 無限リトライの対応
- サーバが応答しなくなった、または接続が切れた場合は無限に再接続を行う
- [x] Subscribe 機能
- subscribe = true
- デバイスに対してメッセージを送る
- <Gateway-Name>/<Device-Name>
- [x] Armadillo-IoT 向けバイナリファイルの提供
- ARM5 向け
- [x] Model B+ | Raspberry Pi 向けパッケージファイルの提供
- Raspbian 向け
- ARM6 向け
- [x] インテル Edison 向けパッケージファイルの提供
- Yocto Linux 向け
- [x] パケットリトライ
- 接続が失敗した場合一定回数を試みる
- [x] 冗長構成時の切り替え
- 一定回数のリトライを試した場合、他のブローカーへ接続を試みる
- [device "sango/1"] と [device "sango/2"]
- [x] 複数ブローカーへの対応
- それぞれのブローカーに対して接続を行う
- [device "sango/1"] と [device "akane/1"]
- [x] 日本語ドキュメント
リリース: | 2015-02-13 |
---|
社内リリース
- [x] シリアルポート経由デバイス
- EnOcean を使って実際にセンサーデータを取得
- [x] ダミーデバイス
- [x] MQTT 3.1 対応
- Paho Golang が 3.1.1 未対応のため
- [x] MQTT ブローカー対応
- シングルのみ
- [x] 日本語ドキュメント
- [x] topic_prefix への対応
- [x] dpkg install - Raspbian への対応
- [x] Raspberry Pi での動作検証
- [x] Raspberry Pi 向けのパッケージファイルの提供
- [ ] セッション対応
- [ ] Web 管理画面
- [ ] 切り戻し
- [ ] バッファリング
- 接続が失敗した場合、データをローカルファイルに書き出す
- 接続が成功した際、通常のデータとともにバッファリングデータも送信する
年間契約での提供をです。基本的にはお問い合わせベースです。
気軽に契約できるように最小コストにしています
年間契約: | 60 時間/年で 60 万円/年 |
---|---|
問い合わせ: | 平日 10:00-17:00 専用の E メールアドレスから |
- バグの優先的修正
- MQTT ゲートウェイ Fuji に関する技術的問い合わせ
開発費用: | 要件次第 |
---|---|
メンテナンス費用(OSS): | 無償 |
メンテナンス費用(非OSS): | 開発費用の 50% / 年 |
カスタマイズ内容がお客様が OSS で公開してもよいと判断され、さらに時雨堂が公開するメリットを感じた場合はメンテナンス費用を無償とします。
時雨堂では一番簡単に始められるセンサーとして EnOcean をお薦めしています。
EnOcean はエナジーハーベストという屋内の微弱な光でも充電することができる仕組みがそろっています。 つまり電池が不要で動くセンサーです。そのため屋内に置いて試すセンサーとしてはお薦めです。
使用する電波帯域が 928 MHz であり、Wifi や ZigBee や BLE が使用する 2.4 GHZ ではないため電波干渉が起こりにくいです。
時雨堂の MQTT as a Service である sango と MQTT Gateway Fuji と EnOcean のセンサーと受信機さえ用意できれば、すぐにセンサーデータを MQTT 経由で配信できます。
後で書く
BLE は接続が不安定で、古い端末での動作しない事から、一度開発休止とすることにしました。 ただし、実際に動作する実装を用意はできますので、興味がある方はご連絡ください。
- serial 経由ではなく直接 Bluetooth と設定できるようにする
- これにより Bluetooth と直接通信を行えるようになる
- https://github.com/paypal/gatt
- 設定ファイルにいくつか設定をする必要あり
- 使用するライブラリが Linux カーネル 3.14 以降でしか使えないことがわかり、一端 3.14 以降への対応とする
- Edison は 2015-08 現在カーネルが 3.10 のため使用不可能
[device."beacon"]
type = "BLE"
broker = "sango"
qos = 1
# または UUID形式 900d4ff61c61445d8c20776359858f4f
peripheral_id = "E7:6F:8B:B6:6D:33"
service_uuid = "713d0000503e4c75ba943148f18d941e"
characteristic_uuid = "713d0003503e4c75ba943148f18d941e"
- 再開に向けて
- Edison の Kernel が 3.1.4 以上になったタイミングで再検討する
ZigBee も 2.4G 帯域を使用するため、Wifi が多いところで不安定な可能性があると判断したため、一度保留としました。
[device."yaki"]
type = "ZigBee"
broker = "spam"
qos = 2
retain = true
serial = "/dev/tty.zigbee"