VITALIFY.ASIA logo

実践FIWARE PoC:Orionを使ったリアルタイム温度データ

FIWARE Orion Context Brokerを中心に、Open-Meteoの気温データをNGSI-v2で取り込み、QuantumLeap・CrateDBで履歴保存し、Grafanaで可視化するPoCを解説。Entity・Attribute、Smart Data Models、Subscription、Docker ComposeやARM64環境で発生した実装課題まで整理します。

Thinh Tran
実践FIWARE PoC:Orionを使ったリアルタイム温度データ
目次

VFAのベトナム人エンジニアが執筆した記事です。原文は、こちらのベトナム語版です。

こんにちは。Thinhです。3D開発を専門にしているエンジニアです。

普段は主に3DやBIMの開発をしていますが、先週、上司から突然こんなことを言われました。

「FIWARE(Future Internet WARE、ファイウェア)について調べてみて。」

……FIWAREって、いったい何だろう?

今回の調査は、そんな疑問から始まりました。

調べていく中で、FIWAREはSmart CityIoTなどの分野で利用されているオープンソースのプラットフォームエコシステムだということが分かりました。

その中心的なコンポーネントの一つが、Orion Context Brokerです。

ただ、ドキュメントを読むだけでは、FIWAREが実際にどのように動いているのかを具体的にイメージするのはなかなか難しいものでした。

そこで今回は、実際の気温データを使って、次のようなデータパイプラインを構築してみました。

Open-Meteo
    ↓
weather_ingest.py
    ↓
Orion Context Broker
    ↓
QuantumLeap
    ↓
CrateDB
    ↓
Grafana

このPoCを通して、FIWAREが実際の環境でどのように動くのかを試してみました。

この記事では、最初は「FIWAREって何?」という状態だったところから、実際にPoCを構築するまでに分かったこと、そしてその過程で遭遇した実際の問題について紹介します。


1. FIWAREとは?

コードを書く前に、まず理解する必要があったのは、

そもそもFIWAREとは何なのか?

ということでした。

最初は、FIWAREを一つのソフトウェア、あるいは一つのサーバーだと考えてしまいがちです。

しかし、実際には少し違います。

FIWAREはオープンソースのプラットフォームエコシステムであり、複数のコンポーネントを組み合わせることで、Smart City、IoT、Context-aware Applicationなどを構築できます。

今回、私が特に注目したのが、

Orion Context Broker

です。

そして、次にこんな疑問が出てきました。

Context Brokerはいったい何をするものなのか?

2. Orion Context Brokerとは?

簡単に言えば、Context Brokerはシステム内のオブジェクトやEntityの現在の状態を管理するものです。

今回のPoCでは、日本の5つの都市を対象にしました。

Tokyo
Osaka
Kyoto
Nagoya
Sapporo

それぞれの都市に対応するEntityを作ります。

WeatherObserved:Tokyo
WeatherObserved:Osaka
WeatherObserved:Kyoto
WeatherObserved:Nagoya
WeatherObserved:Sapporo

それぞれのEntityには、現在の気温が保存されます。

例えば、東京の場合は次のようになります。

{
  "id": "WeatherObserved:Tokyo",
  "type": "WeatherObserved",
  "temperature": {
    "type": "Number",
    "value": 28.4
  }
}

ここで、

  • WeatherObserved:TokyoEntity
  • temperatureAttribute
  • 28.4 が現在の値

です。

重要なのは、Orionが単純なデータベースではないということです。

OrionはContext Informationを管理し、データが変更されたときに他のシステムへ通知できる仕組みを持っています。


3. NGSI-v2とは?

調べていると、もう一つよく出てくる言葉がありました。

NGSI-v2です。

FIWAREがエコシステム、OrionがContext Brokerだとすると、NGSI-v2は、簡単に言えばContext Brokerと通信するためのAPI / Protocolです。

例えば、Entityを取得する場合:

GET /v2/entities

Attributeを更新する場合:

PATCH /v2/entities/WeatherObserved:Tokyo/attrs

