Zum Hauptinhalt springen

Formula Expressions

Mehrere OctoMesh-Funktionen erlauben es Ihnen, eine Formel einzugeben – einen kleinen numerischen Ausdruck, der einen oder mehrere Eingabewerte referenziert und einen einzelnen Wert erzeugt. Alle nutzen dieselbe Formel-Engine (mXparser, gekapselt als IFormulaEngine), sodass die nachfolgende Syntax überall identisch ist, wo eine Formel akzeptiert wird.

Wo Formeln verwendet werden​

FunktionEingabevariable(n)Hinweise
DataPointMapping MappingExpressionvalue – der abgefragte QuellwertWird vom Adapter ausgewertet, wenn ein Steuerwert auf ein Zielattribut abgebildet wird. Vor dem Speichern mit der validate-expression-API validieren.
Berechnete Archivspaltenjede Quellspalte, gebunden über ihren Spaltennamen (z. B. activepower, apparentpower)Wird zum Zeitpunkt des Archiv-Ingests (sowie während Backfill / Rollup) für jede Zeile ausgewertet. Ein null / NaN-Ergebnis speichert SQL NULL. Der ResultType wird mit der Spalte gespeichert und steuert das Rückcasting (siehe unten).
Runtime-Query-@-Ausdrücke(keine – Konstanten + Funktionen)Ein mit @ präfigierter Query-Suchbegriff wird als Formel ausgewertet (z. B. eine Zeitgrenze @startOfDay(0)).
Numerische Engine

Die Engine rechnet mit double. Eingaben und Ergebnisse sind Zahlen; Booleans sind 0 / 1 und Datums-/Zeitwerte sind .NET-Ticks. In Formeln gibt es keine Zeichenketten-Verarbeitung.

Variablen​

Eine Formel referenziert ihre Eingaben über den Namen. Für ein DataPointMapping ist die einzige Eingabe value; andere Funktionen binden ihre eigenen Namen (z. B. bindet eine berechnete Archivspalte jede Quellspalte über ihren Spaltennamen). Ein Name, der von der Funktion nicht bereitgestellt wird, ist ein Syntaxfehler.

Operatoren​

KategorieOperatoren
Arithmetik+ - * / ^ (Potenz) % (Modulo)
Vergleich< <= > >= == !=
Gruppierung( … )

Vergleichsergebnisse werden mit den logischen Operatoren && (und), || (oder) und ! (nicht) kombiniert.

Bedingungen​

Beide Formen werden akzeptiert und sind gleichwertig:

value > 0 ? value : 0
if(value > 0, value, 0)

Der ternäre Operator im C-Stil cond ? a : b wird vor der Auswertung zu mXparsers if(cond, a, b) normalisiert. Verschachtelung wird unterstützt; verwenden Sie zur Klarheit Klammern:

value > 100 ? 100 : (value < 0 ? 0 : value)

Eingebaute Funktionen (mXparser)​

Die Engine ist der vollständige mXparser-Parser (v6.x) – nichts ist deaktiviert – sodass die gesamte mXparser-Math Collection verfügbar ist, nicht nur die Handvoll, die die meisten Formeln verwenden. Da jede Eingabe und das Ergebnis double sind (siehe den Hinweis zur numerischen Engine oben), ist der numerische Teil dieser Collection das, was praktisch nützlich ist; die Helfer für Zeichenketten / Einheiten / Wahrscheinlichkeitsverteilungen existieren, haben hier aber keine Zeichenketten- oder Einheiten-Eingaben, auf denen sie arbeiten können.

Die am häufigsten verwendeten Funktionen:

FunktionBedeutung
abs(x)Absolutwert
sgn(x)Vorzeichen (-1 / 0 / +1)
min(a, b, …) / max(a, b, …)Minimum / Maximum (beliebig viele Argumente)
round(x, n)auf n Nachkommastellen runden
floor(x) / ceil(x)abrunden / aufrunden
sqrt(x)Quadratwurzel
exp(x)e^x
ln(x) / log2(x) / log10(x)natürlicher / Basis-2- / Basis-10-Logarithmus
log(a, b)Logarithmus mit expliziter Basis (Argumentreihenfolge siehe Referenz)
mod(a, b)Modulo (wie der %-Operator)
if(cond, a, b)Bedingung
iff(c1, v1, c2, v2, …)mehrzweigige Bedingung – die erste wahre Bedingung gewinnt

Weitere Kategorien der Collection, die auf numerischen Eingaben arbeiten:

KategorieBeispiele
Trigonometrie (Bogenmaß)sin(x) cos(x) tan(x) cot(x) sec(x) csc(x)
Invers / hyperbolischasin(x) acos(x) atan(x), sinh(x) cosh(x) tanh(x)
Winkelumrechnungrad(deg) (Grad→Bogenmaß), deg(rad) (Bogenmaß→Grad)
Runden / Teilefloor(x) ceil(x) round(x,n), frac(x) (Nachkommaanteil)
Kombinatorik / Zahlentheoriegcd(a,b,…) lcm(a,b,…) C(n,k) (Binomialkoeffizient), n! (Fakultät)
Aggregationmin(…) max(…), gcd(…) lcm(…)
Vollständiger Katalog

