2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OCI Internet of Things Platform入門 ― 自宅の温度データをOCIへ送ってみた

2
Last updated at Posted at 2026-08-07

OCI Internet of Things Platform(以下OCI IoT)は2025年10月にGAとなったサービスです。
端末からセンサーデータを受信する機能だけではなく、OCI IoTはセンサーデータの業務利用まで考慮したサービスとなっています。
センサーデータは端末によって様々なフォーマットで送信されます。
また受信したデータはどこかに蓄積し、アプリケーションやBIから利用できる形にする必要があります。

image.png

OCI IoTは以下特徴を備えることで、センサーデータの受信から業務活用まで簡単に実現できるよう設計されています。

  • 多用なフォーマットのセンサーデータを正規化し、共通モデル化して利便性を向上
  • 受信データは更新が多いオンライン系処理に強い、Autonomous AI Database(ADB)の Autonomous Transaction Processing(ATP)に格納
  • すぐに使えるAPEX環境があるため、データ確認や蓄積データを使ったアプリを簡単に構築
  • HTTPS、MQTTS、MQTT over WebSocketによるセンサーデータ受信に対応

image.png

ちなみにセンサーデータの正規化には DTDL v3 が使われています。

image.png

DTDL v3 で定義されたデジタル・ツイン・モデルの適用により、以下イメージ図の通り異なるフォーマットのデータを共通フォーマットに変換でき、アプリケーション等から利用しやすくなります。

image.png

ユースケースとして製造業はもちろんですが、様々な業種業態でも活用頂けます。

image.png

今回はこのOCI IoTの基本動作を検証しましたので、以降は具体的な検証手順をまとめたいと思います。
おおまかな流れは以下の通りです。

image.png

検証環境の構成は次の通りです。

たまたま自宅にあったIoT系のデバイスを使っています。

Nature Remo mini 2
IMG_5222.jpg

Raspberry Pi 3
IMG_5220.jpg

目次

IAMポリシー設定

OCI IoTを構築するためのIAMポリシーを設定します。

allow group <group-name> to manage iot-family in compartment <compartment-name>

OCI Vaultとシークレット作成

今回は認証方式にシークレットを利用します。
なお本番利用の際はシークレットではなくmTLS証明書による認証が推奨方式です。

以下を参考にOCI Vaultを作成します。
名前を入力したら他はデフォルトのまま作成します。

続いて以下を参考にマスター暗号化キーを作成します。
名前を入力したら他はデフォルトのまま作成します。

作成したOCI Vaultとマスター暗号化キーでシークレットを用意します。
手順は以下をご参照ください。

今回は検証ということでシークレット・ローテーション、ルールは設定せずデフォルトのまま作成しました。

image.png

またこの後OCI IoTからVaultを利用するため、利用許可のIAMポリシーを設定しておきます。

Allow any-user to {SECRET_BUNDLE_READ, SECRET_READ} in compartment <compartment-name> where ALL {request.principal.type = 'iotdomain', target.vault.id = '<vault-OCID>'}

OCI IoT関連コンポーネントの構築

ここからOCI IoTの作成に入っていきます。
OCI IoTでは以下を構成していきます。

image.png

恐らくですが、各コンポーネントの作成単位は次のようになりそうです。

項目 作成単位・方針
ドメイン・グループ DBを分離したい要件に応じて作成
ドメイン 分析用途の単位で作成(工場の生産ライン単位など?)
デジタル・ツイン・モデル 送受信するデータの種別単位で作成(例:温度と湿度、機器の状態など)
デジタル・ツイン・アダプタ 送受信するデータの種別単位で作成(例:温度と湿度、機器の状態など)
デジタル・ツイン・インスタンス 送信元となるセンサー機器単位で作成

ドメイン・グループ作成

まずはドメイン・グループを作成します。

ドメイン・グループを作成すると内部的にATPが構築されます。
なおドメイン・グループ・タイプについては今回は検証のため「開発者」にチェックを入れています。
「開発者」にチェックしない場合、本番向けということでリソースのスケーリングや自動フェイルオーバーが有効化されます。

