さくらインターネットが提供する IoT プラットフォームサービス 「sakura.io」を利用して、IoT デバイスから温湿度情報を取得し、FIWARE Orion のエンティティ情報を更新する「デジタルツイン・システム」を構築する方法を紹介します。
sakura.io と FIWARE システムの連携には、Custom IoT Agent for skaura.io を使用します。これは、sakura.io WebSocket API と NGSI の間をブリッジする、Generic Enabler です。UltraLight ベースのメッセージを、sakura.io channels にラッピングし、WebSocket を使用して、両システム間で交換します。
前提条件
次の環境が必要となります。
- Raspberry Pi
- sakura.io モジュール (LTE)
- sakura.io HAT for Raspberry Pi
- 環境センサ Enviro for Raspberry Pi (Pimoroni)
- サーバ環境
- docker, git, curl, make コマンド等
Raspberry Pi の種類は、Raspberry Pi WH, 3, 4 等です。sakura.io モジュールと sakura.io HAT for Raspberry Pi は、秋月電子通商や Amazon.co.jp 等から購入できるようです。環境センサの Enviro は、発売元の Pimoroni から購入するか、国内では秋月電子通商、スイッチサイエンス等から購入できるようです。
ソースコード
使用するソースコードは、Github の https://github.com/lets-fiware/lets-fiware.tutorials から入手できます。git コマンドで、リポジトリをクローンして、”sakuraio” ディレクトリに移動してください。
git clone https://github.com/lets-fiware/lets-fiware.tutorials.git
cd ./sakuraio
- IoT デバイス関連のソースコード: ./sakuraio/iot-devcie-ultralight
- サーバ関連のソースコード: ./sakuraio/iotagent-sakuraio
Custom IoT Agent for sakura.io のソースコードは、https://github.com/lets-fiware/custom-iotagent-sakuraio から入手できます。
システム構成
センサ・データを FIWARE Orion に送信するため、sakura.io が提供する通信モジュール、通信環境、連携処理を利用します。システムは、通信モジュールを搭載した IoT デバイス、クラウドにある sakura.io プラットフォーム、および、FIWARE プラットフォームで構成されます。FIWARE プラットフォームには、sakura.io から Orion へのデータ送信を仲介する Custom IoT Agent for sakura.io があります。
FIWARE IoT Device の作成
ハードウェア
FIWARE IoT Device には、Raspberry Pi を使用します。これに、sakura.io モジュール (LTE), sakura.io HAT for Raspberry Pi および、環境センサ Enviro for Raspberry Pi を接続します。以下の写真は これら部品のRaspberry Pi 4 への搭載例です。
ソフトウェア
Python で記述されたプログラムで、一定間隔でセンサから温湿度、気圧の値を取得し、通信モジュールを制御して、UltraLight 形式のデータを sakura.io プラットフォームへ送信します。環境センサおよび通信モジュールの制御には、I2C インタフェースを使用します。ソースコードは、クローンしたリポジトリの “./sakuraio/iot-devcie-ultralight” にあり、ファイル名は、”sakuraio-i2c.py” です。
プログラム全体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys import signal import math import time import sakuraio from sakuraio.hardware.rpi import SakuraIOSMBus from bme280 import BME280 try: from smbus2 import SMBus except ImportError: from smbus import SMBus wait = int(os.environ.get('INTERVAL', '5')); key = os.environ.get('IOTA_KEY', '1234'); def handler(signum, frame): sys.exit(0) def main(): signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGINT, handler) bus = SMBus(1) bme280 = BME280(i2c_dev=bus) sakuraio = SakuraIOSMBus() try: while (sakuraio.get_connection_status() and 0x80) == 0 : time.sleep(1) print("Connected") while True: temperature = bme280.get_temperature() pressure = bme280.get_pressure() humidity = bme280.get_humidity() measures = 'A{}?t|{:05.2f}|h|{:05.2f}|p|{:05.2f}A'.format(key, temperature, humidity, pressure) print(measures) for i in range(math.ceil(len(measures) / 8)): sakuraio.enqueue_tx(i, measures[i * 8:i * 8 + 8]) sakuraio.send() print("Send Data") time.sleep(wait) except Exception as e: print(e) if __name__ == '__main__': main() |
プログラムの実行環境
OS 環境
プログラムは、Raspberry Pi OS または Ubuntu 18.04.4 LTS で実行できます。動作確認した環境は以下の通りです。また、sakura.io モジュールと環境センサの制御に I2C インタフェースを使用しますので、インタフェースを有効化してください。
Raspberry Pi OS (32bit)
1 2 3 4 5 6 7 8 9 |
$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 10 (buster) Release: 10 Codename: buster $ uname -a Linux pi 4.19.118-v7+ #1311 SMP Mon Apr 27 14:21:24 BST 2020 armv7l GNU/Linux |
Ubuntu 18.04.4 LTS (64bit)
1 2 3 4 5 6 7 8 9 |
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.4 LTS Release: 18.04 Codename: bionic $ uname -a Linux pi 5.3.0-1028-raspi2 #30~18.04.2-Ubuntu SMP Fri Jun 19 05:12:46 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux |
OS 上で実行
プログラムを OS 上でダイレクトに実行する場合、Python ライブラリをインストールします。
1 2 3 |
sudo apt update sudo apt -y install python3 python3-pip python3-smbus sudo pip3 install requests pimoroni-bme280 sakuraio |
関連するライブラリをインストール後に、以下のコマンドでプログラムを起動できます。
sudo python3 sakuraio-i2c.py
Docker コンテナで実行
Docker コンテナ内でプログラムを実行することもできます。コンテナ・イメージの作成は、”make build” で、実行は、”make run” です。詳細は、”./sakuraio/iot-devcie” にある、Dokcerfile と Makefile を参照ください。
コマンド | 説明 |
make build | コンテナ・イメージを作成 |
make run | コンテナを起動 |
make stop | コンテナを提示 |
make rm | コンテナを削除 |
make logs | コンテナのログを表示 |
sakura.io 連携設定
WebSocket 連携サービスの設定
sakura.io のコントロールパネルにログインして、連携サービスの設定を行います。使用する連携サービス名は WebSocket です。任意の名前で WebSocket を作成すると、WebSocket の URL が生成されます。この値を Custom Iot Agent for sakura.io の環境設定で使用します。
サーバ環境の作成
FIWARE システムは、sakura.io からデータ取得に連携サービスの WebSocket 連携サービスを使用します。WebSocket とは、RFC 6455 で定義された通信プロトコルで、HTTP を使用して双方向通信を行うことができます。Custom IoT Agent for sakura.io が WebSocket クライアントとなり、WebSocket サーバの sakura.io にコネクションを張ることで、センサ・データを sakura.ioから受信します。
サーバでは次の3つのコンポーネントを実行します。
- Orion Context Broker : コンテキスト管理
- MongoDB: Orion のバックエンド DB
- Custom IoT Agent for sakura.io: WebSocket クライアントとして動作。sakura.io からデータを受信し、Orion のエンティティを更新
Docker 環境
docker-compose ファイル
Orion, MongoDB, NGSI Adapter for sakura.io は、Docker コンテナを利用して、サーバ上にデプロイします。クローンしたリポジトリの “./sakuraio/ngsi-adapter-websocket” に、docker-compose.yml ファイルがあります。SAKURA_IO_WEBSOCKET には、sakura.io 連携設定で生成された WebSocket の URL を設定してください。
環境変数 | 設定値 |
IOTA_WEBSOCKET | WebSocket サーバの URL |
Docker コンテナの起動
設定が完了したら、次のコマンドで、Docker コンテナを起動します。これで一連のコンテナが実行されます。初回起動時は、Docker Hub からコンテナ・イメージをプルするため、起動が完了するまで数分かかかります。
docker-compose up -d
システムの実行
サーバ環境の起動
サーバ環境で、docker-compose を使って一連のコンテナを起動します。 “./sakuraio/ngsi-adapter-websocket” ディレクトリに移動して、次のコマンドを実行します。初回起動時に、コンテナ・イメージを Docker Hub からダウンロードするため、起動が完了するまで時間がかかる場合があります。
docker-compose up -d
次のようなメッセージが表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
$ docker-compose up -d Creating network "iotagent-sakuraio_default" with the default driver Pulling mongo (mongo:3.6.16)... 3.6.16: Pulling from library/mongo 0a01a72a686c: Pull complete cc899a5544da: Pull complete 19197c550755: Pull complete 716d454e56b6: Pull complete 0793d4ab2500: Pull complete df33e33466d0: Pull complete 3b2d76901480: Pull complete df04584b8696: Pull complete 80dc6d311601: Pull complete df2c4e522682: Pull complete 6cf0d373bd70: Pull complete aa790a2500fb: Pull complete 90d454b168df: Pull complete Digest: sha256:7a67b178edc0a9a4bf269afc9dbb6b2ff3b8b8da1502eb5a40f2691abf223ce3 Status: Downloaded newer image for mongo:3.6.16 Pulling orion (fiware/orion:2.4.0)... 2.4.0: Pulling from fiware/orion f34b00c7da20: Pull complete 0590135f994b: Pull complete Digest: sha256:352b126ed89498931aabe22b3828265b46a7dd2642b14e05b470030eaba93c53 Status: Downloaded newer image for fiware/orion:2.4.0 Pulling iot-agent (fisuda/custom-iot-agent-sakuraio:1.0)... 1.0: Pulling from fisuda/custom-iot-agent-sakuraio Digest: sha256:657ecd2c4567fec0e2c55754cb3ca7474957909a332fd6293a2116ef0f726588 Status: Downloaded newer image for fisuda/custom-iot-agent-sakuraio:1.0 Creating iotagent-sakuraio_mongo_1 ... done Creating iotagent-sakuraio_iot-agent_1 ... done Creating iotagent-sakuraio_orion_1 ... done |
次のコマンドを実行して、3つのコンテナが正常に起動したことを確認します。
docker-compose ps
次のようなメッセージを確認できるはずです。
1 2 3 4 5 6 |
$ docker-compose ps Name Command State Ports ----------------------------------------------------------------------------------------------- iotagent-sakuraio_iot-agent_1 /usr/bin/node bin/iotagent ... Up 0.0.0.0:4041->4041/tcp iotagent-sakuraio_mongo_1 docker-entrypoint.sh --noj ... Up 27017/tcp iotagent-sakuraio_orion_1 /usr/bin/contextBroker -fg ... Up 0.0.0.0:1026->1026/tcp |
環境環境の設定
Orion の URL と IoT Agent の IP アドレスを設定します。これらが起動しているサーバの IP アドレスを 192.168.1.1 を仮定すると次のように設定します。IP アドレスは環境に応じて変更してください。
export ORION_URL=http://192.168.1.1:1026
export IOTA_IP=192.168.1.1
正常性の確認
IoT Agent のバージョン取得を実行して、正しくデプロイされたことを確認してください。IoT Agent の場合、以下のクエリで正常性を確認できます。
GET /iot/about
‘./sakuraio/iotagent-sakuraio’ のディレクトリにある、次のコマンドを実行して、レスポンスが返ってくることを確認してください。
./00_iotagentVersion
結果
1 2 3 4 5 6 |
{ "libVersion": "2.12.0", "port": "4041", "baseRoot": "/", "version": "1.0.0" } |
デバイスの接続
デバイスをIoT Agent に登録します。このため、最初にサービス・グループをプロビジョニングし、次にデバイスをプロビジョニングします。登録に必要なスクリプトは、’./sakuraio/iotagent-sakuraio’ のディレクトリにあります。
通信モジュール IDの登録
IoT Agent に接続するデバイスの通信モジュール ID を環境変数に登録します。
export DEVICE_ID=xCr8vqsJ0Zbe
サービス・グループのプロビジョニング
次のようなクエリを IoT Agent の ポート 4041 に POST することで、サービス・グループのプロビジョニングができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/bin/bash : ${IOTA_IP:?Not found} : ${IOTA_KEY:=1234} curl -X POST "http://$IOTA_IP:4041/iot/services" \ -H "Fiware-Service: openiot" -H "Fiware-ServicePath: /sakuraio"\ -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d "{ \"services\": [ { \"resource\": \"\", \"apikey\": \"$IOTA_KEY\", \"type\": \"Device\" } ] } " |
次のコマンドを実行して、サービス・グループをプロビジョニングしてください。正常に実行できると、201 Created のステータス・コードが返されます。
./01_createService
次のコマンドを実行すると、プロビジョニングされたサービス・グループの一覧を表示できます。
./02_listServiceGroup
結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ "count": 1, "services": [ { "commands": [], "lazy": [], "attributes": [], "_id": "5f1957746f7e3440b26dcaf9", "resource": "", "apikey": "1234", "service": "openiot", "subservice": "/sakuraio", "__v": 0, "static_attributes": [], "internal_attributes": [], "entity_type": "Device" } ] } |
デバイスのプロビジョニング
次のようなクエリで、動的な属性値として、温度、湿度、気圧、取得時刻を、静的な属性値として位置情報をもつデバイスとして、Ultralight 2.0 対応デバイスをプロビジョニングします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/bin/bash : ${IOTA_IP:?Not found} : ${DEVICE_ID:?Not found} curl -X POST "http://$IOTA_IP:4041/iot/devices" \ -H "Fiware-Service: openiot" -H "Fiware-ServicePath: /sakuraio" \ -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d "{ \"devices\": [ { \"device_id\": \"$DEVICE_ID\", \"entity_name\": \"urn:ngsi-ld:Device:$DEVICE_ID\", \"entity_type\": \"Device\", \"attributes\": [ { \"object_id\": \"t\", \"name\": \"temperature\", \"type\": \"Number\" }, { \"object_id\": \"h\", \"name\": \"relativeHumidity\", \"type\": \"Number\" }, { \"object_id\": \"p\", \"name\": \"atmosphericPressure\", \"type\": \"Number\" } ] } ] } " |
次のコマンドを実行して、Ultralight 2.0 対応デバイスをプロビジョニングしてください。正常に実行できると、201 Created のステータス・コードが返されます。
./11_deviceProvisioning
次のコマンドを実行すると、プロビジョニングされたデバイスの一覧を表示できます。
./12.list_device.sh
結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
{ "count": 1, "devices": [ { "device_id": "xCr8vqsJ0Zbe", "service": "openiot", "service_path": "/sakuraio", "entity_name": "urn:ngsi-ld:Device:uDr8vgsJ0Xbe", "entity_type": "Device", "attributes": [ { "object_id": "t", "name": "temperature", "type": "Number" }, { "object_id": "h", "name": "relativeHumidity", "type": "Number" }, { "object_id": "p", "name": "atmosphericPressure", "type": "Number" } ], "lazy": [], "commands": [], "static_attributes": [] } ] } |
IoT デバイスの起動
Raspberry Pi で “./sakuraio/iot-devcie” ディレクトリに移動して Python のプログラムを起動します。
OS上で実行
次のコマンドを実行すると、プログラムが起動して、コンソールにメッセージが表示されます。
sudo python3 sakuraio-i2c.py
Docker コンテナで実行
次のコマンドを実行して、コンテナを起動します。
make run
メッセージは次のコマンドで表示できます。
make logs
実行結果
次のようなメッセージが表示されます。”Connected” は、IoT デバイスが sakura.io に接続したことを示し、”Send Data” は、センサ・データを sakura.io に送信したことを示します。プログラムは60秒毎にセンサ・データを送信します。そのたびに、”Send Data” のメッセージが表示されます。
1 2 3 4 |
Connected Send Data Send Data Send Data |
エンティティの確認
サーバ環境で、Orion にアクセスしてエンティティ情報を確認してみます。次のコマンドで、エンティティ情報を取得できます。
curl -sS -H ‘FIWARE-Service: openiot’ -H ‘FIWARE-ServicePath: /sakuraio’ localhost:1026/v2/entities
実行結果
実行結果は次の通りです。このような情報を取得できれば、エンティティ情報を正しく更新できています。エンティティの id 属性値は、”urn:ngsi-ld:Device:xCr8vqsJ0Zbe” で、末尾の “xCr8vqsJ0Zbe” は通信モジュールの ID です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
$ curl -sS -H 'FIWARE-Service: openiot' -H 'FIWARE-ServicePath: /sakuraio' \ localhost:1026/v2/entities | jq . [ { "id": "urn:ngsi-ld:Device:xCr8vqsJ0Zbe", "type": "Device", "atmosphericPressure": { "type": "Number", "value": 1006.11, "metadata": { "TimeInstant": { "type": "DateTime", "value": "2020-07-18T00:58:42.00Z" } } }, "modifiedAt": { "type": "DateTime", "value": "2020-07-18T00:58:42.00Z", "metadata": {} }, "relativeHumidity": { "type": "Number", "value": 55.51, "metadata": { "TimeInstant": { "type": "DateTime", "value": "2020-07-18T00:58:42.00Z" } } }, "temperature": { "type": "Number", "value": 28.38, "metadata": { "TimeInstant": { "type": "DateTime", "value": "2020-07-18T00:58:42.00Z" } } } } ] |
環境設定のクリーンアップ
デバイス用コンテナの停止
Raspberry Pi の ‘./sakuraio/iot-devcie-ultralight’ のディレクトリで、次のコマンドを実行することで、デバイス用コンテナを停止できます。
make stop;make rm
デバイスの削除
次のコマンドで、Iot Agent にプロビジョニングしたデバイスを削除できます。
./13_deleteDevice
サービス・グループの削除
次のコマンドで、Iot Agent にプロビジョニングしたサービス・グループを削除できます。
./03_deleteServiceGroup
エンティティの削除
次のコマンドで、Orion にあるデバイスのエンティティを削除できます。
./22_deleteEntity