Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo riferimento si applica sia ai flussi di dati che ai grafici del flusso di dati. Entrambi usano lo stesso linguaggio delle espressioni per le trasformazioni di mapping, filtro e arricchimento. I grafici del flusso di dati supportano anche trasformazioni di rami e finestre (accumulo), indicate se applicabile.
Variabili posizionale
La matrice di inputs ogni regola determina le variabili disponibili in expression. Il primo input diventa $1, il secondo diventa $2e così via.
| Ingressi dati | Expression | Result |
|---|---|---|
Position, Office |
$1 + ", " + $2 |
Concatena Posizione e Office con una virgola |
temperature |
cToF($1) |
Converte Celsius in Fahrenheit |
temperature, humidity |
$1 * $2 < 100000 |
Controlla una soglia rispetto a due campi |
Se viene specificato un solo input e non viene specificata alcuna espressione, il valore in corrispondenza dell'input viene copiato direttamente nell'output.
Operatori
Le espressioni supportano gli operatori seguenti, elencati dalla precedenza più alta alla più bassa:
| Precedenza | Operatori | Descrizione |
|---|---|---|
| 1 | ! |
NOT logico (unario) |
| 2 | ^ |
Elevamento a potenza |
| 3 |
*, /, % |
Moltiplicazione, divisione, modulo |
| 4 |
+, - |
Addizione/concatenazione di stringhe, sottrazione |
| 5 |
<, >, <=>= |
Confronto |
| 6 |
==, != |
Uguaglianza, disuguaglianza |
| 7 | && |
E logico |
| 8 | \|\| |
oppure logico |
L'operatore + concatena le stringhe quando almeno un operando è una stringa. Usare le parentesi per eseguire l'override della precedenza predefinita.
Esempi:
| Expression | Descrizione |
|---|---|
$1 * 2 ^ 3 |
Exponentiation first: $1 * 8 |
($1 * 2) ^ 3 |
Override tra parentesi: moltiplicare per primo |
-$1 * 2 |
Negazione prima, quindi moltiplica |
$1 > 100 && $2 > 200 |
Concatenare le condizioni con AND logico |
Funzioni predefinite
Funzioni di conversione unità
Queste funzioni accettano un singolo valore numerico e restituiscono un valore float.
| Funzione | Conversione | Formula |
|---|---|---|
cToF(value) |
Da Celsius a Fahrenheit | F = (C × 9/5) + 32 |
fToC(value) |
Da Fahrenheit a Celsius | C = (F - 32) × 5/9 |
psiToBar(value) |
Da PSI a bar | bar = PSI × 0.0689476 |
barToPsi(value) |
Da bar a PSI | PSI = bar / 0,0689476 |
inToCm(value) |
Pollici a centimetri | cm = in × 2,54 |
cmToIn(value) |
Centimetri a pollici | in = cm / 2,54 |
ftToM(value) |
Piedi a metri | m = ft × 0,3048 |
mToFt(value) |
Metri a piedi | ft = m / 0,3048 |
lbToKg(value) |
Sterline a chilogrammi | kg = lb × 0,453592 |
kgToLb(value) |
Chilogrammi a chili | lb = kg / 0,453592 |
galToL(value) |
Galloni statunitensi a litri | L = gal × 3.78541 |
lToGal(value) |
Litri a galloni statunitensi | gal = L / 3.78541 |
Funzioni di ridimensionamento e arrotondamento
| Funzione | Descrizione |
|---|---|
scale(value, srcLo, srcHi, dstLo, dstHi) |
Scala value in modo lineare dall'intervallo di origine all'intervallo di destinazione. Tutti e cinque gli argomenti devono essere numerici. |
round_n(value, decimals) |
Arrotonda un oggetto float al numero specificato di posizioni decimali (da 0 a 15). |
Funzioni matematiche
Queste funzioni provengono dalla libreria matematica predefinita.
| Funzione | Descrizione |
|---|---|
floor(value) |
Intero più grande minore o uguale a un numero |
round(value) |
Numero intero più vicino, arrotondamento a metà strada da 0,0 |
ceil(value) |
Intero più piccolo maggiore o uguale a un numero |
math::abs(value) |
Valore assoluto |
math::sqrt(value) |
Radice quadrata (restituisce NaN per numeri negativi) |
math::cbrt(value) |
Radice cubo |
math::ln(value) |
Logaritmo naturale |
math::log2(value) |
Logaritmo di base 2 |
math::log10(value) |
Logaritmo di base 10 |
math::log(value, base) |
Logaritmo con base arbitraria |
math::exp(value) |
e elevato alla potenza del valore |
math::exp2(value) |
2 elevato alla potenza del valore |
math::pow(base, exp) |
Alza la base alla potenza di exp |
math::cos(value) |
Coseno (radianti) |
math::sin(value) |
Seno (radianti) |
math::tan(value) |
Tangente (radianti) |
math::acos(value) |
Arccosine (restituisce radianti) |
math::asin(value) |
Arcsine (restituisce radianti) |
math::atan(value) |
Arctangent (restituisce radianti) |
math::atan2(y, x) |
Arcotangente a quattro quadranti (restituisce radianti) |
math::hypot(a, b) |
Lunghezza dell'ipotenusa dai lati a e b |
Funzioni stringa
| Funzione | Descrizione |
|---|---|
len(string) |
Lunghezza del carattere di una stringa o numero di elementi di una tupla |
str::to_lowercase(string) |
Converte in minuscolo |
str::to_uppercase(string) |
Converte in maiuscolo |
str::trim(string) |
Rimuove gli spazi vuoti iniziali e finali |
str::from(value) |
Converte un valore nella relativa rappresentazione di stringa |
str::substring(string, start, end) |
Estrae una sottostringa per indice di caratteri |
str::regex_matches(string, pattern) |
Restituisce true se la stringa corrisponde al modello regex. Disponibile solo nei grafici del flusso di dati. |
str::regex_replace(string, pattern, replacement) |
Sostituisce tutte le corrispondenze regex con la stringa di sostituzione. Disponibile solo nei grafici del flusso di dati. |
Funzioni condizionali e di raccolta
| Funzione | Descrizione |
|---|---|
if(condition, trueVal, falseVal) |
Restituisce trueVal quando la condizione è true; in caso contrario, falseVal |
min(values) |
Minimo di uno o più valori numerici o di una matrice |
max(values) |
Massimo di uno o più valori numerici o di una matrice |
contains(tuple, value) |
Restituisce true se la tupla contiene il valore |
contains_any(tuple, candidates) |
Restituisce true se la tupla contiene qualsiasi valore della tupla candidati |
typeof(value) |
Restituisce il tipo come stringa: "string", "float", "int", "boolean", "tuple"o "empty" |
Funzioni di aggregazione (solo trasformazioni di finestra)
Queste funzioni sono disponibili solo nelle regole di accumulo all'interno delle trasformazioni di finestra. Ognuno accetta una singola variabile posizionale.
| Funzione | Restituzioni | Comportamento della finestra vuota |
|---|---|---|
average($n) |
Media dei valori numerici | Error |
sum($n) |
Somma dei valori numerici | 0.0 |
min($n) |
Valore numerico minimo | Error |
max($n) |
Valore numerico massimo | Error |
count($n) |
Numero di messaggi in cui esiste il campo | 0 |
first($n) |
Primo valore nella finestra | Error |
last($n) |
Ultimo valore nella finestra | Error |
Per informazioni dettagliate sull'uso delle funzioni di aggregazione, vedere Aggregare i dati nel tempo.
Logica condizionale
Usare la funzione per diramare la if logica all'interno di un'espressione:
| Expression | Descrizione |
|---|---|
if($1 > 100, "high", "normal") |
Restituisce "alto" quando la temperatura supera 100 |
if($2 == (), $1, $1 * $2) |
Torna a $1 quando manca $2 |
if($1 > 5, true, false) |
Restituisce un valore booleano basato su una soglia |
Usare () (il valore vuoto) nei confronti per rilevare i campi mancanti.
Suggerimento
Se è necessario solo un fallback statico per un campo mancante, la ?? <default> sintassi è più semplice. Vedere Valori predefiniti. Riservare if per i casi in cui è necessario scegliere tra i valori calcolati.
Campi dei metadati
Leggere e scrivere nei metadati dei messaggi usando il $metadata. prefisso nei inputs campi o output di una regola. I riferimenti ai metadati vengono inseriti nel percorso del campo, non nell'espressione stessa.
Proprietà dei metadati
-
Argomento: funziona sia per MQTT che per Kafka. Contiene la stringa in cui è stato pubblicato il messaggio. Esempio:
$metadata.topic. -
Proprietà utente: in MQTT, si riferisce alle coppie chiave/valore in formato libero che un messaggio MQTT può contenere. Ad esempio, se il messaggio MQTT è stato pubblicato con una proprietà utente con la chiave "priority" e il valore "high", il
$metadata.user_property.priorityriferimento contiene il valore "high". Le chiavi delle proprietà utente possono essere stringhe arbitrarie e possono richiedere l'uso di caratteri di escape:$metadata.user_property."weird key"utilizza la chiave "chiave strana" (che contiene uno spazio). -
Proprietà di sistema: questo termine viene usato per ogni proprietà che non è una proprietà utente. Attualmente è supportata solo una singola proprietà di sistema:
$metadata.system_property.content_type, che legge la proprietà del tipo di contenuto del messaggio MQTT (se impostata). -
Intestazione: Questa è l'equivalente Kafka della proprietà utente MQTT. Kafka può usare qualsiasi valore binario per una chiave, ma i flussi di dati supportano solo chiavi stringa UTF-8. Esempio:
$metadata.header.priority. Questa funzionalità è simile alle proprietà utente.
| Campo | Descrizione |
|---|---|
$metadata.topic |
Argomento MQTT del messaggio |
$metadata.user_property.<key> |
Proprietà utente nel messaggio, identificata dalla chiave |
$metadata.system_property.content_type |
Proprietà di sistema del tipo di contenuto |
$metadata.header.<key> |
Valore dell'intestazione Kafka, identificato dalla chiave |
Leggere dai metadati
Per fare riferimento all'argomento di origine e a una proprietà utente in un'espressione, elencarli come input:
| Inserimento | Variabile |
|---|---|
$metadata.topic |
$1 |
$metadata.user_property.device_id |
$2 |
Espressione: $1 + "/" + $2
Nell'esempio seguente, la proprietà MQTT topic è mappata nel campo origin_topic nell'output.
| Inserimento | Risultato |
|---|---|
$metadata.topic |
origin_topic |
Se la proprietà priority utente è presente nel messaggio MQTT, l'esempio seguente illustra come eseguirne il mapping a un campo di output:
| Inserimento | Risultato |
|---|---|
$metadata.user_property.priority |
priority |
Scrivere nei metadati
Per impostare una proprietà utente nel messaggio di output, usare $metadata.user_property.<key> come campo di output.
L'impostazione di un campo di metadati su un valore vuoto (()) lo rimuove. Per le proprietà utente, sono consentite chiavi duplicate.
È anche possibile eseguire il mapping delle proprietà dei metadati a un'intestazione di output o a una proprietà utente. Nell'esempio seguente, il MQTT topic è mappato al campo origin_topic nella proprietà utente dell'output.
| Inserimento | Risultato |
|---|---|
$metadata.topic |
$metadata.user_property.origin_topic |
Se il payload in ingresso contiene un priority campo, l'esempio seguente illustra come eseguirne il mapping a una proprietà utente MQTT:
| Inserimento | Risultato |
|---|---|
priority |
$metadata.user_property.priority |
Lo stesso esempio per Kafka:
| Inserimento | Risultato |
|---|---|
priority |
$metadata.header.priority |
I campi dei metadati sono supportati nelle regole di mapping, filtro e ramo. Non sono disponibili nelle regole di finestra (accumulo).
Ultimo valore noto
Usare il ? $last suffisso su un input per indicare al runtime di ricordare il valore più recente per tale campo. Se il campo non è presente nel messaggio corrente, viene invece utilizzato l'ultimo valore noto.
| Inserimento | Comportamento |
|---|---|
temperature ? $last |
Usa l'ultima temperatura nota se il messaggio corrente non ha alcun temperature campo |
La ? $last direttiva non fa distinzione tra maiuscole e minuscole e supporta spazi vuoti flessibili.
Importante
Gli ultimi valori noti vengono archiviati solo in memoria. Vengono persi quando il pod viene riavviato e non vengono condivisi tra le repliche.
L'ultimo valore noto è supportato nelle regole di mapping, filtro e ramo. Non è disponibile nelle regole di finestra (accumulo).
Valori predefiniti
Usare il ?? <default> suffisso su un input per fornire un valore di fallback quando il campo non è presente. Tipi predefiniti supportati: integer, float, boolean, string e null.
Annotazioni
La ?? <default> sintassi è disponibile solo nei grafici del flusso di dati. Non è supportata negli input del flusso builtInTransformation di dati.
| Inserimento | Risoluzione alternativa |
|---|---|
temperature ?? 0 |
Intero 0 |
status ?? "unknown" |
Stringa "unknown" |
threshold ?? 98.6 |
Float 98.6 |
enabled ?? true |
Valore booleano true |
Combinare l'ultimo valore noto e il valore predefinito
È possibile combinare ? $last e ?? <default>. Il runtime controlla prima il messaggio corrente, quindi l'ultimo valore noto, quindi il valore predefinito. Se si usa ?? <default> senza ? $last, il runtime controlla direttamente il messaggio corrente e quindi il valore predefinito.
| Inserimento | Ordine di valutazione |
|---|---|
temperature ?? 0 |
Valore corrente, quindi predefinito (0) |
temperature ? $last ?? 0 |
Valore corrente, quindi ultimo noto, quindi predefinito (0) |
I valori predefiniti sono supportati nelle regole di mapping, filtro e ramo. Non sono disponibili nelle regole di finestra (accumulo).
Tipi di dati
| Tipo | Descrizione | Esempio |
|---|---|---|
| Intero | Intero con segno a 64 bit |
42, -7 |
| Galleggiare | Virgola mobile a 64 bit |
3.14, -0.5 |
| Stringa | Testo UTF-8 | "hello" |
| Bool | Booleano |
true, false |
| Tupla | Matrice di valori primitivi | (1, 2, 3) |
| Vuoto | Valore mancante o Null | () |
| JSON | Oggetto JSON passato tramite | (non può essere usato nelle espressioni) |
Gli oggetti JSON e le matrici vengono mantenuti as-is quando i campi vengono copiati senza un'espressione, ma non possono essere usati come input per la valutazione delle espressioni.
Supporto delle funzionalità per tipo di trasformazione
| Feature | Mappa | Filter | Branch | Finestra (accumulo) |
|---|---|---|---|---|
| Variabili posizionale | Sì | Sì | Sì | Sì |
| Operatori | Sì | Sì | Sì | Sì |
| Funzioni predefinite | Sì | Sì | Sì | Sì |
| Funzione di aggregazione | No | No | No | Sì |
$metadata Accesso |
Sì | Sì | Sì | No |
$context Arricchimento |
Sì | Sì | Sì | No |
? $last |
Sì | Sì | Sì | No |
?? <default> ¹ |
Sì | Sì | Sì | No |
str::regex_matches
/
str::regex_replace ¹ |
Sì | Sì | Sì | No |
| Caratteri jolly | Sì | No | No | No |
¹ Disponibile solo nei grafici del flusso di dati. Non supportato negli input del flusso builtInTransformation di dati.
Notazione e escape dei punti
La notazione punto viene ampiamente usata per fare riferimento a campi annidati. Un percorso di notazione punto standard è simile a Person.Address.Street.Number.
In un flusso di dati, un percorso descritto dalla notazione punto può includere stringhe e alcuni caratteri speciali senza dover eseguire l'escape, ad esempio Person.Date of Birth.
In altri casi, l'escape è necessario, ad esempio: nsu=http://opcfoundation.org/UA/Plc/Applications;s=RandomSignedInt32. Questo percorso, tra gli altri caratteri speciali, contiene punti all'interno del nome del campo. Senza escape, il nome del campo fungerebbe da separatore nella notazione del punto stesso.
Mentre un flusso di dati analizza un percorso, tratta solo due caratteri come speciali:
- I punti (
.) fungono da separatori di campo. - Le virgolette singole, se posizionate all'inizio o alla fine di un segmento, iniziano una sezione di escape in cui i punti non vengono considerati come separatori di campo.
Tutti gli altri caratteri vengono considerati come parte del nome del campo. Questa flessibilità è utile in formati come JSON, in cui i nomi dei campi possono essere stringhe arbitrarie.
La definizione del percorso deve inoltre rispettare le regole del formato di configurazione. Quando un carattere con un significato speciale viene incluso nel percorso, è necessario inserire le virgolette appropriate. Ad esempio, i nomi di campo che iniziano con due punti (ad :Person:.:name:esempio ) o che iniziano con un numero seguito da testo (ad 100 celsius.hotesempio ) devono essere interpretati correttamente come stringhe.
Evasione
La funzione primaria di escape in un percorso con notazione punto consiste nell'usare punti che fanno parte dei nomi dei campi anziché dei separatori. Ad esempio, il percorso Payload."Tag.10".Value è costituito da tre segmenti: Payload, Tag.10e Value. Le virgolette doppie impediscono Tag.10 al punto di fungere da separatore.
Regole di escape nella notazione con punti
Esegui l'escape di ciascun segmento separatamente: nel caso in cui più segmenti contengano punti, tali segmenti devono essere racchiusi tra virgolette doppie. Anche altri segmenti possono essere racchiusi tra virgolette, ma non influisce sull'interpretazione del percorso. Ad esempio:
Payload."Tag.10".Measurements."Vibration.$12".ValueUso corretto delle virgolette doppie: le virgolette doppie devono aprire e chiudere un segmento di testo tra virgolette. Tutte le virgolette al centro del segmento vengono considerate parte del nome del campo. Ad esempio, il percorso
Payload.He said: "Hello", and waveddefinisce due campi:PayloadeHe said: "Hello", and waved. Quando un punto viene visualizzato in queste circostanze, continua a fungere da separatore. Ad esempio, il percorsoPayload.He said: "No. It is done"viene suddiviso nei segmentiPayload,He said: "NoeIt is done"(a partire da uno spazio).
Algoritmo di segmentazione
- Se il primo carattere di un segmento è una virgoletta, il parser cerca la virgoletta successiva. La stringa racchiusa tra queste virgolette è considerata un singolo segmento.
- Se il segmento non inizia con virgolette, il parser identifica i segmenti cercando il punto successivo o la fine del percorso.
Caratteri jolly
Usare un carattere jolly (*) nei percorsi di input e output per trovare una corrispondenza con più campi contemporaneamente. Ciò è utile quando l'output è simile all'input o quando è necessario applicare la stessa trasformazione in molti campi senza elencarne uno.
Copiare tutti i campi
Per passare ogni campo senza modifiche:
| Inserimento | Risultato |
|---|---|
* |
* |
Corrisponde * a ogni percorso di campo nell'input e lo inserisce nello stesso percorso nell'output. La parte del percorso corrispondente * viene chiamata segmento acquisito. Nell'output il segmento acquisito sostituisce .*
Appiattire i campi annidati
Per spostare i campi da un oggetto annidato al livello radice, inserire il prefisso nell'input e * nell'output:
| Inserimento | Risultato |
|---|---|
Sensors.* |
* |
Metadata.* |
* |
Dato questo input:
{
"Sensors": { "Temperature": 72.5, "Pressure": 14.7 },
"Metadata": { "LineId": "Line-3", "Shift": "A" }
}
L'output rende flat entrambi gli oggetti:
{
"Temperature": 72.5,
"Pressure": 14.7,
"LineId": "Line-3",
"Shift": "A"
}
Ristrutturare i campi
Per spostare i campi in un nuovo elemento padre, inserire * l'input e aggiungere un prefisso nell'output:
| Inserimento | Risultato |
|---|---|
* |
Telemetry.* |
In questo modo vengono inclusi tutti i campi di primo livello all'interno di un Telemetry oggetto .
Regole di posizionamento con caratteri jolly
- È consentito un solo valore
*per input o percorso di output. - Deve
*corrispondere a un segmento completo (non a un segmento parziale comeSensor*). - Può
*essere visualizzato all'inizio (*.Value), al centro (Sensors.*.Reading) o alla fine (Sensors.*) di un percorso.
Caratteri jolly a più input
Quando una regola ha più input con caratteri jolly, deve * acquisire lo stesso segmento in tutti gli input. Il runtime risolve l'oggetto * dal primo input, quindi cerca i percorsi corrispondenti negli altri input.
Ad esempio, per mediare le letture massime e minime per ogni sensore:
| Inserimento | Risultato | Expression |
|---|---|---|
*.Max ($1)*.Min ($2) |
Averaged.* |
($1 + $2) / 2 |
Dato questo input:
{
"Temperature": { "Max": 85.3, "Min": 62.1 },
"Pressure": { "Max": 15.2, "Min": 14.1 }
}
L'oggetto * acquisisce Temperature prima di tutto, quindi la regola cerca sia Temperature.Max che Temperature.Min. Acquisisce Pressure quindi e cerca Pressure.Max e Pressure.Min. L'output è il seguente:
{
"Averaged": { "Temperature": 73.7, "Pressure": 14.65 }
}
Se un input non può essere risolto per un segmento acquisito(ad esempio, *.Mid.Avg quando il campo è annidato in modo diverso), tale segmento viene ignorato. Assicurarsi che i percorsi in tutti gli input riflettano la struttura effettiva dei dati.
Eseguire l'override di un carattere jolly per campi specifici
È possibile combinare una regola con caratteri jolly con regole specifiche. Le regole specifiche hanno la precedenza quando hanno una copertura inferiore (meno segmenti corrispondono a *). Questa operazione è denominata specializzazione.
| Inserimento | Risultato | Expression |
|---|---|---|
*.Max ($1)*.Min ($2) |
Averaged.* |
($1 + $2) / 2 |
Pressure.Max ($1)Pressure.Min ($2) |
Averaged.PressureAdj |
($1 + $2 + 1.0) / 2 |
La prima regola si applica a tutti i campi. La seconda regola esegue l'override solo per Pressure , perché Pressure.Max è più specifica di *.Max (copertura 0 e copertura 1).
Per escludere completamente un campo, usare un output vuoto:
| Inserimento | Risultato |
|---|---|
Pressure.Max, Pressure.Min |
(vuoto) |
Un output vuoto elimina il campo dal risultato. In questo modo viene eseguito l'override di qualsiasi regola con caratteri jolly che altrimenti lo includerebbe.
Più regole sugli stessi input
Se due regole hanno la stessa copertura o superiore, entrambe si applicano. In questo modo è possibile calcolare più valori derivati dagli stessi input:
| Inserimento | Risultato | Expression |
|---|---|---|
*.Max ($1)*.Min ($2) |
Stats.*.Avg |
($1 + $2) / 2 |
*.Max ($1)*.Min ($2) |
Stats.*.Range |
$1 - $2 |
Entrambe le regole vengono eseguite per ogni segmento acquisito, producendo due campi di output per sensore.
Caratteri jolly nei set di dati di contestualizzazione
È possibile usare caratteri jolly con $context riferimenti per copiare tutti i campi da un set di dati:
| Inserimento | Risultato |
|---|---|
$context(assetMeta).* |
Asset.* |
In questo modo ogni campo del assetMeta set di dati viene copiato nella Asset sezione dell'output.
Set di dati di contestualizzazione
I set di dati di contestualizzazione consentono ai mapping di integrare dati aggiuntivi da database esterni. Usare il $context(datasetName) prefisso per fare riferimento ai campi di un set di dati. Ad esempio, $context(position).BaseSalary legge il BaseSalary campo da un set di dati denominato position.
Per informazioni dettagliate sulla configurazione dei set di dati di contestualizzazione, vedere Arricchire i dati usando i flussi di dati e Arricchire i dati esterni nei grafici del flusso di dati.