関係を図にすると、次のようになります。

FIWARE
  │
  └── Orion Context Broker
          │
          └── NGSI-v2 API

ここで重要なことが一つ分かりました。

FIWARE = Orionではありません。

FIWAREはエコシステムであり、OrionはContext Brokerの実装の一つです。


4. EntityとAttribute

FIWAREを理解するうえで、特に重要な概念の一つがEntityです。

一般的なIoTシステムを構築するとき、私たちはDatabase TableやJSON Objectを考えることが多いと思います。

FIWAREでは、少し違った考え方をします。

Entityは、現実世界に存在するオブジェクトや対象を表します。

例えば、

WeatherObserved:Tokyo

というEntityがあります。

このEntityには、次のようなAttributeを持たせることができます。

temperature
relativeHumidity
windSpeed
location
dateObserved

今回のPoCでは、パイプラインをシンプルにして分かりやすくするため、主にtemperature(気温)に焦点を当てました。

Attributeは単なる値ではありません。

例えば、

"temperature": {
  "type": "Number",
  "value": 28.4
}

のように、

  • type
  • value
  • 必要に応じてmetadata

などを持つことができます。

この構造は、一般的なREST APIとは少し違う、FIWAREらしい特徴の一つだと感じました。


5. Smart Data Models

調査を進める中で、もう一つ気になったのがSmart Data Modelsです。

もしプロジェクトごとにEntityの構造を自由に決めてしまうと、データの共有やシステム間の連携が難しくなります。

例えば、あるプロジェクトでは、

temperature

を使っているのに、別のプロジェクトでは、

temp

または、

currentTemperature

を使っているかもしれません。

Smart Data Modelsでは、分野ごとに標準化されたデータモデルが定義されています。

今回のPoCでは、

WeatherObserved

を使用しました。

つまり、単なる自由形式のJSONではなく、あらかじめ定義された構造に沿ってデータを扱うことができます。


6. PoCを作ってみる

基本的な概念を理解したところで、実際にシンプルなパイプラインを作り始めました。

今回のPoCの目的は、とてもシンプルです。

実際の気温データを取得する → Orionに送る → 履歴を保存する → Dashboardに表示する。

データソースにはOpen-Meteoを使いました。

今回の用途では、API Keyを必要とせずにWeather APIを利用できます。

対象としたのは、日本の5つの都市です。

Tokyo
Osaka
Kyoto
Nagoya
Sapporo

データは約5分ごとに更新します。


7. Open-Meteo → weather_ingest.py

まず、

weather_ingest.py

というPython ScriptからOpen-Meteo APIを呼び出します。

5都市それぞれに対して5回リクエストを送るのではなく、5都市の座標をまとめて一つのリクエストとして送るようにしました。

取得したデータを、Orionが扱える形式に変換します。

概念的には、

Open-Meteo
    ↓
weather_ingest.py
    ↓
WeatherObserved entities

という流れです。

例えば、東京の気温データは次のようになります。

{
  "id": "WeatherObserved:Tokyo",
  "type": "WeatherObserved",
  "temperature": {
    "type": "Number",
    "value": 28.4
  }
}

そして、このEntityをOrionへ送ります。


8. Orionへデータを送る

データの更新には、OrionのNGSI-v2 APIを使用します。

例えば、

PATCH /v2/entities/WeatherObserved:Tokyo/attrs

のようにリクエストします。

まだEntityが存在しない場合は、新しくEntityを作成します。

実際の流れは、

Entity exists?
     │
 ┌───┴───┐
Yes      No
 │        │
PATCH    POST
 │        │
 └───┬────┘
     ↓
   Orion

となります。

最初の実行では、Orionに5つのEntityが作成されます。

その後の実行では、それぞれのEntityの気温が更新されます。


9. 重要なポイント:Orionが管理するのは現在の状態

ここで、一つ重要なことに気付きました。

例えば東京の気温が、

10:00 → 28.0°C
10:05 → 28.3°C
10:10 → 28.7°C
10:15 → 29.1°C

