参照: デジタル・ツイン・モデルおよびアダプタのJQ式

デバイス入力、アダプタ・エンベロープ、ルート条件およびペイロード・マッピングの実用的なJQ式パターンで、テレメトリをデジタル・ツイン・モデルで定義されるものに正規化します。

主な概念

デジタル・ツイン・アダプタ内にJQ式をプレースホルダ${ ... }として記述して、payload-mappingのターゲット値を計算し、ルート条件を評価できます。

JQ式の一般的な使用方法:

  • デバイス入力: デバイスによってポストされたRAWペイロード。
  • エンベロープ: 参照エンドポイントおよびサンプル・ペイロード・シェイプを宣言します。たとえば、timeObservedマッピングを定義できます。
  • ルート: エンドポイント、ヘッダー、本文などの条件を評価し、ペイロード・マッピングを選択します。
  • ペイロード・マッピング: 変換、ユニットの変換、キーの名前変更およびDTDLモデル・スキーマへの正規化を行います。
  • 出力: タイプ、範囲、単位など、デジタル・ツイン・モデル検証を満たす必要がある正規化されたJSON出力。
  • マッピング関数のサポート: 算術関数およびfloor関数を使用できます。toIntegernumberなどの関数はサポートされません。
  • エンドポイント一致: endpoint(n)を含むセグメントベースの条件を使用します。たとえば、サポートされていないワイルドカード・パターンではなく${endpoint(1) == 'home' and endpoint(2) == 'sonnen' and endpoint(3) == 'status'}です。
  • 整数スキーマとダブル・スキーマ:
    • schema: "integer"の場合、マッピングが整数("${(.velocity_kph / 1.609) | floor}"など)を発行していることを確認します。
    • schema: "double"の場合、小数出力が受け入れられます。floorは、68.0などの整数記憶域をdoubleとして使用する場合にのみ使用します。
  • ソフト変換タイプ: 数値のような文字列と整数倍は、モデル・タイプ(整数など)と一致する場合に受け入れられます。number()toIntegerなどのキャスト・ヘルパーは、ルート式ではサポートされません。算術およびfloorに依存するか、schema: "double"を採用して分数を保持します。
    • パススルー(mph、スキーマ"integer"): {"speed": "60"}および{"speed": 60.0}60として格納されます。{"speed": "60.2"}は、マッピングがfloorなどの整数に強制されないかぎり拒否されます。
    • メトリック・ルート(kph→mph): {"velocity_kph": 110}68、マッピングfloorが整数を発行するため{"velocity_kph": "110"}68。式エラーを回避するために、算術入力の数値を保持します。可能な場合は、"110"よりも110を優先します。
    • 丸めは明示的なままです: ソフト変換では、68.3568に自動丸められません。整数スキーマにfloorを使用するか、モデルをschema: "double"に切り替えて分数を保持します。
  • エンベロープおよび時間処理: timeObservedが指定されていない場合、プラットフォームはreceivedTimeを使用できます。エンベロープまたはペイロード・マッピングの時間変換には、fromdateformattodateformatおよび関連関数を使用します。
ノート

データ検証は、DTDLモデルに対して行われます。プロパティがintegerとして宣言されている場合、正規化された出力は、stringまたはfloatではなく、integer値である必要があります。次の整数の修正パターンを参照してください。

詳細は、DTMI検証拡張機能リファレンスを参照してください

デバイス入力の例

ユニット固有のスキーマを含む一般的な受信ペイロード:

米国標準単位マイル/時:

{
  "speed": 60
}

ヨーロッパのメトリック単位キロメートル/時:

{
  "velocity_kph": 110
}

センサーからのネストされたペイロード:

{
  "telemetry": { "temp_c": 22.4, "humidity": 48 }
}

サンプルの配列:

{
  "samples": [ { "kph": 30 }, { "kph": 50 }, { "kph": 0 } ]
}

これらの例は、温度が0 - 100の範囲内の整数で、湿度がオプションであるDTDLモデルを示しています。

両方の値が存在し、温度が許容範囲および正しいタイプの範囲内にある場合、有効であり、完全な入力値が取り込まれます:
{ "temperature": 60, "humidity": 45 }
値が不在の場合、有効なデータのみが取り込まれます。この例では、温度がないため、湿度が取り込まれ、温度値は更新されません。
{
"humidity": 45
}
値がnullの場合、値は無視され、有効な値のみが取り込まれます。
{
		“temperature”: null
 		“humidity”: 45
	}

