Scenario: normalizzazione delle unità di misura mediante un adattatore Digital Twin
Questo scenario spiega come utilizzare un modello digital twin, un adattatore digital twin con mapping di envelope e instradamento per normalizzare una telemetria specifica in uno schema comune e come convalidare il flusso pubblicando payload di dispositivi di esempio.
Questo scenario dimostra come pubblicare i dati di telemetria automobilistica con diverse unità di misura per miglia all'ora e chilometri all'ora utilizzando endpoint diversi, due istanze gemelle digitali e due chiavi esterne diverse. Per ulteriori informazioni sui pattern JQ a cui viene fatto riferimento in questo scenario, vedere Riferimento: Espressioni JQ per adattatori gemelli digitali
Un adattatore digital twin installa le richieste in base all'endpoint e mappa i payload in un singolo modello. Ad esempio, il modello di metrica invia la velocità in chilometri orari (velocity_kph) mentre un'altra istanza gemella digitale standard invia miglia all'ora (speed).
Task
Prima di iniziare
Assicurarsi di disporre delle autorizzazioni necessarie e che l'interfaccia CLI OCI sia configurata. Per ulteriori informazioni, vedere Prerequisiti, Dettagli dei criteri per la piattaforma Internet of Things (IoT) e Uso di un file JSON per input complessi.
Comprendere i file in questo scenario:
Frammenti di codice che puoi utilizzare nel tuo modello gemello digitale a cui si fa riferimento nei passaggi seguenti:
model.json: modello gemello digitale basato sulle specifiche DTDL v3 con una proprietà di telemetriaspeedin miglia all'ora che utilizza un'estensione di convalida che applica limiti all'intervallo di valori compreso tra 0 e 100.envelope.json: configurazione dell'envelope che dichiara un endpoint di riferimento e una forma di payload di esempio.routes.json: condizioni di percorso e mappature del payload che convertono chilometri all'ora in miglia all'ora.script.sh: in questo esempio, è possibile salvare tutti i comandi CLI OCI elencati di seguito per creare un modello gemello digitale, un adattatore e istanze, oltre ai comandicurlnella telemetria di esempio POST, quindi eseguirli come script shellscript.sh.Per completare i passi di questo scenario, è possibile creare e salvare l'interfaccia CLI OCI e i comandi
curlelencati nei passi riportati di seguito e eseguire questo scenario come script della shell:script.sh
Questo snippet di codice model.json del modello digital twin di esempio utilizza un'estensione personalizzata dtmi:com:oracle:dtdl:extension:validation;1 che applica le regole di convalida allo schema JSON per gli elementi "Telemetry", "Historized", "Validated", "Velocity". Se i dati non corrispondono ai valori previsti definiti in questa convalida, i dati vengono rifiutati.
Per un elenco completo delle regole delle proprietà di convalida supportate, vedere Riferimento estensione convalida DTMI.
model.json
{
"@context":[
"dtmi:dtdl:context;3",
"dtmi:dtdl:extension:historization;1",
"dtmi:com:oracle:dtdl:extension:validation;1",
"dtmi:dtdl:extension:quantitativeTypes;1"
],
"@id":"dtmi:com:oracle:iot:poc:testmodel;1",
"@type":"Interface",
"contents":[
{
"@type":[ "Telemetry", "Historized", "Validated", "Velocity" ],
"displayName":"Speed",
"name":"speed",
"schema":"integer",
"unit":"milePerHour",
"minimum":0,
"maximum":100
}
]
}envelope.json
{
"referenceEndpoint": "telemetry/automotive/usa-standard-units",
"referencePayload": {
"dataFormat": "JSON",
"data": {
"speed": 65
}
}
}
routes.json elencato di seguito contiene 3 espressioni che trasformano i chilometri e normalizzano il payload dei dati in un'unità di misura, miglia all'ora:- Espressione di condizione che valuta i dati dall'endpoint:
"condition" : "${endpoint(3) == \"metric-units\"}"La sintassi
${ ... }indica un'espressione che valuta il valore del terzo parametro endpoint o elemento percorso in una chiamata APIendpoint(3). La condizione confronta il valore restituito conmetric-units. Se è vero, allora applica queste regole. - Espressione mapping payload:
"payloadMapping" : { "$.speed": "${(.velocity_kph / 1.609) | floor}"}La sintassi
${ ... }indica un'espressione, questa espressione valuta ed esegue un calcolo aritmetico per convertire la velocità da chilometri all'ora a miglia all'ora(.velocity_kph / 1.609), dividendo il campovelocity_kphper1.609e quindi applicando la funzione floor, arrotondando per difetto all'intero più vicino. Questo valore deriva dalla conversione di chilometri in miglia che è chilometri = miglia × 1.60934, "payloadMapping": {"$.speed": "$.speed"}Si tratta di un'espressione di mapping di valore diretto che passa attraverso il valore della velocità così com'è.
[
{
"description" : "Automotive data using metric units (kilometers) that's converted to miles, with a different external key in the digital twin instance",
"condition" : "${endpoint(3) == \"metric-units\"}",
"payloadMapping" : {
"$.speed": "${(.velocity_kph / 1.609) | floor}"
},
"referencePayload" : {
"dataFormat" : "JSON",
"data" : { "velocity_kph": 104 }
}
},
{
"description" : "Auto 1 and Auto 2 use USA standard units, shows speed as is.",
"condition" : "*",
"payloadMapping" : { "$.speed": "$.speed" }
}
]
Passo 1: Creare un modello Digital Twin
Utilizzare questo comando CLI oci iot digital-twin-model create per creare un modello gemello digitale utilizzando il file model.json. Questo modello digital twin standardizza speed in miglia all'ora.
Questo comando registra il modello digital twin con questo URI DTMI dtmi:com:oracle:iot:poc:testmodel;1 come definito nella menzione model.json sopra riportata.
oci iot digital-twin-model create \
--iot-domain-id <iot-domain-ocid> \
--display-name "Test Digital Twin Model" \
--description "Model for testing automotive telemetry routing and unit normalization" \
--spec file://~/model.json
Passaggio 2: creare un adattatore Digital Twin con busta e percorsi
Creare un adattatore che faccia riferimento alla specifica DTMI del modello gemello digitale e che utilizzi l'inviluppo e gli instradamenti in entrata per normalizzare la telemetria in entrata.
oci iot digital-twin-adapter create \
--iot-domain-id <iot-domain-ocid> \
--display-name "automotive-speed-adapter" \
--description "Routes by units" \
--digital-twin-model-spec-uri "dtmi:com:oracle:iot:poc:testmodel;1" \
--inbound-envelope file://~/envelope.json \
--inbound-routes file://~/routes.json
referenceEndpoint in envelope.json è telemetry/automotive/usa-standard-units. Il file routes.json:
- Esegue l'instradamento delle richieste al terzo segmento di percorso che equivale a
metric-units, ad esempio/telemetry/automotive/metric-units, quindi convertevelocity_kphinspeedin mph e ne pianifica il risultato. - Utilizza una condizione predefinita di catch-all (
*) per passare attraversospeedinvariato per le automobili che utilizzano miglia all'ora.
Passo 3: Creare due istanze Digital Twin
- Endpoint per mph:
https://device-host/telemetry/automotive/usa-standard-units - Endpoint per kph:
https://device-host/telemetry/automotive/metric-units
Quando si creano un'istanza gemella digitale con l'autenticazione, è possibile utilizzare un segreto vault o un certificato mTLS per l'autenticazione. Per motivi di sicurezza, è consigliabile creare un segreto vault o un certificato mTLS univoco per ogni istanza digital twin. Tutte le risorse devono trovarsi nella stessa area e tenancy di qualsiasi altra risorsa IoT correlata.
Se si utilizza un certificato mTLS per l'autenticazione, è necessario utilizzare il nome comune del certificato come chiave esterna: --external-key <common-name-from-certificate-details>. Vedere Scenario: Create a Digital Twin Instance that using a mTLS Certificate.
Un amministratore deve aggiungere il criterio per la creazione di segreti o certificati. Vedere il Passo 3 in Prerequisiti.
Istanza digital twin per unità standard USA, miglia all'ora (mph), nota la chiave esterna:
american-auto-standard-unitsoci iot digital-twin-instance create \
--iot-domain-id <IoT-domain-ocid> \
--display-name "auto using miles per hour" \
--external-key american-auto-standard-units \
--digital-twin-adapter-id <same-digital-twin-adapter-ocid> \
--auth-id <secret-ocid-or-certificate-ocid>Istanza gemella digitale per le unità metriche europee, chilometri all'ora (kph), nota la chiave esterna: european-auto-metric-units
oci iot digital-twin-instance create \
--iot-domain-id <IoT-domain-ocid> \
--display-name "auto using kilometers per hour" \
--external-key european-auto-metric-units \
--digital-twin-adapter-id <same-digital-twin-adapter-ocid> \
--auth-id <secret-ocid-or-certificate-ocid>
Passo 4: inviare la telemetria di esempio per convalidare l'instradamento e il mapping
Per inviare la telemetria è necessaria la chiave esterna della risposta dell'istanza gemella digitale dal passo 3, dalla password del dispositivo e dall'endpoint dell'host del dispositivo.
Se l'istanza digital twin utilizza il segreto vault per l'autenticazione, è necessario utilizzare come password del dispositivo il valore segreto con codifica Base 64.
- Chiave esterna: sostituire
external-keyconexternal-keydall'istanza gemello digitale con cui si desidera lavorare. Per evitare di citare i problemi, è consigliabile non utilizzare le virgolette nel valore della chiave esterna. - Password dispositivo: sostituire la password del dispositivo con il contenuto dei segreti testo semplice o il certificato mTLS.
- Host dispositivo: sostituire
device-hostcon l'host dispositivo dal dominio IoT. Per ottenere l'URL dell'endpoint host del dispositivo per il dominio IoT, vedere Recupero dei dettagli di un dominio IoT.
-u "external-key:device-password-secret-contents-or-certificate"
A seconda del sistema operativo o dell'applicazione, alcune applicazioni o editor di codice possono aggiungere preventivi indesiderati ai valori, questo può causare un errore. Per gli esempi di citazione, vedere Risoluzione dei problemi.
curl -i -X POST \
-u "european-auto-metric-units:device-password-secret-or-certificate" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/metric-units" \
-d '{ "velocity_kph": 0 }'curl -i -X POST \
-u "european-auto-metric-units:device-password-secret-or-certificate" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/metric-units" \
-d '{ "velocity_kph": 110 }'
curl -i -X POST \
-u "american-auto-standard-units:device-password-secret-or-certificate" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/usa-standard-units" \
-d '{ "speed": 0 }'
curl -i -X POST \
-u "american-auto-standard-units:device-password-vault-secret-base-64-or-certificate-OCID" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/usa-standard-units" \
-d '{ "speed": 60 }'
Passo 5: verifica del comportamento di normalizzazione
La condizione di instradamento ${endpoint(3) == "metric-units"} valuta i dati e applica il seguente mapping di payload all'endpoint dati delle unità di metrica:
"$.speed": "${(.velocity_kph / 1.609) | floor}"
Risultato previsto:
- Il mapping dell'adattatore converte i chilometri orari (kph) in miglia orarie (mph), quindi applica il piano per soddisfare uno schema di numeri interi:
speed_mph = floor(velocity_kph / 1.609) - In questo esempio,
velocity_kph = 0: speed_mph = floor(0 / 1.609) = floor(0) = 0 mphDopo il piano indica il passo di arrotondamento che forza il risultato a un numero intero, arrotondando verso il basso verso l'infinito negativo. Questo valore è obbligatorio quando il modello DTDL dichiara la telemetria di velocità come
schema: "integer", quindi il valore è un numero intero, non un float o una stringa. velocity_kph = 110→speed = floor(110 / 1.609) = 68mph- I post dati standard con
speedpassano invariati, ad esempio i valori di questo esempio:0,60
Se la convalida del modello è abilitata per minimum: 0, maximum: 100, i valori fuori intervallo vengono rifiutati in base alle regole di convalida.
Utilizza conversione tipo flessibile:
- Pass-through (mph, schema "integer"):
{"speed": "60"}e{"speed": 60.0}vengono memorizzati come60.{"speed": "60.2"}viene rifiutato a meno che il mapping delle coercizioni a un numero intero (ad esempio, confloor). - Instradamento metrica (kph → mph):
{"velocity_kph": 110}→68;{"velocity_kph": "110"}→68perché il mappingflooremette un numero intero. Mantenere gli input aritmetici numerici per evitare errori di espressione; preferire110rispetto a"110", se possibile. - L'arrotondamento rimane esplicito: la conversione flessibile non arrotonda automaticamente
68.35a68. Usarefloorper lo schema di numeri interi oppure passare al modelloschema: "double"per conservare le frazioni.
Procedure ottimali
- Riferimento dei file JSON per le specifiche e gli adattatori dei modelli gemelli digitali: quando si carica un adattatore utilizzando l'interfaccia CLI, è possibile utilizzare i file JSON per specificare il mapping dei dati. Nei comandi della CLI è possibile fare riferimento ai file come
file://~/name.jsono fornire un percorso assoluto o relativo a seconda dell'ambiente della shell. A seconda del sistema operativo in uso, è possibile che la sintassi del file sia leggermente diversa tra virgolette, barre o posizione. Vedere Gestione dell'input e dell'output CLI e Utilizzo di un file JSON per l'input complesso. - I file di configurazione JSON (envelope, instradamenti) utilizzano i nomi dei campi API in
camelCase(ad esempio,referenceEndpoint). L'interfaccia CLI OCI trasmette questi file tramite gli argomentifile://invariati, pertanto è previsto l'uso di JSON camelCase con CLI e è corretto. referenceEndpointinenvelope.jsondeve riflettere un endpoint tipico per l'adattatore.- La condizione di instradamento con caratteri jolly (
*) viene valutata dopo condizioni specifiche; ordinare di conseguenza le definizioni di instradamento. - Ambito di conversione soft: le stringhe di tipo numerico e le doppie numeriche vengono accettate quando corrispondono al tipo di modello (ad esempio, numero intero). Gli aiutanti di casting come
number()etoIntegerrimangono non supportati nelle espressioni di instradamento; si basano sull'aritmetica e suflooro adottanoschema: "double"per preservare le frazioni.
Variazione: viene utilizzato schema="double" anziché floor
Questa variazione mostra come l'impostazione dello schema delle proprietà del modello su double influisce sul mapping dell'adattatore e sui valori registrati. Con double, il validatore accetta qualsiasi valore integrale o frazionario numerico che soddisfi i vincoli di intervallo, senza arrotondamento automatico. È possibile scegliere di preservare la precisione frazionaria (raw) o di forzare numeri interi utilizzando floor. Entrambe passano la convalida finché i valori rimangono all'interno dell'intervallo definito.
Cosa fa la convalida schema=double
- Accettazione del tipo: accetta numeri JSON con o senza parti frazionarie, ad esempio: 60, 68.35. Le stringhe come
"68"rimangono non valide. - Intervallo: vengono applicati i valori minimo e massimo, ad esempio, in questo esempio
0–100. - Nessun arrotondamento automatico: la piattaforma IoT non arrotonda i valori; è possibile controllare l'arrotondamento nel mapping dell'adattatore digital twin o a valle utilizzando APEX o SQL a seconda dei sistemi configurati per visualizzare i dati.
File utilizzati in questa variazione:
model_double.json: modello DTDL conschema: "double".{ "@context": [ "dtmi:dtdl:context;3", "dtmi:dtdl:extension:historization;1", "dtmi:com:oracle:dtdl:extension:validation;1", "dtmi:dtdl:extension:quantitativeTypes;1" ], "@id": "dtmi:com:oracle:iot:poc:testmodeldouble;1", "@type": "Interface", "contents": [ { "@type": [ "Telemetry", "Historized", "Validated", "Velocity" ], "displayName": "Speed", "name": "speed", "schema": "double", "unit": "milePerHour", "minimum": 0, "maximum": 100 } ] }routes_double_raw.json- La mappatura conserva la precisione frazionaria:"$.speed": "${.velocity_kph / 1.609}".[ { "description": "Double model: European metric units to miles per hour (mph); preserving fractional precision (no floor).", "condition": "${endpoint(3) == \"metric-units\"}", "payloadMapping": { "$.speed": "${.velocity_kph / 1.609}" }, "referencePayload": { "dataFormat": "JSON", "data": { "velocity_kph": 110 } } }, { "description": "Double model: USA standard units passthrough.", "condition": "*", "payloadMapping": { "$.speed": "$.speed" } } ]routes_double_floor.json- Mappatura delle coercizioni in mph a numero intero:"$.speed": "${(.velocity_kph / 1.609) | floor}"memorizzato come doppio.[ { "description": "Double model: European metric units to miles per hour (mph); floor to whole number (stored as double).", "condition": "${endpoint(3) == \"metric-units\"}", "payloadMapping": { "$.speed": "${(.velocity_kph / 1.609) | floor}" }, "referencePayload": { "dataFormat": "JSON", "data": { "velocity_kph": 110 } } }, { "description": "Double model: USA standard units passthrough.", "condition": "*", "payloadMapping": { "$.speed": "$.speed" } } ]
Passo A: Creare il modello digital twin utilizzando il doppio
oci iot digital-twin-model create \
--iot-domain-id iot-domain-ocid \
--display-name "TestModelSpeedDouble" \
--spec file://model_double.json
Passo B: Creare due adattatori associati al modello doppio
Utilizzare i valori raw per mantenere la precisione frazionaria:
oci iot digital-twin-adapter create \
--iot-domain-id iot-domain-ocid \
--display-name "auto-adapter-double-raw" \
--digital-twin-model-id double-model-ocid \
--inbound-envelope file://envelope.json \
--inbound-routes file://routes_double_raw.json
Floor utilizza un numero intero come mph, che è un doppio:
oci iot digital-twin-adapter create \
--iot-domain-id iot-domain-ocid \
--display-name "auto-adapter-double-floor" \
--digital-twin-model-id double-model-ocid \
--inbound-envelope file://envelope.json \
--inbound-routes file://routes_double_floor.json
Passo C: creare istanze digital twin per ogni adattatore
oci iot digital-twin-instance create \
--iot-domain-id iot-domain-ocid \
--display-name "american-auto-raw" \
--external-key american-auto-raw \
--digital-twin-adapter-id adapter-double-raw-ocid \
--auth-id vault-secret-ocid
oci iot digital-twin-instance create \
--iot-domain-id iot-domain-ocid \
--display-name "european-auto-raw" \
--external-key european-auto-raw \
--digital-twin-adapter-id adapter-double-raw-ocid \
--auth-id vault-secret-ocid
oci iot digital-twin-instance create \
--iot-domain-id iot-domain-ocid \
--display-name "american-auto-dfloor" \
--external-key american-auto-dfloor \
--digital-twin-adapter-id adapter-double-floor-ocid \
--auth-id vault-secret-ocid
oci iot digital-twin-instance create \
--iot-domain-id iot-domain-ocid \
--display-name "european-auto-dfloor" \
--external-key european-auto-dfloor \
--digital-twin-adapter-id adapter-double-floor-ocid \
--auth-id vault-secret-ocid
Passo D: inviare la telemetria di esempio e confrontare i risultati
-u "external-key:device-password" \- Se il gemello digitale utilizza il segreto del vault per l'autenticazione, utilizzare
base64-secretcome password del dispositivo. - Se l'istanza digital twin utilizza una certificazione mLTS, utilizzare
certificate-ocidcome password del dispositivo.
Valori non elaborati (double, no floor):
curl -i -X POST \
-u "american-auto-raw:device-password" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/usa-standard-units" \
-d '{ "speed": 60 }'
curl -i -X POST \
-u "european-auto-raw:device-password" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/metric-units" \
-d '{ "velocity_kph": 110 }'
Risultato previsto: il secondo post produce circa 68.35… mph (frazionario) ed è accettato perché schema=double accetta numeri frazionari compresi nell'intervallo.
Piano (doppio, con pavimento):
curl -i -X POST \
-u "american-auto-dfloor:device-password" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/usa-standard-units" \
-d '{ "speed": 60 }'
curl -i -X POST \
-u "european-auto-dfloor:device-password" \
-H "Content-Type: application/json" \
"https://device-host/telemetry/automotive/metric-units" \
-d '{ "velocity_kph": 110 }'
Risultato previsto: il secondo post produce 68 come numero intero ed è accettato. Il valore viene memorizzato come valore doppio, ad esempio 68.0, anche se è un numero intero.
Note sulle virgolette dei nomi utente e sull'impatto a valle
- La chiave esterna equivale al nome utente di autenticazione: se un'istanza digital twin viene creata utilizzando virgolette nel valore della chiave esterna, ad esempio
"\"american-auto-standard-units\"", il nome utente di autenticazione di base nella richiestacurldeve includere le virgolette oppure si verifica una mancata corrispondenza e si verifica un errore401 Unauthorized. Per evitare di citare i problemi, è consigliabile non utilizzare le virgolette nel valore della chiave esterna come negli esempi di questo scenario. - A valle in APEX o utilizzando SQL: con
schema=double, i valori mph frazionari vengono conservati. Se sono necessari numeri interi nei report, applicareFLOOReROUNDin SQL, ad esempioSELECT FLOOR(speed) FROM …. Conschema=integer, assicurarsi che il mapping emetta valori integrali, ad esempio, utilizzandofloorper soddisfare la digitazione di numeri interi. - Supporto per le espressioni:
inbound-routeaccetta aritmetica efloor. Funzioni cometoIntegeronumbersono state rifiutate e non sono supportate; utilizzareflooro adottareschema: "double"per l'accettazione frazionaria.