image.png

ドメイン作成

作成したドメイン・グループの中にドメインを追加します。

名前と説明は任意の内容を入力します。
ドメイン・グループは先ほど作成したものを選びます。

image.png

このドメインの中にデジタル・ツイン系のコンポーネントを作成していきます。

デジタル・ツイン・モデル作成

まずはドメインの中にデジタル・ツイン・モデルを追加します。

作成したドメインの詳細画面より「デジタル・ツイン・モデル」のタブを選択し、作成ボタンを押下します。

image.png

名前や説明を入力した後、「モデル仕様」にて「仕様の貼り付け」を選択します。
ここで DTDL v3 に従った JSON-LD 形式のモデル定義を入力していきます。

image.png

今回やり取りするセンサーデータのフォーマットは以下を想定しています。

{ "temp": 25.4 }

温度データのみを送るという非常にシンプルなフォーマットです。
本検証で使うNature Remo mini 2は上記フォーマットですが、同じ温度センサーでも機器によっては次のようなフォーマットかもしれません。

{"sensorValue": 25.4, "unit": "C"}

フォーマットが異なるとデータを利用するアプリ側が困ります。
そのためOCI IoTではデジタル・ツイン・モデルによって正規化し、データ活用しやすくする機能が備わっています。
これを DTDL v3 という仕様に沿って実装するのですが、具体的なリファレンスは以下をご参照ください。

今回のケースにおいてデジタル・ツイン・モデルの定義は以下のようになります。

{
  "@context": [
    "dtmi:dtdl:context;3",
    "dtmi:dtdl:extension:historization;1",
    "dtmi:dtdl:extension:quantitativeTypes;1"
  ],
  "@id": "dtmi:com:example:iot:temperatureSensor;2",
  "@type": "Interface",
  "displayName": "Temperature Sensor",
  "description": "Digital twin model for historized temperature data",
  "contents": [
    {
      "@type": [
        "Telemetry",
        "Historized",
        "Temperature"
      ],
      "name": "temp",
      "displayName": "Temperature",
      "description": "Temperature measured in degrees Celsius",
      "schema": "double",
      "unit": "degreeCelsius"
    }
  ]
}

主な種別としてセンサーデータを時系列データとして扱うか否か、という観点があります。
今回は時系列データにしたいため @typeHistorized を定義しています。
時系列データにしない場合は最新の値のみに着目する形でデータが保持されます。
その場合も過去データを参照する方法は一応ありますが、時系列で活用したいのであれば時系列データ化した方が利便性は良いです。

最終的な作成画面は以下のようになります。

image.png

作成ボタンを押下し、モデル仕様に問題がなければデジタル・ツイン・モデルが作成されます。

デジタル・ツイン・アダプタ作成

デジタル・ツイン・アダプタは受信したセンサーデータをデジタル・ツイン・モデルにマッピングして正規化するコンポーネントです。

ドメインの詳細画面から「デジタル・ツイン・アダプタ」タブを選び、作成ボタンを押下します。

image.png

名前、説明は任意の内容で入力します。
デジタル・ツイン・モデルは先ほど作成したモデルを選びます。

次に「インバウンド・エンベロープおよびルートの指定」を有効化します。
インバウンド・エンベロープとインバウンド・ルートの仕様については下記マニュアルをご参照ください。

それぞれの役割はざっくり以下の通りです。

要素 役割
インバウンド・エンベロープ(Inbound Envelope) 受信メッセージ全体から、後続処理に必要な共通メタデータやコンテキストを取り出す
インバウンド・ルート(Inbound Route) エンベロープで整理された情報を使って、どの処理を実行するかを条件分岐し、必要ならペイロードを変換・別Digital Twinへ転送する

