本記事では、Rapsberry Pi を使って、温湿度、気圧の情報をコンテキスト・ブローカーやコンテキスト・コンシューマにコンテキスト情報を提供する、コンテキスト・プロバイダを紹介します。
Context Provider (CPr)
コンテキスト・プロバイダ (CPr) は、コンテキスト・プロデューサ (CP) の特別な種類です。同期モードでオンデマンドでのコンテキスト情報を提供します。つまり、コンテキスト・ブローカーだけでなく、コンテキスト・コンシューマも、コンテキスト情報を取得するためにコンテキスト・プロバイダを呼び出すことができます。コンテキスト・プロバイダは特定の呼び出しに対してコンテキスト・データのみを提供します。すべてのコンテキスト・プロバイダは、適切なアナウンスをコンテキスト・ブローカーに送信することによりその可用性と機能をレジストレーション (登録) し、コンテキスト・ブローカーおよびコンテキスト・コンシューマにコンテキスト情報を提供するためにインタフェースを公開します。
前提条件
次の環境が必要となります。
- FIWARE Orion が稼働する Linux サーバ環境
- Raspberry Pi (i2c を有効化)
- 環境センサ Enviro for Raspberry Pi (Pimoroni)
- git, curl, jq コマンド
FIWARE Orion, WireCloud が稼働する環境の構築方法は、「WireCloud のセットアップ」の記事を参照ください。Raspberry Pi の種類は、Raspberry Pi Zero WH, 3, 4 等です。Raspberry Pi 4 を使用すると、FIWARE Orion と 環境情報を収集するプログラムを1台で稼働できます。環境センサの Enviro は、発売元の Pimoroni から購入するか、国内では秋月電子通商、スイッチサイエンス等から購入できるようです。
 
ソースコード
使用するソースコードは、Github の https://github.com/lets-fiware/lets-fiware.tutorials から入手できます。git コマンドで、リポジトリをクローンして、”raspberrypi/02.context_provider” ディレクトリに移動してください。
git clone https://github.com/lets-fiware/lets-fiware.tutorials.git
cd ./lets-fiware.tutorials/raspberrypi/02.context_provider
システム構成
システム構成は、Raspberry Pi で動作するコンテキスト・プロデューサと、Linux サーバで動作する Orion Context Broker です。
 
