LoRaWANのThe Things Networkと都市OSのFIWAREでデータを連携するFIWARE IoT-Agent-LoRaWANを動かしてみた🍣
TL,DR; Too Long, Don't Read
- LoRa通信やLoRaWANを使用して都市型OSのFIWAREを経由してデータの取得やデータベースへの保存ができた
- Tutorialのサンプルがあった
- The Things Network v3に対応させた
- ASIA923に周波数帯に設定を変更させた
- スマートシティにもLoRa通信やLoRaWANが活用できそう。
- あなたのスマートシティにもどうでしょうか?
LoRaWANのThe Things Networkって何?
LoRaWANはLoRa通信を利用したネットワークです。
The Things NetworkはそのLoRaWANのグローバルなコミュニティで、オープンなクラウドIoTプラットフォームです。
- 「The Things Networkの生い立ちとTNN Japanユースケース」
- 「LoRaWAN」をみんなでシェアして使う The Things Network - Draginoダイレクトショップ
- LoRaWANゲートウェイ Dragino LPS8 を使って The Things Network(TTN)と接続する - Qiita
都市OSのFIWAREって何?
スマートシティ化に向けたオープンデータの利活用に使用されている都市OSです。
[FIWAREとは何か? 基礎からわかるスマートシティ標準のIoTプラットフォーム |ビジネス+IT[(https://www.sbbit.jp/article/cont1/35595)
世界各地の都市で導入の取り組みがなされ、日本でもいくつかの自治体が導入の取り組みを行っている
FIWAREを基盤にした都市OS活用によるスマートシティ展開|冬のデジ田甲子園|デジタル田園都市国家構想
>富山県富山市、兵庫県加古川市、愛媛県新居浜市、北海道更別村、北海道札幌市、宮城県仙台市、茨城県つくば市、東京都東村山市
活用されるデータとしては、観光IoTや防災IoTや市の設備などのオープンデータによく使われている
FIWAREを活用したスマートシティ向け共通プラットフォームの構築(高松市事例): Vol.71 No.1:データを活用した持続可能な都市経営特集 | NEC
>観光IoT, 防災IoT, オープンデータ(市設備など)
FIWARE IoT-Agent-LoRaWANを動かしてみた
全体図
- LoRaエンドノード
- LoRaゲートウェイ
- The Things Network V3 Community
- → MQTT通信でFIWAREへ
- FIWARE (IoT-Agent, Orion Context Provider, Mongo DB)
- PCからCurlでOrion Context Providerにアクセスする
tutrialStm32TTN
基本的には下記のtutorial通りに進めた。
進めていくにあたり、The Things Network V3への対応と日本で動かすにはASIA923への周波数帯の変更が必要が出てきたので補足します。
FIWARE IoT-Agent-LoRaWANをThe Things Network v3に対応させた
以下の#171のpull requestでも指摘されている通り、
The Things Network v3では MQTT出力のJSONのセンサデータの属性が message.uplink_message.frm_payload に変更されている。
(The Things Network v2では message.uplink_message.payload_raw だったようだ。)
fix #170 by chicco785 · Pull Request #171 · Atos-Research-and-Innovation/IoTagent-LoRaWAN
lib/applicationServers/ttnAppService.js の139行目辺りに message.uplink_message.frm_payload の分岐を追加する。
} else if (message.uplink_message && message.uplink_message.frm_payload) {
config.getLogger().info(context, 'debug: message.uplink_message.frm_payload');
intoTrans(localContext, this.messageHandler)(
this, deviceId,
deviceEui,
message.uplink_message.frm_payload
);
- 対応した変更をdockerで動かすためにdocker rebuildする
下記のdockerの説明通りに進めた。
IoTagent-LoRaWAN/docker at master · Atos-Research-and-Innovation/IoTagent-LoRaWAN
(folkしてrebuildしたが、ローカルのファイルを参照してrebuildできると思う。)
sudo docker build -t iot-agent .\
--build-arg GITHUB_ACCOUNT=takurx\
--build-arg GITHUB_REPOSITORY=IoTagent-LoRaWAN\
--build-arg SOURCE_BRANCH=master
LoRaエンドノードの周波数帯の設定をEU868からASIA923に変更した
STM32cubeIDEの使い方は省略しますが、
IoTagent-LoRaWAN/examples/devices/stm32
以下にtutorialのprojectがあります。
IoTagent-LoRaWAN/examples/devices/stm32 at master · Atos-Research-and-Innovation/IoTagent-LoRaWAN
このprojectをSTM32cubeIDEで読んでbuildしてB-L072Z-LRWAN1に書き込みます。
-
PredefinedされているEU868をASIA923に書き換えた。周波数帯の設定をEU868からASIA923に変更するために
- IoTagent-LoRaWAN/examples/devices/stm32/Projects/B-L072Z-LRWAN1/Applications/LoRa/End_Node/MDK-ARM/Lora.uvprojx
Lora.uvprojx, Line 338<Define>STM32L072xx,USE_B_L072Z_LRWAN1,USE_HAL_DRIVER, REGION_AS923</Define>
- IoTagent-LoRaWAN/examples/devices/stm32/Projects/B-L072Z-LRWAN1/Applications/LoRa/End_Node/SW4STM32/mlm32l07x01/.cproject
.cproject, Line 71<listOptionValue builtIn="false" value="REGION_AS923"/>
.cproject, Line 185<listOptionValue builtIn="false" value=" REGION_AS923"/>
-
(小ネタ)main.cのデータも減らしました。確認しやすくするために
- そのままだと項目が多いせいか?The Things NetworkのConsole上での認識がいまいちだった気がしたので
- IoTagent-LoRaWAN/examples/devices/stm32/Projects/B-L072Z-LRWAN1/Applications/LoRa/End_Node/LoRaWAN/App/src/main.c
/*
AppData.Buff[i++] = cchannel++;
AppData.Buff[i++] = LPP_DATATYPE_BAROMETER;
AppData.Buff[i++] = ( pressure >> 8 ) & 0xFF;
AppData.Buff[i++] = pressure & 0xFF;
*/
AppData.Buff[i++] = cchannel++;
AppData.Buff[i++] = LPP_DATATYPE_TEMPERATURE;
AppData.Buff[i++] = ( temperature >> 8 ) & 0xFF;
AppData.Buff[i++] = temperature & 0xFF;
//AppData.Buff[i++] = cchannel++;
//AppData.Buff[i++] = LPP_DATATYPE_HUMIDITY;
//AppData.Buff[i++] = humidity & 0xFF;
#if defined( REGION_US915 ) || defined ( REGION_AU915 )
/* The maximum payload size does not allow to send more data for lowest DRs */
#else
/*
AppData.Buff[i++] = cchannel++;
AppData.Buff[i++] = LPP_DATATYPE_DIGITAL_INPUT;
AppData.Buff[i++] = batteryLevel*100/254;
AppData.Buff[i++] = cchannel++;
AppData.Buff[i++] = LPP_DATATYPE_DIGITAL_OUTPUT;
AppData.Buff[i++] = AppLedStateOn;
*/
-
(小ネタ)シリアル通信でデバッグ出力を見ていると、↓のThe Things Network v3でゲートウェイの登録とLoRaエンドノードの登録ができると、JOINEDってでます
-
(小ネタ)mosquitto_subコマンドを使ってLoRaエンドノード→The Things Network v3からのMQTTの出力を確認する
↓のThe Things Network v3でMQTTの設定を使って、mosquitto_subコマンドでMQTTの出力を確認できます。
chiya@ujimatsu:~$ mosquitto_sub -h eu1.cloud.thethings.network -p 1883 -t "#" -u "test-stm32-geetsuku@ttn" -P "NNSXS.6SOVX3SACVIUJPNU4WAD672YHSLOKAV33S6LWKA.2OUFT26PMPNMFFFOJV43LGTJ34H4NBVJYA7TKII3UXRKBMKKT2FA" -d
The Things Network v3からのMQTTが出力されていたら、下記のようなJSONの応答が来ます。
Client mosq-RoWMpAsU24yGazYFzi sending CONNECT
Client mosq-RoWMpAsU24yGazYFzi received CONNACK (0)
Client mosq-RoWMpAsU24yGazYFzi sending SUBSCRIBE (Mid: 1, Topic: #, QoS: 0, Options: 0x00)
Client mosq-RoWMpAsU24yGazYFzi received SUBACK
Subscribed (mid: 1): 0
......
{"end_device_ids":{"device_id":"eui-303636327f397a07","application_ids":{"application_id":"test-stm32-geetsuku"},"dev_eui":"303636327F397A07","join_eui":"70B3D57ED000985F","dev_addr":"260B4A18"},"correlation_ids":["as:downlink:01H2MQNFADF15K0PHVW9SY0SHR","as:up:01H2NP96EJD2KG44RCRJJA5AY1","gs:conn:01H2B2AAKAXS327NWDY5YT8D10","gs:tx_ack:01H2NP96EGKA56GJXJ3FBRGDBB","gs:up:host:01H2B2AAM5H4B60XE6PK06JRCE","gs:uplink:01H2NP95SFDWHR869WC15BZ05E","ns:downlink:01H2NP966J7TA292R9T0A2B8X4","ns:transmission:01H2NP966JDBWDR5X0MPFFS5YM","ns:tx_ack:01H2NP96EH6J1DCRJ3KQYC4TWK","ns:uplink:01H2NP95SHYZV0MZZ5W2A3CRXG","rpc:/ttn.lorawan.v3.AppAs/DownlinkQueuePush:579d94f6-8b6e-4477-8ffe-91ea8ffbd82f","rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H2NP95SHXZXE2HRR95PG82X7","rpc:/ttn.lorawan.v3.GsNs/ReportTxAcknowledgment:01H2NP96EGFWWCC81F2NBV6H1R","rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01H2NP96EJ90WMQZXPP2EGKD5P","rpc:/ttn.lorawan.v3.NsGs/ScheduleDownlink:01H2NP966KH5WS8YN3WTS2K2TY"],"received_at":"2023-06-11T16:57:56.946358426Z","downlink_sent":{"session_key_id":"AYirYJ+ikw9FiXMjYlBeZQ==","f_port":1,"f_cnt":26,"confirmed":true,"priority":"HIGHEST","correlation_ids":["as:downlink:01H2MQNFADF15K0PHVW9SY0SHR","gs:conn:01H2B2AAKAXS327NWDY5YT8D10","gs:tx_ack:01H2NP96EGKA56GJXJ3FBRGDBB","gs:up:host:01H2B2AAM5H4B60XE6PK06JRCE","gs:uplink:01H2NP95SFDWHR869WC15BZ05E","ns:downlink:01H2NP966J7TA292R9T0A2B8X4","ns:transmission:01H2NP966JDBWDR5X0MPFFS5YM","ns:tx_ack:01H2NP96EH6J1DCRJ3KQYC4TWK","ns:uplink:01H2NP95SHYZV0MZZ5W2A3CRXG","rpc:/ttn.lorawan.v3.AppAs/DownlinkQueuePush:579d94f6-8b6e-4477-8ffe-91ea8ffbd82f","rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01H2NP95SHXZXE2HRR95PG82X7","rpc:/ttn.lorawan.v3.GsNs/ReportTxAcknowledgment:01H2NP96EGFWWCC81F2NBV6H1R","rpc:/ttn.lorawan.v3.NsGs/ScheduleDownlink:01H2NP966KH5WS8YN3WTS2K2TY"]}}
......
The Things Network v3でゲートウェイの登録とLoRaエンドノードの登録とMQTTの設定をした
- The Things Network v3でゲートウェイの登録とLoRaエンドノードの登録
詳しい登録方法は省略しますが、
- device_id, 例:"eui-303636327f397a07"
- host, 例:"eu1.cloud.thethings.network"
- dev_eui, 例:"303636327F397A07"
- app_eui, 例:"70B3D57ED000985F"
- application_id, 例:"test-stm32-geetsuku@ttn"
- application_key, 例:"E5DEE0E4A3FF229129686A09CDDF9BBA"
以上の値は、以降の↓のProvisioningで使います。
- The Things Network v3のMQTTの設定
The Things Network v3のConsoleのApplicationのIntegrationからMQTTを追加します。そのときの
- username, 例:"test-stm32-geetsuku@ttn"
- password, 例:"NNSXS.6SOVX3SACVIUJPNU4WAD672YHSLOKAV33S6LWKA.2OUFT26PMPNMFFFOJV43LGTJ34H4NBVJYA7TKII3UXRKBMKKT2FA"
以上の値は、以降の↓のProvisioningで使います。
dockerでFIWARE IoT-Agentをローカルで起動する
- 起動
sudo docker-compose -f examples/stm32_ttn_tutorial/docker-compose.yml up
- 停止
sudo docker-compose -f examples/stm32_ttn_tutorial/docker-compose.yml down
以降の↓のProvisioningするとデータがローカルに保存されるので必要があったら消してください。クリーンな環境でテストしたい時とか。
- データ削除
sudo docker volume rm stm32_ttn_tutorial_cratedata stm32_ttn_tutorial_mongo_data stm32_ttn_tutorial_redisdata
Provisioning, FIWARE IoT-AgentにLoRaエンドノードを登録した
- attributesの属性、cayenne形式のセンサから送られてくるデータ
- device_id, 例:"eui-303636327f397a07"
- host, 例:"eu1.cloud.thethings.network"
- username, 例:"test-stm32-geetsuku@ttn"
- password, 例:"NNSXS.6SOVX3SACVIUJPNU4WAD672YHSLOKAV33S6LWKA.2OUFT26PMPNMFFFOJV43LGTJ34H4NBVJYA7TKII3UXRKBMKKT2FA"
- dev_eui, 例:"303636327F397A07"
- app_eui, 例:"70B3D57ED000985F"
- application_id, 例:"test-stm32-geetsuku@ttn"
- application_key, 例:"E5DEE0E4A3FF229129686A09CDDF9BBA"
これらの値は↑のThe Things Network v3でのゲートウェイ、LoRaエンドノード、MQTTの個々の設定値によって変更してください。
以下はコマンドのサンプルです。
curl -X POST \
http://localhost:4061/iot/devices \
-H 'Content-Type: application/json' \
-H 'fiware-service: atosioe' \
-H 'fiware-servicepath: /lorattn' \
-d '{
"devices": [
{
"device_id": "eui-303636327f397a07",
"entity_name": "LORA-DEVICE",
"entity_type": "LoraDevice",
"timezone": "Asia/Tokyo",
"attributes": [
{
"name": "temperature_3",
"type": "Number"
}
],
"internal_attributes": {
"lorawan": {
"application_server": {
"host": "eu1.cloud.thethings.network",
"username": "test-stm32-geetsuku@ttn",
"password": "NNSXS.6SOVX3SACVIUJPNU4WAD672YHSLOKAV33S6LWKA.2OUFT26PMPNMFFFOJV43LGTJ34H4NBVJYA7TKII3UXRKBMKKT2FA",
"provider": "TTN"
},
"dev_eui": "303636327F397A07",
"app_eui": "70B3D57ED000985F",
"application_id": "test-stm32-geetsuku@ttn",
"application_key": "E5DEE0E4A3FF229129686A09CDDF9BBA"
}
}
}
]
}'
- (小ネタ)FIWARE IoT-Agentがデータを取得してMongo DBにNGSI v2形式でデータを取得できたときのdockerのデバッグ用のメッセージ
Operation Successful!! Yeahhhhhhhh!!
iotagent-lora_1 | time=2023-06-15T10:13:53.623Z | lvl=INFO | corr=ae57a28e-817f-4212-a3a1-3b4c08218e22 | trans=ae57a28e-817f-4212-a3a1-3b4c08218e22 | op=IoTAgentLoRaWAN.Agent | from=n/a | srv=n/a | subsrv=n/a | msg=Observations sent to CB successfully for device | comp=IoTAgent eui-303636327f397a07
orion_1 | time=Thursday 15 Jun 10:14:22 2023.167Z | lvl=INFO | corr=N/A | trans=N/A | from=N/A | srv=N/A | subsrv=N/A | comp=Orion | op=connectionOperations.cpp[701]:runCollectionCommand | msg=Database Operation Successful (command: { listDatabases: 1 })
orion_1 | time=Thursday 15 Jun 10:14:22 2023.168Z | lvl=INFO | corr=N/A | trans=N/A | from=N/A | srv=N/A | subsrv=N/A | comp=Orion | op=connectionOperations.cpp[94]:collectionQuery | msg=Database Operation Successful (query: {})
Getting Data, FIWAREからLoRaエンドノードのセンサの値を取得する
curl -X GET \
http://localhost:1026/v2/entities \
-H 'fiware-service: atosioe' \
-H 'fiware-servicepath: /lorattn'
- 応答例
chiya@ujimatsu:~/LoRaWorks/IoTagent-LoRaWAN/docker$ curl -X GET \
> http://localhost:1026/v2/entities \
> -H 'fiware-service: atosioe' \
> -H 'fiware-servicepath: /lorattn'
[{"id":"LORA-DEVICE","type":"LoraDevice","TimeInstant":{"type":"DateTime","value":"2023-06-15T10:13:53.00Z","metadata":{}},"temperature_3":{"type":"Number","value":59.7,"metadata":{"TimeInstant":{"type":"DateTime","value":"2023-06-15T10:13:53.612Z"}}}}]
まとめ
- LoRa通信やLoRaWANを使用して都市OSのFIWAREを経由してデータの取得やデータベースへの保存ができた
- スマートシティにもLoRa通信やLoRaWANが活用できそう
- あなたのスマートシティにもどうでしょうか?
- 同じ変更でUS915やAU915にも使えそう
- つくば市や他の市町村の導入中のスマートシティのFIWAREでもLoRa通信を試せたらおもしろそうだよね
課題
- Tutorialのupdateが止まってそう?
- Tutorialはデータの入力形式がcayenne形式しか対応していない
- lib/applicationServers/ttnAppService.jsやlib/dataModels/cayenneLpp.jsを書き換えたら他の形式にも対応できそう
クレジット
本調査は筑波大学のシステム情報系の亀田研究室の非常勤研究員として調査したものです。
また先日の「第6回 The Things Network(TTN)勉強会」&「第4回TTNイニシエーター会議」 - connpassにて飛び込みで同内容でライトニングトークさせていただきました。
2019年9月の「「第2回 The Things Network(TTN)勉強会」 @柏の葉」 - connpassに参加しLoRa通信やThe Things Networkに興味を持ち、いろいろあって先生に相談したところLoRa関連の仕事があるということで動かしてみて、こうして公開の機会をいただきありがたいことです。
その他、小ネタ
FIWARE IoT-Agent-LoRaWANが受信したデータがCayenne形式じゃなかった場合のdockerのデバッグ用のエラーメッセージ
msg=Error decoding CaynneLPP message:TypeError......
iotagent-lora_1 | time=2023-06-11T16:54:36.705Z | lvl=ERROR | corr=7a07cc86-f982-4b9e-85b8-6fcb86cb18c3 | trans=7a07cc86-f982-4b9e-85b8-6fcb86cb18c3 | op=IoTAgentLoRaWAN.CayenneLpp | from=n/a | srv=n/a | subsrv=n/a | msg=Error decoding CaynneLPP message:TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Object | comp=IoTAgent
iotagent-lora_1 | time=2023-06-11T16:54:36.705Z | lvl=ERROR | corr=7a07cc86-f982-4b9e-85b8-6fcb86cb18c3 | trans=7a07cc86-f982-4b9e-85b8-6fcb86cb18c3 | op=IoTAgentLoRaWAN.Agent | from=n/a | srv=n/a | subsrv=n/a | msg=Could not cast message to NGSI | comp=IoTAgent
Cayenne LPP形式
たしかにデータフォーマットとしてはバイナリで短い
- Cayenne Low Power Payload | myDevices Documentation
- CayenneLPP( Cayenne Low Power Payload) について調べてみた - Qiita
- Cayenne LPP Decoder - End Devices (Nodes) / Pycom - The Things Network
FIWARE-Bigbang
FIWAREの本体。これにIoT-AgentやMongo DBを追加して動かす。
そのままデプロイしようとすると各サービスごと(Orion, IoT-Agent, MongoDBなど)にサブドメインが必要。
Big-BangからOrionやDracoなど星座の名前が付いたりしている。
FIWARE-Draco, Apache NiFi
Apache NiFiはNode-REDやScratchやM5Stack UIFlowのようなビジュアルプログラミングができるソフトウェア。
Apache NiFiをFIWAREに取り込んだスタックをFIWARE-Dracoと名前が付いている。
取り込んだNGSIのデータを加工するのには便利そう。
こちらからThe Things Networkからのデータの取り込みができるか考えたが、IoT-Agentの方が簡単そうだったのでやめた。
FIWARE IoT Agent UltraLight 2.0, IoT-over-MQTT
おそらくこの辺のFIWARE IoT-AgentのMQTT通信でも同じことができるのではないかと思う。
- FIWARE/tutorials.IoT-Agent: FIWARE 202: Provisioning the Ultralight IoT Agent
- FIWARE/tutorials.IoT-over-MQTT: FIWARE 203: Provisioning Ultralight with an alternative transport: IoT over MQTT
DRAGINO LHT65N
最初はLoRaエンドノードがこれでいけるかと考えていたのだが、これのThe Things Networkへのデータのupload形式は独自フォーマットでcayenne形式ではない……。
なので、B-L072Z-LRWAN1に切り替えた。
ChripStack
The Things Networkと同様のオープンソースのLoRaWANスタック
FIWARE IoT-Agent-LoRaWANはこちらにも対応してる
ChirpStack open-source LoRaWAN Network Server
LoRa通信を使用した衛星通信が熱いぜ
Lacuna spaceやFOSSA SystemsのLoRa通信の衛星が打ち上がってきたのでめちゃくちゃおもしろくなってきたと思います。
- Lacuna – Low-cost, simple and reliable global connections to sensors and mobile equipment.
- FOSSA Systems – Global Cost-Effective IoT Connectivity
LoRa衛星のオープンソースの地上局のプロジェクトのTinyGSのプロジェクトがおもしろそう。似たプロジェクトのSatNOGSの地上局と組み合わせている人もたまに見る。
スマートシティ、略してスシ🍣
スマートシティ略して「スシ」
市民起点のスマートシティを語る会 #001 FIWARE Global Summit2023報告! | Peatix
スシ🍣!なぜこんなにも美味いんだ!