まずはインバウンド・エンベロープがデータの観測日時やターゲットとなるデジタル・ツイン・インスタンスの情報を抽出します。
その後インバウンド・ルートにデータが渡り、データの中身をデジタル・ツイン・モデルで定義した形式に変換することで正規化します。
データ変換は JQ式 と呼ばれる言語で実装します。
変換する際ですが、元データのフォーマットに応じてマッピングを変えられるようになっています。
例えば以下のように condition を使ってマッピング方式を分岐できます。

[
  {
    "condition": "${endpoint(1) == \"hvac\"}",
    "payloadMapping": { ... }
  },
  {
    "condition": "${endpoint(1) == \"compressor\"}",
    "payloadMapping": { ... }
  },
  {
    "condition": "*",
    "payloadMapping": { ... }
  }
]

今回はJSONフォーマットが単純で宛先となるデジタル・ツイン・インスタンスも1つのため、以下の通り非常にシンプルな定義となっています。

インバウンド・エンベロープ

{
  "referenceEndpoint": "sampletopic",
  "referencePayload": {
    "dataFormat": "JSON",
    "data": {
      "temp": 32.4
    }
  }
}

インバウンド・ルート

[
  {
    "description": "Map temperature telemetry to the temp field",
    "condition": "*",
    "payloadMapping": {
      "$.temp": "$.temp"
    },
    "referencePayload": {
      "dataFormat": "JSON",
      "data": {
        "temp": 32.4
      }
    }
  }
]

以下のように必要情報を入力し、作成ボタンを押下します。

image.png

デジタル・ツイン・インスタンス作成

最後にデジタル・ツイン・インスタンスを作成します。

名前、説明は任意の内容を入力します。

外部キーは端末からデータ送信する際に利用するユーザ名となります。
未入力で作成すると自動でランダムな文字列が定義されます。

タイプは「直接接続」を選びます。

image.png

アダプタの選択を有効化し、作成したデジタル・ツイン・アダプタを選びます。

認証IDは「認証IDの選択」を選び、最初の方で作成したOCI Vaultとシークレットを選びます。

image.png

以上で作成ボタンを押下します。

センサーデータを送信してみる

これでOCI IoT側はデータを受け取る準備が出来ましたので、実際に端末からデータを送ってみます。
今回送るデータは Nature Remo mini 2 の温度センサーが計測した、自宅のリビングの温度データになります。
HTTPSとMQTTS両方を試してみます。

HTTPSで送信

まずはHTTPSです。今回は単純な curl コマンドのワンライナーを使って送信します。
コマンド例は Nature Remo mini 2 のAPIを想定しているため、他の端末であればコマンドは変わってきます。

curl \
  -u '<external key>:<secret>' \
  -H 'Content-Type: application/json' \
  -d "$(
    curl -sS -X GET \
      'https://api.nature.global/1/devices' \
      -H 'accept: application/json' \
      -H 'Authorization: Bearer <your api token>' \
    | jq '.[] | select(.name == " リビング") | {temp: .newest_events.te.val}'
  )" \
  'https://<domain>.device.iot.<region>.oci.oraclecloud.com/sampletopic'

無事に送信できると Accepted と標準出力に返ってきます。
external key には作成したデジタル・ツイン・インスタンスの詳細画面から確認できる「外部キー」を入れます。
secret は冒頭で作成したシークレットの内容をプレーンテキストで入れます。
最後に指定しているエンドポイントについては、ドメインの詳細画面にある「エンドポイント」から確認できます。

Nature Remo mini 2のAPI実行パートについては割愛しますが、リファレンスは以下になります。

MQTTSで送信

始めにMQTTについて補足しますと、MQTTはセンサーデータのような細かいデータを大量かつ継続的に送信するユースケース向けに作られたプロトコルです。
HTTPと比べて通信のオーバーヘッドを抑えられるメリットがあります。

image.png

image.png

MQTTSで送信するには対応したクライアント・ツールが必要です。
今回は mqttx を利用しました。
ARMのRaspberry Pi 3上で実行するため、ARM版を以下のようにインストールしました。