と変化した場合、Orionが主に扱うのは、

29.1°C

つまり、**現在の状態(Current State)**です。

Orionは、すべての履歴を永続的に保存するためのHistorical Databaseではありません。

では、

OrionがHistorical Databaseではないなら、過去のデータはどこに保存されるのか?

そこで登場するのがQuantumLeapです。


10. Orion → QuantumLeap

QuantumLeapは、Context Brokerから取得したContext Dataの履歴を永続化するためのコンポーネントです。

今回はOrionにSubscriptionを作成しました。

概念的には、

Orion
  │
  │ data changed
  ↓
QuantumLeap

という流れになります。

気温が変更されると、OrionがQuantumLeapへNotificationを送ります。

つまり、

weather_ingest.pyからQuantumLeapを直接呼び出す必要はありません。

Scriptが行うのは、

Open-Meteo
    ↓
Orion

までです。

その後、OrionがQuantumLeapへ変更を通知します。

この構成は、それぞれのコンポーネントの役割が明確に分かれている点が良いと感じました。


11. QuantumLeap → CrateDB

QuantumLeapは、その履歴データをCrateDBへ保存します。

ここまで来ると、パイプライン全体がかなり見えてきます。

Open-Meteo
    ↓
weather_ingest.py
    ↓
Orion
    ↓
QuantumLeap
    ↓
CrateDB

例えば、しばらくデータを収集すると、CrateDBには次のような履歴が保存されます。

Tokyo
10:00   28.0°C
10:05   28.3°C
10:10   28.7°C
10:15   29.1°C

これは、Orionが主に担当する部分ではない、

Historical Data

です。


12. CrateDB → Grafana

最後に、実際のデータを確認するためにGrafanaを使用しました。

GrafanaからCrateDBのデータをQueryし、Dashboardとして表示します。

完成したパイプラインは次のようになります。

┌─────────────┐
│ Open-Meteo  │
└──────┬──────┘
       ↓
┌──────────────────┐
│ weather_ingest.py│
└────────┬─────────┘
         ↓
┌──────────────────┐
│ Orion Context    │
│ Broker           │
└────────┬─────────┘
         ↓
┌──────────────────┐
│ QuantumLeap      │
└────────┬─────────┘
         ↓
┌──────────────────┐
│ CrateDB          │
└────────┬─────────┘
         ↓
┌──────────────────┐
│ Grafana          │
└──────────────────┘

これで、5都市の気温履歴をGrafana上で確認できるようになりました。

単純なWeather APIから始めて、最終的には、

Real-time Data → Context Broker → Historical Storage → Visualization

という一通りのデータパイプラインを作ることができました。


13. パイプライン全体を振り返る

実際にシステムを動かしてみると、それぞれのコンポーネントの役割を次のように整理できます。

ComponentRole
Open-Meteo気温データを提供
weather_ingest.pyデータの取得と変換
OrionCurrent Contextを管理
QuantumLeapContextの変更をHistorical Dataとして保存
CrateDBHistorical / Time-series Dataを保存
GrafanaデータのQueryと可視化

全体の流れは、

Open-Meteo
    ↓
weather_ingest.py
    ↓
Orion Context Broker
    ↓
QuantumLeap
    ↓
CrateDB
    ↓
Grafana

です。

今回のPoCを通して、私が最も理解できたのはこの部分でした。

FIWAREを単純な**「Database」として見るのではなく、それぞれのコンポーネントが異なる役割を持つ「Data / Context Platform」**として考えると、全体の構成がかなり分かりやすくなりました。


14. 実際に遭遇した問題

Architecture Diagramだけを見ると、すべてがかなりシンプルに見えます。

しかし、実際にシステムを動かしてみると、いくつか興味深い問題に遭遇しました。

14.1. Containerが起動した = ServiceがReady、ではない

Docker Composeでは、Containerが起動したからといって、その中のApplicationがすぐにRequestを受け付けられるとは限りません。

例えば、

MongoDB starts
      ↓
Orion container starts
      ↓
Orion is not ready yet

という状態になる可能性があります。