サーバ環境の作成
docker-compose ファイル
Orion は、Docker コンテナを利用して、Linux サーバ上にデプロイします。クローンしたリポジトリには、x86_64 (amd64) 用 と Raspberry Pi (aarch64) 用の dokcer-compose.yml ファイルがあります。環境に応じて、以下の設定を行います。
x86_64 (amd64)
ln -s docker-compose-arm64.yml docker-compose.yml
Raspberry Pi (aarch64)
ln -s docker-compose-aarch64.yml docker-compose.yml
Docker コンテナの起動
次のコマンドで、Docker コンテナを起動します。これで、Orion に関連する一連のコンテナが実行されます。
docker-compose up -d
Raspberry Pi での環境変数の設定
Raspberry Pi で、Orion とコンテキスト・プロデューサにアクセスするための環境変数を設定します。Orion が稼働する Linux サーバの IP アドレスを 192.168.1.1、コンテキスト・プロデューサが稼働する Raspberry Pi の IP アドレスを 192.168.1.2 として説明しています。環境に合わせて、値を変更してください。
export ORION_URL=http://192.168.1.1:1026
export CONTEXT_PROVIDER_URL=http://192.168.1.2:8080
正常性の確認
Raspberry Pi から、Orion のバージョンを取得するクエリを実行して、正しくデプロイされたことを確認してください。
GET /version
次のコマンドを実行して、レスポンスが返ってくることを確認してください。
./00.version.sh
| 1 2 3 4 5 6 7 8 9 10 11 12 | { "orion" : {   "version" : "2.4.0-next",   "uptime" : "0 d, 0 h, 32 m, 41 s",   "git_hash" : "4f26834ca928e468b091729d93dabd22108a2690",   "compile_time" : "Tue Mar 31 15:41:02 UTC 2020",   "compiled_by" : "root",   "compiled_in" : "d99d1dbb4d9e",   "release_date" : "Tue Mar 31 15:41:02 UTC 2020",   "doc" : "https://fiware-orion.rtfd.io/" } } | 
コンテキスト・プロバイダ環境の作成
プログラム概要
本記事で作成するコンテキスト・プロバイダは、コンテキスト・ブローカーからコンテキスト情報取得のリクエストを受け付けるために、次のエンドポイントを提供します。
POST /v1/weatherObserved/op/query
エンドポイントは、Python の Webサーバのライブラリを利用して実現します。具体的には、エンドポイントにアクセスがあると、温湿度、気圧の情報をセンサーから取得し、これらをコンテキスト情報としてレスポンスします。
プログラム全体
プログラム全体は以下のような内容です。この Pythonのプログラムがコンテキスト・プロバイダとして動作します。
| 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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys import signal from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import parse_qs, urlparse import json from bme280 import BME280 try:   from smbus2 import SMBus except ImportError:   from smbus import SMBus def handler(signum, frame):   sys.exit(0) class ContextProviderHandler(BaseHTTPRequestHandler):   def do_POST(self):     content_length = int(self.headers['content-length'])     path = self.path     if (path != '/v1/weatherObserved/op/query'):       self.send_response(404)       return     body = json.loads(self.rfile.read(content_length).decode('utf-8'))     e = body['entities'][0]['id']     if (e != device_id):       self.send_response(404)       return     if (debug):       print('path = {}'.format(path))       print('body = {}'.format(body))     response = [       {         "id": device_id,         "type": "WeatherObserved",         'temperature': {           'type': 'Number',           'value': '{:05.2f}'.format(bme280.get_temperature())         },         'relativeHumidity': {           'type': 'Number',           'value': '{:05.2f}'.format(bme280.get_humidity())         },         'atmosphericPressure': {           'type': 'Number',           'value': '{:05.2f}'.format(bme280.get_pressure())         }       }     ]     if (debug):       print(response)     self.send_response(200)     self.send_header('Content-Type', 'application/json; charset=utf-8')     self.end_headers()     self.wfile.write(json.dumps(response).encode('utf-8')) if __name__ == '__main__':   signal.signal(signal.SIGTERM, handler)   signal.signal(signal.SIGINT, handler)   bus = SMBus(1)   bme280 = BME280(i2c_dev=bus)   device_id = 'urn:ngsi-ld:WeatherObserved:' + os.environ.get('DEVCIE_ID', 'sensor002')   debug = not not os.environ.get('DEBUG_FLAG', '')   debug = True   print('Start Context Provider')   address = ('0.0.0.0', 8080)   with HTTPServer(address, ContextProviderHandler) as server:       server.serve_forever() | 
コンテキスト・プロバイダの実行
コンテキスト・プロバイダは、環境センサが接続された Raspberry Pi で実行します。
Docker コンテナ内での実行
Docker コンテナ・イメージの取得
コンテキスト・プロバイダ用のコンテナ・イメージを Docker Hubから取得します。次のコマンドで、fisuda/context_provider01 という名前のコンテナ・イメージを取得できます。
./pull.sh
Docker コンテナのビルド
プログラムをDocker コンテナ内で実行するため、環境センサ用コンテナをビルドします。ビルドには以下のコマンドを実行してい下さい。fisuda/context_provider01 という名前のコンテナ・イメージが作成されます。
./build.sh
Docker コンテナの起動
Dokcer コンテナを起動することで、プログラムを実行できます。起動時に、Orion の IP アドレスとポートを指定します。使用している環境に合わせて、これらの値を変更してください。
./run.sh
コンソールの出力
プログラムが正常に稼働しているかを確認するため、コンソールの出力を確認します。
./logs.sh
コマンドを実行して以下のようなメッセージが出力されば正常に稼働していることを確認できます。
| 1 | Start Context Provider | 
コンテキスト・プロバイダの登録
コンテキスト・ブローカーの FIWARE Orion から、このコンテキスト・プロバイダにアクセスできるように、コンテキスト・プロバイダのレジストレーションが必要です。
POST /v2/registrations
次のコマンドでレジストレーションできます。
./01.create-registration.sh
01.create-registration.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 | #!/bin/bash : ${ORION_URL:?Not found} : ${CONTEXT_PROVIDER_URL:?Not found} curl -iX POST \   "$ORION_URL/v2/registrations" \   -H "Content-Type: application/json" \   -H "Fiware-ServicePath: /device" \   -d "{   \"description\": \"Weather Context Source\",   \"dataProvided\": {     \"entities\": [       {         \"id\": \"urn:ngsi-ld:WeatherObserved:sensor002\",         \"type\": \"WeatherObserved\"       }     ],     \"attrs\": [       \"temperature\",       \"relativeHumidity\",       \"atmosphericPressure\"     ]   },   \"provider\": {     \"http\": {       \"url\": \"$CONTEXT_PROVIDER_URL/v1/weatherObserved\"     }   } }" | 
実行結果
“201 Created” のレスポンスがあれば正常に登録できています。
| 1 2 3 4 5 6 | HTTP/1.1 201 Created Connection: Keep-Alive Content-Length: 0 Location: /v2/registrations/5ed06731b10dc3f8b36b3c94 Fiware-Correlator: dddbc9de-a14c-11ea-b945-0242ac140004 Date: Fri, 29 May 2020 00:00:00 GMT | 
実行結果に含まれている Location 中の文字列 ”5ed06731b10dc3f8b36b3c94” がレジストレーション ID です。レジストレーションの情報取得や削除するときに使用します。以下の環境変数に登録しておきます。
export REG_ID=5ed06731b10dc3f8b36b3c94
レジストレーションの一覧情報を取得
レジストレーションの一覧情報は以下のクエリで取得できます。
GET /v2/registrations
02.list-registrations.sh
| 1 2 3 | #!/bin/bash : ${ORION_URL:?Not found} curl -sS -H "Fiware-ServicePath: /device" "$ORION_URL/v2/registrations" | jq . | 
実行結果
次のような内容がレスポンスとして返却されます。
| 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 | [   {     "id": "5ed06731b10dc3f8b36b3c94",     "description": "Weather Context Source",     "dataProvided": {       "entities": [         {           "id": "urn:ngsi-ld:WeatherObserved:sensor002",           "type": "WeatherObserved"         }       ],       "attrs": [         "temperature",         "relativeHumidity",         "atmosphericPressure"       ]     },     "provider": {       "http": {         "url": "http://192.168.1.3:8080/v1/weatherObserved"       },       "supportedForwardingMode": "all",       "legacyForwarding": true     },     "status": "active"   } ] | 
コンテキスト情報を取得
./run.sh でコンテキスト・プロバイダのコンテナを起動したあと、Orion にアクセスして、コンテキスト情報を取得します。次のクエリで取得できます。
GET /v2/entities/urn:ngsi-ld:WeatherObserved:sensor002
03.get_entity.sh
| 1 | $ curl -sS -X GET 192.168.1.2:1026/v2/entities/urn:ngsi-ld:WeatherObserved:sensor002 | jq . | 
結果
Orion にアクセスすると、Orion がコンテキスト・プロデューサから取得した、次のような情報はレスポンスとして返却されます。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | {   "id": "urn:ngsi-ld:WeatherObserved:sensor002",   "type": "WeatherObserved",   "temperature": {     "type": "Number",     "value": "23.74",     "metadata": {}   },   "relativeHumidity": {     "type": "Number",     "value": "26.87305",     "metadata": {}   },   "atmosphericPressure": {     "type": "Number",     "value": "1017.254",     "metadata": {}   } } | 
コンソールの出力
./log.sh でコンソールの出力を確認すると、エンティティ情報取得のリクエスト毎に、Orion から コンテキスト・プロバイダへのリクエストと、コンテキスト・プロバイダから Orion へのレスポンスが表示されます。
| 1 2 3 4 5 6 7 8 9 | Start Context Provider path = /v1/weatherObserved/op/query body = {'entities': [{'id': 'urn:ngsi-ld:WeatherObserved:sensor002', 'type': 'WeatherObserved'}], 'attrs': ['temperature', 'relativeHumidity', 'atmosphericPressure']} [{'id': 'urn:ngsi-ld:WeatherObserved:sensor002', 'type': 'WeatherObserved', 'temperature': {'type': 'Number', 'value': '25.47'}, 'relativeHumidity': {'type': 'Number', 'value': '92.09'}, 'atmosphericPressure': {'type': 'Number', 'value': '661.89'}}] 192.168.1.3 - - [29/May/2020 00:00:00] "POST /v1/weatherObserved/op/query HTTP/1.1" 200 - path = /v1/weatherObserved/op/query body = {'entities': [{'id': 'urn:ngsi-ld:WeatherObserved:sensor002', 'type': 'WeatherObserved'}], 'attrs': ['temperature', 'relativeHumidity', 'atmosphericPressure']} [{'id': 'urn:ngsi-ld:WeatherObserved:sensor002', 'type': 'WeatherObserved', 'temperature': {'type': 'Number', 'value': '35.53'}, 'relativeHumidity': {'type': 'Number', 'value': '19.76'}, 'atmosphericPressure': {'type': 'Number', 'value': '1006.29'}}] 192.168.1.3 - - [29/May/2020 00:00:01] "POST /v1/weatherObserved/op/query HTTP/1.1" 200 - | 
環境設定のクリーンアップ
レジストレーションの削除
次のクエリでレジストレーションを削除できます。
DELETE /v2/registrations/{id}
./04.delete-registrations.sh
| 1 2 3 4 | #!/bin/bash : ${ORION_URL:?Not found} : ${REG_ID:?Not found} curl -isS -H "Fiware-ServicePath: /device" -X DELETE "$ORION_URL/v2/registrations/$REG_ID" | 
実行結果
“204 No Content” のレスポンス・コードが返ってくれば、レジストレーションは正常に削除できています。
| 1 2 3 4 5 | HTTP/1.1 204 No Content Connection: Keep-Alive Content-Length: 0 Fiware-Correlator: 36509458-a15e-11ea-a5fd-0242ac140004 Date: Fri, 29 May 2020 00:00:04 GMT | 
コンテキスト・プロバイダの停止
次のコマンドを実行することで、コンテキスト・プロバイダのコンテナを停止できます。
./stop.sh


 
											 
							
							
							
															 
							
							
							
															 
										
					