curl -LO \
  https://www.emqx.com/zh/downloads/MQTTX/1.13.0/mqttx-cli-linux-arm64

sudo install \
  ./mqttx-cli-linux-arm64 \
  /usr/local/bin/mqttx

mqttx を使ったデータ送信コマンドは次の通りです。

mqttx pub \
  -h <domain>.device.iot.<region>.oci.oraclecloud.com \
  -p 8883 \
  --protocol mqtts \
  -t "/sampletopic" \
  -m "$(curl -sS -X GET "https://api.nature.global/1/devices" -H "accept: application/json" -H "Authorization: Bearer <your api token>" | jq '.[] | select(.name == " リビング") | {temp: .newest_events.te.val}')" \
  -u "<external key>" \
  -P "<secret>"

受信したデータをOCI IoT側で確認

データ確認はいくつか方法があります。

  • ATPにDBクライアントから直接接続して確認
  • APEXのSQLコマンドやアプリを利用
  • Oracle Analytics ClousなどBIツールから参照

今回はAPEXのSQLコマンドから簡単に確認してみました。
なおデータ確認するには、以下マニュアルにある通り、方法に応じて事前の許可設定が必要となります。

APEXから確認する場合はOCIコマンドを使って以下を事前実行します。

oci iot domain configure-apex-data-access --db-workspace-admin-initial-password "<your password>" --iot-domain-id <IoT Domain OCID>

これでAPEXワークスペースへログインできるようになりました。
APEXワークスペースのURL、ワークスペース名とユーザ名はドメイン詳細画面より確認できます。
パスワードは上記 oci コマンドで入力したパスワードを使います。

image.png

ちなみに受信したデータは以下フローで処理されます。

image.png
※画像の出展元: https://docs.oracle.com/ja-jp/iaas/Content/internet-of-things/overview.htm#flow

上記画像に記載されている表のうち、以下は実表として存在します。

テーブル名 用途
RAW_DATA_IN 受信したデータをそのまま保管
NORMALIZED_DATA デジタル・ツイン・モデルで正規化されたデータを保管
REJECTED_DATA_IN デジタル・ツイン・モデルによる正規化が上手く出来なかったデータを保管

以下はViewとして存在します。

テーブル名 用途
RAW_DATA 受信したデータをそのまま参照
HISTORIZED_DATA 時系列データとしてこれまで受信したデータを参照
SNAPSHOT_DATA 受信データのうち最新のものを参照
REJECTED_DATA 正規化が上手く出来なかったデータを参照(失敗した理由も確認可能)

実際にアプリやBIから参照するデータはViewの方になると思われます。
ということで4つのViewそれぞれを確認した結果が次の通りです。

Rowデータ

SELECT * FROM <domain>__IOT.RAW_DATA WHERE DIGITAL_TWIN_INSTANCE_ID = '<digital twin instance ocid>'

image.png

Rejectedデータ

SELECT * FROM <domain>__IOT.REJECTED_DATA WHERE DIGITAL_TWIN_INSTANCE_ID = '<digital twin instance ocid>'

image.png

Historizedデータ

SELECT * FROM <domain>__IOT.HISTORIZED_DATA WHERE DIGITAL_TWIN_INSTANCE_ID = '<digital twin instance ocid>'

image.png

Snapshotデータ

SELECT * FROM <domain>__IOT.SNAPSHOT_DATA WHERE DIGITAL_TWIN_INSTANCE_ID = '<digital twin instance ocid>'

image.png

おわりに

以上、OCI Internet of Things Platformの簡易検証でした。
本サービスを通して最近はやりのフィジカルAIも実装できるのでは、と考えていたりします。
もちろんOCI IoTのデータ基盤はATPですので、SELECT AIやSELECT AI Agentも使えます。
という訳で次回はSELECT AI Agentを使い、OCI IoTに蓄積されたデータを使って簡単なAIエージェントを実装してみたいと思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?