このタイミングで別のServiceからOrionへRequestを送ると、失敗することがあります。

そのため、Health Checkservice_healthyを使ったdepends_onを設定し、実際にServiceがReadyになってから依存先が起動するようにしました。


14.2. GrafanaのLogin Session

もう一つはGrafanaに関する問題です。

Default Accountを使用した後にPasswordを変更すると、Sessionが無効になることがあります。

その結果、後続のRequestが、

/login

へRedirectされる場合があります。

Frontendだけを見ていると、APIやDatasourceの問題だと勘違いしやすいところでした。


14.3. Subscriptionが存在していてもNotificationが失敗する

今回、特に興味深かったのがこの問題です。

Orion上ではSubscriptionが正常に存在しているように見えても、QuantumLeapから、

HTTP 400

が返ってくることがあります。

今回のケースでは、Notification Formatが原因でした。

attrsFormatがLegacyなNGSI-v1 Formatになっている一方で、QuantumLeap側がNGSI-v2に対応したFormatを期待している場合、Subscription自体は正常に作成されても、実際のデータ送信は失敗します。

ここから、

「Subscriptionが存在する」=「Data Pipelineが正常に動いている」ではない

ということを学びました。

Subscriptionの状態だけではなく、実際のNotification Flowまで確認する必要があります。


15. このPoCで分かったこと

今回のPoCは比較的小さなものです。

  • 5都市
  • 約5分ごとの更新
  • 主なデータはtemperature
  • Docker Composeによるローカル環境

それでも、FIWAREの各コンポーネントがどのように連携するのかを理解するには十分でした。

特に、Orionの役割について、

Orion
  ↓
Manage current context
  ↓
Notify other systems

というイメージを持てるようになりました。

つまり、

Orion
  ↓
Store everything forever

というものではありません。

これはArchitectureを設計するときに重要なポイントだと思います。


16. 今回のPoCでは扱っていないこと

今回のPoCは、あくまで最初のステップです。

まだ、以下のようなケースは試していません。

  • 数千〜数百万Entity
  • 非常に高い更新頻度
  • MQTT / LoRaWAN
  • IoT Agents
  • Message Queue
  • High Availability
  • Orion Clustering
  • MongoDBのScaling / Sharding

例えば、5都市のデータを5分ごとに更新する程度であれば、システムへの負荷は比較的小さいです。

しかし、

100,000 sensors
      ↓
updates every few seconds

のような環境になった場合、Architectureを改めて評価する必要があります。

そして、これが次に試してみたい、より興味深いテーマです。


17. まとめ

最初に、

「FIWAREについて調べてみて。」

と言われたとき、私は正直、FIWAREが何なのか全く知りませんでした。

しかし、自分で調べ、実際にPoCを構築してみることで、FIWAREについてかなり具体的なイメージを持てるようになりました。

今回学んだことをまとめると、次のようになります。

FIWARE
  │
  ├── Orion
  │     └── Current Context
  │
  ├── QuantumLeap
  │     └── Historical Persistence
  │
  ├── CrateDB
  │     └── Historical Data
  │
  └── Grafana
        └── Visualization

5都市のデータを5分ごとに更新するという小規模なケースでは、FIWARE OrionはCentral Context Brokerとして十分検討できると感じました。

今回、私が一番面白いと思ったのは、単にAPIから気温データを取得できたことではありません。

実際に自分でパイプラインを構築することで、

「なぜFIWAREはこのような構成になっているのか」

そして、

「それぞれのコンポーネントは何のために存在するのか」

を少しずつ理解できるようになったことです。

そして、これはまだ始まりに過ぎないのかもしれません。

次に試してみたいのは、

5都市から数千、あるいは数十万Entityまでスケールさせた場合、FIWARE Orionはどのように動くのか?

ということです。

1,000社以上の事業成長を支えた圧倒的な『スピードと柔軟性』で、御社のアイデアを最短で形にします。まずは無料で壁打ちしませんか?

ブログに戻る
ぼくはデューパー、なんでもきいてね!