Diese Tabelle ist eine kuratierte Teilmenge. Die maßgebliche, versionsgenaue Liste jeder Funktion, jedes Operators und jeder Konstante, die der Parser akzeptiert, ist die mXparser Math Collection. Alles, was dort aufgeführt ist und nur numerische Argumente entgegennimmt, funktioniert in einer OctoMesh-Formel.

Konstanten​

mXparser liefert eine große Menge mathematischer und physikalischer Konstanten mit. Diejenigen, die Sie am wahrscheinlichsten verwenden:

KonstanteWert
piπ ≈ 3.14159
eEulersche Zahl ≈ 2.71828
[phi]Goldener Schnitt ≈ 1.61803
[gam]Euler–Mascheroni-Konstante ≈ 0.57722
true / false1 / 0 (praktisch mit den logischen Operatoren)

(Physikalische Konstanten wie die Lichtgeschwindigkeit sind ebenfalls definiert – siehe Referenz. Wie bei den Funktionen sind hier nur ihre numerischen Werte relevant.)

OctoMesh-Erweiterungen​

Diese drei werden von OctoMesh zusätzlich zur Standard-Collection registriert (siehe OctoExpression / NowFunction / StartOfDayFunction in Runtime.Engine.Formulas):

Funktion / KonstanteBedeutung
now(addMinutes)aktueller Zeitstempel als .NET-Ticks, versetzt um addMinutes Minuten (negativ = Vergangenheit)
startOfDay(dayCount)lokale Mitternacht als .NET-Ticks, verschoben um dayCount Tage (startOfDay(0) = heute, startOfDay(-1) = gestern)
nullder Null-Sentinel – siehe unten

Beide Datumsfunktionen geben Ticks zurück, sie sind also für einen DateTime-Ergebnistyp oder für Vergleiche gegen andere Tick-Werte gedacht (z. B. eine Runtime-Query-Zeitgrenze @startOfDay(0)).

Null- und Fehlerbehandlung​

  • Eine fehlende / null Eingabe bindet an den null-Sentinel.
  • Wenn eine Formel zu NaN (z. B. 0 / 0) oder zum null-Sentinel auswertet, wird der Wert als kein Ergebnis behandelt – Funktionen bilden dies auf einen Fallback ab (DataPointMapping behält den rohen numerischen Wert; eine berechnete Archivspalte speichert NULL).
  • Ein Syntaxfehler (unausgeglichene Klammern, unbekannte Variable, fehlerhafter Ausdruck) wird zum Validierungszeitpunkt gemeldet, bevor die Formel jemals verwendet wird.

Beispiele​

AusdruckBedeutung
value / 100Prozent in Verhältnis skalieren
value * 100Verhältnis in Prozent skalieren
value - 2.5Kalibrierungs-Offset
abs(value)Betrag
min(max(value, 0), 100)auf 0…100 begrenzen
value > 0 ? value : 0nur positiver Anteil
value < 0 ? abs(value) : 0Betrag des negativen Anteils (z. B. Entladeleistung)

Eine Formel validieren​

Für DataPointMapping stellt der Communication Controller einen maßgeblichen Validierungs-Endpunkt bereit, der dieselbe Engine ausführt, die der Adapter zur Laufzeit verwendet, sodass eine Formel, die validiert, auch läuft:

POST {tenantId}/v1/communication/validate-expression
{ "expression": "value > 0 ? value : 0", "testValue": 42.0 }

Er gibt { valid, error, result, normalizedExpression } zurück – result ist der Wert für den übergebenen testValue, und normalizedExpression zeigt das Umschreiben von ternär zu if.

Ergebnistypen​

Funktionen, die ein Formelergebnis persistieren (insbesondere berechnete Archivspalten), speichern einen Ergebnistyp neben dem Ausdruck. Die Engine wertet zu double aus und castet dann zurück:

ErgebnistypRückcasting
Doubleder rohe Wert
Intauf eine 32-Bit-Ganzzahl abgeschnitten
Int64auf eine 64-Bit-Ganzzahl abgeschnitten
Booleanfalse, wenn der Wert 0 ist, andernfalls true
DateTimeder Wert wird als .NET-Ticks interpretiert (passt natürlich zu now() / startOfDay())

Ein null-Sentinel- oder NaN-Ergebnis wird unabhängig vom gewählten Typ immer auf null abgebildet.

Für Entwickler

Die Engine selbst – der IFormulaEngine-Servicevertrag, die mXparser-Abhängigkeit, die DI-Registrierung und die gemeinsamen Konventionen zu ternär / null / Rückcasting – ist im Entwicklerhandbuch dokumentiert: Formula Engine.