エンベロープ・マッピング

envelope.jsonは、referenceEndpointおよびreferencePayloadを宣言します。オプションで、エンベロープ・マッピングでtime-observedを設定できます。

{
  "referenceEndpoint": "telemetry/automotive/standard",
  "referencePayload": {
    "dataFormat": "JSON",
    "data": { "speed": 65 }
  }
}
ノート

デバイスがtimeを省略すると、プラットフォームによって特別な識別子receivedTimeが提供される場合があります。エンベロープ・マッピングが指定され、timeObservedが含まれている場合は、receivedTimetimeObserved値として使用されます。

ルート条件パターン

ルート条件は、受信メッセージまたはリクエストに適用するマッピング・ルールまたは処理ルールを決定するために使用されるルールまたは式です。ルート条件がtrueと評価されると、関連するマッピングまたは変換ルールがトリガーされて適用されます。

この例では、デジタル・ツイン・アダプタのルート条件によって、受信デバイス・メッセージを処理するための2つのルートが定義されます。たとえば、エンドポイント・パスの3番目のセグメントでメトリック単位を受信した場合、/vehicle/speed/metric-units/のようにデータの形式に基づいて、

[
  {
    "description": "European metric to mph; convert then floor (no explicit cast).",
    "condition": "${endpoint(3) == \"metric-units\"}",
    "payloadMapping": {
      "$.speed": "${(.velocity_kph / 1.609) | floor}"
    },
    "referencePayload": {
      "dataFormat": "JSON",
      "data": { "velocity_kph": 104 }
    }
  },
  {
    "description": "USA standard units passthrough.",
    "condition": "*",
    "payloadMapping": { "$.speed": "$.speed" }
  }
]
  • endpoint(n)は、n-thパス・セグメントを選択します(アダプタに応じて0ベースまたは1ベース)。測定単位の正規化シナリオでは、/vehicle/speed/metric-units/が3番目のセグメントmetric-unitsと一致するようにendpoint(3)が使用されます。
  • より具体的な条件を"*"キャッチオールより前に配置します。
  • payloadMapping:
    • フィールドvelocity_kph速度(キロメートル/時)をペイロードから取得し、それをマイル/時に変換します: .velocity_kph / 1.609
    • floorを適用して、floorがキャストしない最も近い整数に切り捨てるため、結果は浮動小数になる可能性があります。
    • 結果は、出力フィールドspeedに割り当てられます。
  • referencePayload:
    • このルートの予期される入力を示します: {"velocity_kph": 104}
  • 入力エンドポイント: /vehicle/speed/metric-units/device123
  • 入力ペイロード: { "velocity_kph": 104 }出力マッピング: { "speed": 64 } (since 104 / 1.609 = 64.64, floor is 64)

ペイロード・マッピングの例

ペイロード・マッピングの一般的なJQ式:

  • パススルー: "$.speed": "$.speed"
  • キー名の変更: "$.speed": "${.velocity_kph}"
  • 単位変換: "$.mph": "${.kph / 1.609}"
  • フロア/天井/ラウンド: "${.x | floor}""${.x | ceil}""${.x | round}"
  • Coalesce/default (バージョンに依存): "${ if .value? then .value else 0 end }"
  • 型変換:
    • To number: "${.value | tonumber}" (ほとんどのビルドでtonumberをサポート)
    • 文字列: "${.value | tostring}"
    ノート

    IoTデジタル・ツイン・アダプタでは、toIntegernumberなどのキャスト関数は、inbound-routesでは受け入れられません。整数スキーマに定義されたfloorで算術を使用するか、ダウンストリーム・データの取込みにschema: "double"および丸め形式を使用できます。inbound-routesは有効なJSONである必要があります。式は引用符付き文字列"${ ... }"内に属します。
  • ネストされた抽出: "${.telemetry.temp_c}"
  • 配列マップ: "${[ .samples[] | .kph / 1.609 | floor ]}"
  • 条件付き: "${ if .kph > 0 then .kph / 1.609 else 0 end }"
ノート

アダプタの統合によっては、引用符"${...}"内の式が文字列としてシリアライズされることがあります。エンジンで引用符なしの式(たとえば、RAW値として${...})がサポートされる場合、文字列ではなくJSON番号を出力する形式を推奨します。

