Riferimento: Espressioni JQ per adattatori gemelli digitali
Modelli di espressione JQ pratici per gli input del dispositivo, gli involucri dell'adattatore, le condizioni di instradamento e i mapping del payload per normalizzare la telemetria in ciò che è definito nei modelli gemelli digitali.
Concetti chiave
È possibile scrivere espressioni JQ all'interno di un adattatore digital twin come segnaposto ${ ... } per calcolare i valori di destinazione in payload-mapping e per valutare le condizioni di instradamento.
Modi comuni per utilizzare le espressioni JQ:
- Input dispositivo: payload raw inviati dai dispositivi.
- Sviluppo: dichiara gli endpoint di riferimento e le forme di payload di esempio, ad esempio è possibile definire il mapping
timeObserved. - Cicli: valuta le condizioni, inclusi endpoint, intestazioni, corpo e seleziona un mapping di payload.
- Mapping payload: trasforma, converte unità, rinomina chiavi e normalizza nello schema del modello DTDL.
- Output: output JSON normalizzato che deve soddisfare la convalida del modello gemello digitale, inclusi tipi, intervalli, unità.
- Supporto delle funzioni di mapping: le funzioni aritmetica e
floorsono accettate. Funzioni qualitoIntegerenumbernon sono supportate. - Corrispondenza endpoint: utilizza condizioni basate su segmenti con
endpoint(n), ad esempio:${endpoint(1) == 'home' and endpoint(2) == 'sonnen' and endpoint(3) == 'status'}anziché pattern con caratteri jolly non supportati. - Confronto tra intero e doppio schema:
- Per
schema: "integer", assicurarsi che il mapping emetta numeri integrali (ad esempio,"${(.velocity_kph / 1.609) | floor}"). - Per
schema: "double", vengono accettati output frazionari. Utilizzarefloorsolo se si desidera che lo storage con numeri interi sia doppio, ad esempio 68.0.
- Per
- Tipo di conversione soft: le stringhe di tipo numerico e le doppie con numeri interi 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.- 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.
- Pass-through (mph, schema "integer"):
- Gestione di buste e tempi: se non viene fornito
timeObserved, la piattaforma può utilizzarereceivedTime. Utilizzarefromdateformat,todateformate le funzioni correlate per le conversioni temporali nei mapping di buste o payload.
La convalida dei dati viene eseguita in base al modello DTDL. Se una proprietà viene dichiarata come
integer, l'output normalizzato deve essere un valore integer, non un valore string o float. Vedere il pattern di correzione numero intero riportato di seguito.Per ulteriori informazioni, vedere Informazioni di riferimento sull'estensione per la convalida DMI
Esempi di input dispositivo
Payload in entrata tipici con schemi specifici dell'unità:
Unità standard USA miglia all'ora:
{
"speed": 60
}Unità metriche europee chilometri all'ora:
{
"velocity_kph": 110
}
Payload nidificato da un sensore:
{
"telemetry": { "temp_c": 22.4, "humidity": 48 }
}
Array di campioni:
{
"samples": [ { "kph": 30 }, { "kph": 50 }, { "kph": 0 } ]
}Questi esempi mostrano un modello DTDL in cui la temperatura è un numero intero compreso tra 0 e 100 e l'umidità è facoltativa.
{ "temperature": 60, "humidity": 45 }{
"humidity": 45
}{
“temperature”: null
“humidity”: 45
}Mapping buste
envelope.json dichiara un referenceEndpoint e un referencePayload. Facoltativamente, un mapping di buste può impostare time-observed:
{
"referenceEndpoint": "telemetry/automotive/standard",
"referencePayload": {
"dataFormat": "JSON",
"data": { "speed": 65 }
}
}
L'identificativo speciale
receivedTime può essere fornito dalla piattaforma quando il dispositivo omette time. Se il mapping dell'envelope viene specificato e contiene un valore timeObserved, receivedTime viene utilizzato come valore timeObserved. Pattern delle condizioni di instradamento
Le condizioni di instradamento sono regole o espressioni utilizzate per determinare quale regola di mapping o elaborazione deve essere applicata a un messaggio o a una richiesta in entrata. Se una condizione di instradamento restituisce true, la regola di mapping o trasformazione associata viene attivata e applicata.
In questo esempio, la condizione di instradamento digital twin adapter definisce due instradamenti per l'elaborazione dei messaggi dispositivo in entrata, in base al formato dei dati, ad esempio se vengono ricevute unità di metrica nel 3° segmento del percorso endpoint, /vehicle/speed/metric-units/ quindi
[
{
"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)seleziona il segmento di percorson-th(basato su 0 o 1 a seconda dell'adattatore). Nello scenario di normalizzazione delle unità di misura, viene utilizzatoendpoint(3)in modo che/vehicle/speed/metric-units/corrisponda al terzo segmentometric-units.- Porre condizioni più specifiche prima del
"*"catch-all. payloadMapping:- Prende la velocità del campo
velocity_kphin chilometri all'ora dal payload e la converte in miglia all'ora:.velocity_kph / 1.609 - Applica
floorper arrotondare al numero intero più vicinofloornon cast, pertanto il risultato potrebbe essere un float. - Il risultato viene assegnato al campo di output
speed.
- Prende la velocità del campo
referencePayload:- Dimostra l'input previsto per questo instradamento:
{"velocity_kph": 104}
- Dimostra l'input previsto per questo instradamento:
- Endpoint di input:
/vehicle/speed/metric-units/device123 - Payload di input:
{ "velocity_kph": 104 }Mapping di output:{ "speed": 64 } (since 104 / 1.609 = 64.64, floor is 64)
Esempi di mapping dei payload
Espressioni JQ comuni per i mapping del payload:
- Pass-through:
"$.speed": "$.speed" - Rinomina chiave:
"$.speed": "${.velocity_kph}" - Conversione unità:
"$.mph": "${.kph / 1.609}" - Pavimento/soffitto/rotondo:
"${.x | floor}","${.x | ceil}","${.x | round}" - Coalesce/default (dipendente dalla versione):
"${ if .value? then .value else 0 end }" - Conversione del tipo:
- Al numero:
"${.value | tonumber}"(supportatonumbernella maggior parte delle build) - Stringa - A:
"${.value | tostring}"
Nota
In un IoT adattatore gemello digitale, le funzioni di fusione cometoIntegeronumbernon sono accettate ininbound-routes. È possibile utilizzare l'aritmetica confloordefinito per uno schema con numeri interi oppure utilizzare i formatischema: "double"e di arrotondamento per l'inclusione dei dati a valle.inbound-routesdeve essere un JSON valido; le espressioni appartengono alle stringhe tra virgolette"${ ... }". - Al numero:
- Estrazione nidificata:
"${.telemetry.temp_c}" - Mappa array:
"${[ .samples[] | .kph / 1.609 | floor ]}" - Condizionale:
"${ if .kph > 0 then .kph / 1.609 else 0 end }"
A seconda dell'integrazione dell'adattatore, le espressioni all'interno delle virgolette
"${...}" possono essere serializzate come stringhe. Quando il motore supporta ad esempio espressioni senza virgolette, ${...} come valore raw, è consigliabile che il modulo emetta un numero JSON anziché una stringa.Nuances: tipi di numeri interi, stringhe e numeri calcolati
Se la proprietà DTDL è schema: "integer", l'output normalizzato deve essere di tipo intero. Due modalità comuni di errore durante il calcolo dei valori:
- Stringificazione: un'espressione racchiusa tra virgolette può generare
"68"(stringa), errore durante la convalida degli interi. - Numero a virgola mobile: l'aritmetica produce
68.0; alcuni convalidatori la considerano come un numero non intero, anche se matematicamente integrale.
Correggi pattern:
- Usa solo piano per lo schema con numeri interi:
"${(.velocity_kph / 1.609) | floor}"per produrre un numero integrale che soddisfi la digitazione di numeri interi. - Alternativa: consente di impostare la proprietà del modello su
schema: "double"per mantenere la precisione frazionaria oppure applicarefloornel mapping durante la memorizzazione di un numero intero come doppio. Arrotonda/formatta in APEX/SQL in base alle esigenze.
Esempi di mappatura dell'adattatore Digital Twin
Questo esempio normalizza chilometri all'ora (KPH) in miglia all'ora (MPH) utilizzando floor (senza cast).
{
"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 }
}
}
Esempio: pass-through catch-all predefinito
{
"description": "English units passthrough.",
"condition": "*",
"payloadMapping": {
"$.speed": "$.speed"
}
}
Esempio: telemetria nidificata e impostazione predefinita di coalesce
{
"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 }"
}
}
Esempio: normalizzazione degli array
{
"description": "Normalize kph samples to mph (whole-number mph via floor).",
"condition": "${.samples?}",
"payload-mapping": {
"$.speeds": "${ [ .samples[] | .kph / 1.609 | floor ] }"
}
}
Aspettative dell'output rispetto alla convalida del modello
Gli output devono soddisfare schemi e vincoli del modello gemello digitale. Per il modello di unità per il settore automobilistico in model.json, vedere Scenario: normalizzazione delle unità di misura mediante un adattatore Digital Twin:
name:speedschema:integerunit:milePerHourminimum:0,maximum:100
speed normalizzato deve essere un numero intero all'interno di 0,100. Una stringa calcolata "68" o un numero a virgola mobile 68.0 non riuscirà a eseguire la convalida.
Limitazioni e suggerimenti
- La disponibilità dei filtri varia: la maggior parte dei filtri jq di base (
floor,ceil,round,tonumber,tostring,map,select,add) - Emissione tipo: le espressioni incorporate nelle stringhe tra virgolette possono essere serializzate come stringhe. Preferire le espressioni senza virgolette raw se supportate per l'emissione di tipi numerici.
- Gestione nulla: le operazioni su
nullpossono produrrenull. Utilizzareif .x? then ... else ... endper le impostazioni predefinite difensive. - Precisione: l'aritmetica a virgola mobile può introdurre artifact di arrotondamento; applicare
roundefloorin base alle esigenze prima della fusione. - Integer cast: nei test osservati,
toIntegerenumbernon sono stati accettati ininbound-routesal momento della creazione dell'adattatore. Preferire l'aritmetica +floorper lo schema con numeri interi oppure utilizzareschema: "double"e arrotondare il formato a valle.
Applicazione della correzione numero intero allo scenario automobilistico
Lo scenario crea un modello con un numero intero speed e instrada i payload dell'unità metrica allo stesso modello gemello digitale. Senza un cast esplicito, il valore calcolato può essere rifiutato dalla convalida a causa della deviazione del tipo (stringa o numero a virgola mobile).
Correzione utilizzata nello scenario:
"$.speed": "${(.velocity_kph / 1.609) | floor}"
Perché è necessario:
- floor garantisce che il valore sia di tipo numero intero soddisfacente.
- Alternativa: utilizzare
schema: "double"per mantenere la precisione frazionaria e arrotondare e formattare a valle, se necessario.
Quando si utilizza uno schema con numeri interi, si preferisce aritmetica più
floor. Per il doppio schema, è possibile omettere floor per mantenere MPH frazionario o includerlo per memorizzare un numero intero MPH come doppio.Frammenti di riferimento rapidi
Esempi supportati:
- Condizione: corrispondenza endpoint:
"condition": "${endpoint(3) == \"metric-units\"}" - Mapping: pass-through:
"$.speed": "$.speed" - Mapping: kph → mph (schema intero):
"$.speed": "${(.kph / 1.609) | floor}" - Mapping: nidificato:
"$.room_temp_c": "${.telemetry.temp_c}" - Mapping: predefinito:
"$.value": "${ if .value? then .value else 0 end }" - Trasformazione dell'array:
"$.list": "${ [ .arr[] | .x | tonumber ] }"
Comportamento modello intero/doppio
In questa sezione viene descritto come il tipo di schema del modello influisce sul mapping e sulla convalida dell'adattatore.
- schema: "integer"
- Tipo: deve essere un numero JSON intero integrale. Le stringhe come
68o i risultati a virgola mobile68.0possono non riuscire nella convalida dei numeri interi. - Mapping: l'aritmetica è consentita;
floorè supportato. Funzioni qualitoIntegerenumbernon sono supportate. - Pattern: utilizzare
"${(.velocity_kph / 1.609) | floor}"per forzare a MPH integrale. Il componente aggiuntivo ha superato il processo di validazione e telemetriaHTTP 202. - Intervallo: vengono applicati i valori minimo e massimo, ad esempio
0–100
- Tipo: deve essere un numero JSON intero integrale. Le stringhe come
schema: "double"- Tipo: qualsiasi numero JSON integrato o frazionario viene accettato se compreso nell'intervallo; nessun arrotondamento automatico eseguito dalla piattaforma.
- Mapping: è possibile preservare la precisione frazionaria, ad esempio
"${.velocity_kph / 1.609}", oppure applicare anchefloorper produrre un numero intero MPH memorizzato come doppio, ad esempio68.0 - Intervallo: se definito, minimo e massimo applicati, ad esempio:
0–100
Risultati telemetria osservati
Le seguenti combinazioni sono state convalidate end-to-end (HTTP/1.1 202 Accepted):
- Modello intero + mappatura del pavimento:
"${(.velocity_kph / 1.609) | floor}"→ accettato - Modello doppio + mapping raw:
"${.velocity_kph / 1.609}"→ mph frazionario accettato - Mapping doppio modello + pavimento:
"${(.velocity_kph / 1.609) | floor}"→ numero intero mph accettato e memorizzato come doppio
Curl di esempio (placeholder)
Doppio modello, valore raw che è mph frazionario come previsto:
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 }'
Doppio modello, pavimento un numero intero MPH, che è memorizzato come doppio:
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 }'
Risposta HTTP prevista per ciascun caso:
HTTP/1.1 202 Accepted
content-type: text/plain
Accepted
Considerazioni a valle in APEX o SQL
- Con il comando double la velocità frazionaria viene mantenuta. Utilizzare SQL
FLOOR/ROUNDper la visualizzazione dei numeri interi:SELECT FLOOR(speed) AS speed_mph FROM ... - Con integer, assicurarsi che il mapping generi valori integrali (ad esempio, tramite
floor) per soddisfare la convalida.
Nome utente e preventivi autorizzazione
In OCI IoT, l'uso del nome utente di autenticazione Basic equivale all'istanza external-key. Se l'istanza viene creata con virgolette incorporate nella chiave esterna, tali virgolette diventano parte del nome utente richiesto e devono essere inviate letteralmente. Questo spesso causa problemi di citazione delle shell.
Procedura ottimale: creare istanze digital twin con chiavi esterne che non includono virgolette, ad esempio american-auto Quando è necessario eseguire l'autenticazione con nomi utente tra virgolette, creare un'intestazione Authorization: Basic ... anziché utilizzare -u per evitare errori di citazione.