ニュアンス: 整数型、文字列、計算された数値

DTDLプロパティがschema: "integer"の場合、正規化された出力は整数型である必要があります。値を計算する場合の一般的な2つの障害モード:

  1. 文字列化: 引用符で囲まれた式は、"68" (文字列)を生成し、整数の検証に失敗する可能性があります。
  2. 浮動小数点数: 算術は68.0を生成します。一部のバリデータでは、数学的に整数であっても、これを非整数として扱います。

パターンの修正:

  • 整数スキーマにfloorのみを使用: "${(.velocity_kph / 1.609) | floor}"は、整数型指定を満たす整数値を生成します。
  • 代替: モデル・プロパティをschema: "double"に切り替えて小数精度を保持するか、floorをマッピングに適用して整数をdoubleとして格納します。必要に応じてAPEX/SQLでラウンド/フォーマットします。

デジタル・ツイン・アダプタ・マッピングの例

この例では、floor (キャストなし)を使用して、時速キロメートル(KPH)を時速マイル(MPH)に正規化します。

{
  "description": "European auto uses metric units; convert to mph and floor to whole number.",
  "condition": "${endpoint(3) == \"metric-units\"}",
  "payloadMapping": {
    "$.speed": "${(.velocity_kph / 1.609) | floor}"
  },
  "referencePayload": {
    "dataFormat": "JSON",
    "data": { "velocity_kph": 104 }
  }
}

例: デフォルトのキャッチオール・パススルー

{
  "description": "English units passthrough.",
  "condition": "*",
  "payloadMapping": {
    "$.speed": "$.speed"
  }
}

例: ネストされた遠隔測定および結合のデフォルト

{
  "description": "Extract nested temp; default to 0 when missing.",
  "condition": "${endpoint(2) == \"env\"}",
  "payload-mapping": {
    "$.room_temp_c": "${ if .telemetry.temp_c? then .telemetry.temp_c else 0 end }"
  }
}

例: 配列正規化

{
  "description": "Normalize kph samples to mph (whole-number mph via floor).",
  "condition": "${.samples?}",
  "payload-mapping": {
    "$.speeds": "${ [ .samples[] | .kph / 1.609 | floor ] }"
  }
}

出力予想とモデル検証

出力は、デジタル・ツイン・モデルのスキーマおよび制約を満たす必要があります。model.jsonの自動車ユニット・モデルについては、シナリオ: デジタル・ツイン・アダプタを使用した測定単位の正規化を参照してください。

  • name: speed
  • schema: integer
  • unit: milePerHour
  • minimum: 0, maximum: 100

正規化されたspeedは、0,100内の整数である必要があります。計算された文字列"68"または浮動小数点数68.0は検証に失敗します。

制限事項とヒント

  • フィルタの可用性は様々: ほとんどのコアjqフィルタ(floorceilroundtonumbertostringmapselectadd)
  • Type emission: 引用符で囲まれた文字列に埋め込まれた式は、文字列としてシリアライズできます。数値型の出力がサポートされている場合は、引用符なしのRAW式を優先します。
  • NULL処理: nullに対する操作では、nullが生成される場合があります。防御のデフォルトには、if .x? then ... else ... endを使用します。
  • 精度: 浮動小数点演算では、端数処理アーティファクトを導入できます。キャストする前に、必要に応じてroundおよびfloorを適用します。
  • 整数のキャスト: 監視されたテストでは、アダプタの作成時にinbound-routestoIntegerおよびnumberが受け入れられませんでした。整数スキーマの場合は算術+ floorを優先するか、schema: "double"を使用してフォーマットを下流に丸めます。

自動車シナリオへの整数の修正の適用

このシナリオでは、整数speedのモデルを作成し、メトリック・ユニット・ペイロードを同じデジタル・ツイン・モデルにルーティングします。明示的なキャストがないと、型ドリフト(文字列または浮動小数点数)のために、計算された値を検証によって拒否できます。

シナリオで使用された修正:

"$.speed": "${(.velocity_kph / 1.609) | floor}"

IDRが必要な理由:

  • floorは、整数の入力を満たす整数の値であることを確認します。
  • 代替方法: schema: "double"を使用して、小数精度を保持し、必要に応じて下流に丸めて書式設定します。
ノート

整数スキーマを使用する場合は、算術+floorを優先します。doubleスキーマの場合、floorを省略して小数MPHを保持するか、整数MPHをdoubleとして格納するように含めることができます。

クイック参照スニペット

サポートされる例:

  • 条件: エンドポイント一致: "condition": "${endpoint(3) == \"metric-units\"}"
  • マッピング: パススルー: "$.speed": "$.speed"
  • マッピング: kph→mph (整数スキーマ): "$.speed": "${(.kph / 1.609) | floor}"
  • マッピング: ネスト: "$.room_temp_c": "${.telemetry.temp_c}"
  • マッピング: デフォルト: "$.value": "${ if .value? then .value else 0 end }"
  • 配列変換: "$.list": "${ [ .arr[] | .x | tonumber ] }"

整数と二重モデルの動作

この項では、モデル・スキーマ・タイプがアダプタのマッピングおよび検証に与える影響の概要を示します。

  • スキーマ: "integer"
    • タイプ: 整数JSON数値である必要があります。68や浮動小数点のような結果68.0などの文字列は、整数検証に失敗する可能性があります。
    • マッピング: 算術を使用できます。floorがサポートされています。toIntegernumberなどの関数はサポートされません。
    • パターン: "${(.velocity_kph / 1.609) | floor}"を使用して、MPHを統合します。これは検証に合格し、テレメトリはHTTP 202として受け入れられました。
    • 範囲: 最小値と最大値が強制されます(たとえば、0–100)。
  • schema: "double"
    • タイプ: 範囲内であれば、任意のJSON数値整数または小数を使用できます。プラットフォームによって自動丸めは実行されません。
    • マッピング: "${.velocity_kph / 1.609}"などの小数精度を保持することも、floorを適用してdoubleとして格納された整数MPHを生成することもできます(例: 68.0)。
    • 範囲: 定義されている場合、最小および最大が強制されます。例: 0–100

観測されたテレメトリ結果

次の組合せがエンドツーエンド(HTTP/1.1 202 Accepted)で検証されました。

  • 整数モデル+フロア・マッピング: "${(.velocity_kph / 1.609) | floor}"→ 受け入れられました
  • ダブル・モデルとRAWマッピング: "${.velocity_kph / 1.609}"→ 許容される小数mph
  • ダブル・モデル+フロア・マッピング: "${(.velocity_kph / 1.609) | floor}"→ 整数mphがdoubleとして受け入れられ、格納されました

カールの例(プレースホルダ)

二重モデル、期待どおりの小数mphのRAW値:

curl -i -X POST \
  -u "european-auto-raw:secret-or-certificate-ocid" \
  -H "Content-Type: application/json" \
  "https://device-host/telemetry/automotive/metric-units" \
  -d '{ "velocity_kph": 110 }'

ダブルモデル、ダブルとして保存されている整数MPHを床に:

curl -i -X POST \
  -u "european-auto-dfloor:secret-or-certificate-ocid" \
  -H "Content-Type: application/json" \
  "https://device-host/telemetry/automotive/metric-units" \
  -d '{ "velocity_kph": 110 }'

各ケースの予想HTTPレスポンス:

HTTP/1.1 202 Accepted
content-type: text/plain

Accepted

APEXまたはSQLのダウンストリームに関する考慮事項

  • doubleの場合、分数の速度は維持されます。整数表示にはSQL FLOOR/ROUNDを使用します。
    SELECT FLOOR(speed) AS speed_mph FROM ...
  • integerでは、マッピングで検証を満たすために整数値が(たとえば、floorを介して)出力されることを確認します。

承認ユーザー名および見積り

OCI IoTでは、Basic認証ユーザー名を使用すると、インスタンスexternal-keyと等しくなります。インスタンスが外部キーに埋め込まれた引用符で作成されている場合、それらの引用符は必要なユーザー名の一部となり、文字どおりに送信される必要があります。これはシェル引用の問題を引き起こすことがよくあります。

ベスト・プラクティス: 引用符を含めない外部キーでデジタル・ツイン・インスタンスを作成します(例: american-auto)。引用符で囲まれたユーザー名で認証する必要がある場合は、-uを使用せずにAuthorization: Basic ...ヘッダーを構築して、引用符のエラーを回避します。