Formelsyntax
Überblick Formelzeitreihen
Formelzeitreihen werden durch die zugrundeliegende Formel festgelegt. Diese spiegelt die Berechnungsvorschrift wider. Die Zeitreihendefinition einer Formelzeitreihe wird gleich jeder anderen Zeitreihe in der Datenbank gespeichert und enthält zusätzlich eine Formel.
Beim Auslesen der Zeitreihe wird diese entsprechend der Formel berechnet und das Ergebnis bereitgestellt.
Über die Formel können Berechnungsvorschriften auf Basis anderer Zeitreihen abgebildet werden. Zeitreihen oder Zahlen können mittels Grundrechnungsarten und Funktionen (+, -, *, /) mit weiteren Zahlen oder Zeitreihen berechnet werden.
Formelsyntax
Formeln werden in Textform verwaltet. Die Formel wird zur Laufzeit des Auslesens der Zeitreihe vom HAKOM Framework kompiliert und berechnet.
Die Syntax ist ident zu der in VB.Net verwendeten. Es können auch sämtliche Funktionen vom Math Namespace verwendet werden: http://msdn.microsoft.com/de-de/library/system.math_members.aspx
Operatoren
Formeln unterstützen folgende Operatoren:
+ | - | * | / | ^ | Mod |
Zusätzlich werden folgende Vergleichsoperatoren unterstützt:
= | <> | < | > | <= | >= |
z.B. 3 + 5 * 2 führt dazu, dass die Zeitreihe immer den Wert 13 annimmt.
Es können auch Klammern gesetzt werden:
z.B.: (3 + 5) * 2 führt dazu, dass die Zeitreihe immer den Wert 16 annimmt.
Zeitreihen referenzieren
Zeitreihen können nach folgendem Muster in einer Formel referenziert werden:
[Zeitreihe (Name oder ID), Offset (Optional), Einheit (Optional), Aggregation (Optional)]
Parameter | Bedeutung |
---|---|
Zeitreihe | Name oder ID der Zeitreihe, die referenziert wird. |
Offset | Erweiterung des Zeitraums, für welchen Daten geladen werden, in beide Richtungen. Bei Angabe eines Offsets n werden zusätzlich die Daten n Intervallschritte vor dem Rasterbeginn der Formelzeitreihe und n Intervallschritte nach dem Rasterende der Formelzeitreihe geladen. Diese zusätzlich geladenen Daten stehen dann für Berechnungen zur Verfügung. |
Einheit | Einheit, in die die Daten der referenzierten Zeitreihe konvertiert werden. |
Aggregation | Aggregationsregel, die beim Aggregieren der Daten der referenzierten Zeitreihe herangezogen werden soll. |
Mit der Verwendung der Zeitreihen in Formeln mittels eckigen Klammern wird ein Data-Element übergeben. Dieses beinhaltet neben den Werten ([8765].Value) der Zeitreihe auch den Status ([8765].Flag) der Werte, das Von und Bis-Datum ([8765].fromDate und [8765].toDate) und der Index der Zeitreihe ([8765].Index).
Für alle unter dem Punkt "Operatoren" erwähnten Operatoren gilt:
- Vergleich/Berechnung einer referenzierten Zeitreihe mit einer weiteren Zeitreihe liefert als Ergebnis ebenfalls ein Data-Element.
- Vergleich/Berechnung einer referenzierten Zeitreihe mit einem Integer-Wert liefert als Ergebnis ein Data-Element.
- Vergleich/Berechnung einer referenzierten Zeitreihe mit einem Double-Wert liefert als Ergebnis ein Data-Element.
- Wird statt der Zeitreihen-ID direkt mit den Werten der Zeitreihe gerechnet (also [Zeitreihen-ID].Value anstatt [Zeitreihen-ID]), liefert dies als Ergebnis einen Double-Wert.
Beispiele
Beispiel 1:
Hier wird nur die ID einer Zeitreihe übergeben:
[4711]
Die Formelzeitreihe nimmt beim Auslesen nun dieselben Daten wie die Zeitreihe 4711 an.
Beispiel 2:
Hier werden die ID einer Zeitreihe und ein Offset übergeben:
Lead([4711, 2], 2)
Die Formelzeitreihe nimmt beim Laden die Daten der Zeitreihe 4711 an, zusätzlich werden die Daten 2 Intervallschritte vor dem Rasterbeginn der Formelzeitreihe und 2 Intervallschritte nach dem Rasterende der Formelzeitreihe geladen. Die Funktion "Lead" verschiebt die Daten um zwei Rasterschritte, was durch die zusätzlich geladenen Daten außerhalb der "von" und "bis" Daten ermöglicht wird.
Beispiel 3:
Hier werden die ID einer Zeitreihe, ein Offset und eine Einheit übergeben:
[4711, 0, kW]
Die Formelzeitreihe nimmt beim Auslesen die Daten der Zeitreihe 4711 konvertiert in kW an.
Beispiel 4:
Hier werden die ID einer Zeitreihe, ein Offset, eine Einheit und eine Aggregation übergeben:
[4711, 0, "", Sum]
Die Formelzeitreihe nimmt beim Auslesen die Daten der Zeitreihe 4711 an. Werden Daten aggregiert (weil sich z.B. die Intervalle der Zeitreihen unterscheiden), wird entsprechend der Aggregationsregel "Sum" die Summe der Daten gebildet.
Beispiel 5:
Hier werden Zeitreihen mittels der unterstützten Operatoren miteinander verknüpft:
[4711]*3+[123]+0.22
Die Formelzeitreihe nimmt hier den Wert der Zeitreihe 4711 multipliziert mit drei und addiert mit dem Wert der Zeitreihe 123 und dem Wert 0,22 an.
Spezifikation Formelzeitreihen
Raster
Formelzeitreihen werden im Raster der angelegten Formelzeitreihe berechnet. Dies bedeutet, dass in Formeln verwendete Zeitreihen, für die Berechnung, im Raster der Formelzeitreihe abgefragt werden.
Beispiel: Bewerten von Lastprofilen mit Lastprofil im Stunden- und Preiszeitreihe im Halbstundenraster für Stunden- und Tageswerte:
Szenario 1 - Formelzeitreihe im Stundenraster
Berechnung: Lastprofil (Stundenraster) * Preiszeitreihe (auf Stundenraster gemittelt)
Ergebnis: Formelzeitreihe im Stundenraster
Szenario 2 – Eine Formelzeitreihe im Tagesraster
Berechnung: Lastprofil (auf Tagesraster gemittelt) * Preiszeitreihe (auf Tagesraster gemittelt)
Ergebnis: Formelzeitreihe im Tagesraster
-> Dies bedeutet das falsche Ergebnis, da nur die Tagesdurchschnittswerte berechnet werden
Szenario 3 – Eine Formelzeitreihe im Stundenraster, als Tagesraster auslesen
Berechnung: Lastprofil (auf Stundenraster gemittelt) * Preiszeitreihe (auf Stundenraster gemittelt)
Zwischenergebnis: Formelzeitreihe im Stundenraster
Ergebnis: Formelzeitreihe ausgelesen als Tagesraster
-> Hier ist das Ergebnis richtig, da der Tageswert der Formelzeitreihe aus den aufsummierten Stundenwerten besteht.
Einheiten
Es besteht die Möglichkeit eine Einheit in der Formel der Zeitreihe angeben zu können.
Z.B.: [530379,-3,KW,Average] wandelt die Daten der Zeitreihe 530379 von ursprünglichen MW in KW um, verschiebt die Zeitreihe um -3 Intervalle und errechnet dabei den Durchschnitt, der über den Raster der Formelzeitreihe mit den Werten der Zeitreihe 530379 gebildet wird.
Dabei muss darauf geachtet werden, dass die Umrechnungen der Einheiten auch plausibel gewählt werden (Es ist nicht möglich eine Zeitreihe mit der Einheit MW in Euro oder Prozent umzuwandeln.).
Standardfunktionen
Mit der HAKOM TSM App werden bereits eine Reihe von nützlichen Funktionen im Rahmen der Installation bereit gestellt und sind somit ohne zusätzlichen Aufwand verfügbar. Diese Funktionen sind in sogenannten EvalComponentHAKOM Dateien definiert. Des Weiteren besteht die Möglichkeit eigene kundenspezifische Funktionen zu implementieren. Eine Erläuterung hierzu ist auf folgender Seite zu finden: Defining Formula Functions
Name | Parameter | Beispiel | Beschreibung |
---|---|---|---|
Average | Average(ByVal ParamArray data As Data())* | Average([15],[16]) | Liefert den Durchschnittswert der übergebenen Werte. Hier würde der Durchschnittswert aus beiden übergebenen Zeitreihen zurückgegeben werden. |
AverageLeadLag | AverageLeadLag(ByVal data As Data, ByVal Shift As Int32())* | AverageLeadLag([16748],6) | Liefert den um die Anzahl Rasterschritte (Shift) verschobenen Durchschnittswert der Zeitreihe. |
AvgDaily | AvgDaily(ByVal data As Data)* | AvgDaily([15]) | Liefert den Tagesdurchschnittwert. |
AvgOfRange | AvgOfRange(ByVal data As Data, ByVal shiftFrom As Integer, ByVal shiftTo As Integer)* | AvgOfRange([195829],6,12) | Liefert den Durchschnitt der Werte der Zeitreihe zwischen ShiftFrom und ShiftTo. |
BestValue | BestValue(ByVal ParamArray dataArray As Data())* | BestValue([15],[16]) | Die Funktion BestValue gibt den anhand des Status des aktuellen Werts ermittelten "besten" Wert der übergebenen Zeitreihen zurück. Hat also der Wert einer der Zeitreihen die Flag "Fehlerhaft" und die andere zum selben Zeitpunkt die Flag "Gültig" wird der Wert der gültigen zurückgegeben. Sollten beide dieselbe Flag haben, wird der Wert der zuerst übergebenen Zeitreihe zurückgegeben. |
ConstantMaturity | ConstantMaturity(ByVal data As Data, ByVal maturity As Integer, ByVal maturityInterval As Components2016.TimeSeries.TimeSeriesInterval, Optional ByVal exact As Boolean = True) ConstantMaturity(ByVal data As Data, ByVal maturity As Integer, Optional ByVal exact As Boolean = True) | ConstantMaturity([4231],4) ConstantMaturity([4231],4,Components2016.TimeSeries.TimeSeriesInterval.Hour) | Diese Funktion dient dazu unterschiedliche Notierungszeitpunkte einer Zeitreihe in einer Formelzeitreihe zusammenzufassen. Ein Beispiel zu ihrer Funktionsweise finden Sie am Ende der Tabelle. |
FromNow | FromNow(ByVal value As Double) | FromNow(100) | Schreibt den angegebenen Wert in die Formelzeitreihe, solange der Rastereintrag > der aktuellen Zeit ist, ansonsten 0. Am 01.01.2019 um 18.00 hat die Zeitreihe in jedem Rastereintrag bis 01.01.2019,18.00 den Wert "0". Ab dem nächsten Raster hat sie den Wert "100". |
GD „Gleitender Durchschnitt“ | GD(ByVal data As Data, ByVal average As Integer, ByVal offset As Integer)* GD(ByVal data As Data, ByVal average As Integer, ByVal offset As Integer, ByVal valid As Integer)* | GD([195829], 7, 0) GD([195829],2,0,3) | GD mit 3 Parametern (ohne "valid"): Die Funktion "GD" berechnet den gleitenden Durchschnitt über die übergebene Anzahl Intervallschritte ("average") mit dem übergebenen Offset ("offset") an Intervallschritten. Dabei bestimmt das Intervall des Templates die Intervallschritte. Bsp.: GD([195829],7,0): Wenn man hier ein Tagesintervall mit einer Länge von "1" annimmt, wird beim Auslesen der Zeitreihe der gleitende Durchschnitt über 7 Tage ohne Offset berechnet. Für den 8. Tag wird also der Durchschnitt der Tage 1-7 berechnet, für den 9. Tag der Durchschnitt der Tage 2-8, usw. GD mit 4 Parametern (mit "valid"): Der zusätzliche Parameter gibt an, wie viele Intervalleinheiten den berechneten Wert übernehmen. Achtung: hier ist das Kalkulationsintervall stehts "Monat"! Bsp.: GD([195829],2,0,3): Hier wird der Durchschnitt von jeweils 2 Monaten ohne Offset gebildet. Dieser Wert wird dann für 3 Monate übernommen. |
GetMyAttributeValue | GetMyAttributeValue(Attributsname As String, Optional [Datum] As DateTime) | GetMyAttributeValue("Test_Attribut_1") | Gleiches Verhalten wie GetAttributeValue, jedoch wird hier die Zeitreihen ID der aktuellen Zeitreihe genommen |
GetAttributeValue | GetAttributeValue(Zeitreihen-ID As Integer, Attributsname As String, Optional [Datum] As DateTime) | GetAttributeValue(101752,"Test_Attribut_1", new DateTime(2019,01,01,23,0,54) | GetAttributeValue liefert den Wert eines Attributes einer bestimmten Zeitreihe zurück.
|
Lag | Lag(ByVal data As Data, ByVal Shift As Integer)* | Lag([15],48) | Die Werte der Zeitreihe werden um die Anzahl Rasterschritte (Shift) nach vorne verschoben. |
LagDaily | LagDaily(ByVal data As Data, ByVal Shift As Integer)* | LagDaily([15],2) | Die Werte der Zeitreihe werden um die Anzahl Tage (Shift) nach vorne verschoben. |
Lead | Lead(ByVal data As Data, ByVal Shift As Integer) | Lead([15],-1) | Die Werte der Zeitreihe werden um die Anzahl Rasterschritte (Shift) nach hinten verschoben. |
LeadDaily | LeadDaily(ByVal data As Data, ByVal Shift As Integer)* | LeadDaily([15],2) | Die Werte der Zeitreihe werden um Anzahl Tage (Shift) nach hinten verschoben. |
MaxDaily | MaxDaily(ByVal data As Data) | MaxDaily([17]) | Ermittelt den Maximalwert auf Tagesbasis. |
MaxOfRange | (ByVal data As Data, ByVal shiftFrom As Integer, ByVal shiftTo As Integer)* | MaxOfRange([195830],6,12) | Liefert den höchsten Wert einer Zeitreihe innerhalb der Parameter shiftFrom bis shitTo. |
MinDaily | MinDaily(ByVal data As Data)* | MinDaily([17]) | Ermittelt den Minimalwert auf Tagesbasis. |
MinOfRange | MinOfRange(ByVal data As Data, ByVal shiftFrom As Integer, ByVal shiftTo As Integer)* | MinOfRange([195830],6,12) | Liefert den kleinsten Wert einer Zeitreihe innerhalb der Parameter shiftFrom bis shitTo. |
OffPeak | OffPeak(ByVal data As Data) | OffPeak([195830]) | Liefert die Off-Peak (Mo-Fr, 20:00-08:00, Sa und So) Werte einer Zeitreihe. Zu jeden anderen Zeitpunkt nehmen die Werte 0 missing an. |
Peak | Peak(ByVal data As Data) | Peak([200]) | Liefert die Peak (Mo-Fr, 08:00-20:00) Werte einer Zeitreihe. Zu jeden anderen Zeitpunkt nehmen die Werte 0 missing an. |
Sum | Sum(ByVal data As Data) | Sum([1447]) | Liefert die Summe der Werte die auf der referenzierten Zeitreihe gespeichert sind. |
TSA | TSA(Attributes As String, Unit As String) | TSA("DocCategory","kW") | Liefert das Aggregat des übergebenen Attributs (Dieses muss vom Typ Category (=Eigenschaft) sein), konvertiert in die angegebene Einheit. Die Werte pro Rastereinheit nehmen immer die schlechteste Flag an, die eine der Zeitreihen, denen das Attribut zugewiesen ist, hat. Bsp.: Ist die Flag einer Zeitreihe von 12.00-13.00 "gültig" und die einer anderen in diesem Zeitbereich "ungültig", hat die Formelzeitreihe zu diesem Zeitbereich die Flag "ungültig". |
TSAA | TSAA(Unit As String, bestStatus As Boolean, ParamArray Attributes() As String) | TSAA("kW",true,"DocAttribute") | Die TSAA Formel funktioniert ähnlich der TSA Formel. Hier ist es aber möglich auch Attribute für die Aggregation zu wählen. Außerdem kann ein Boolean übergeben werden. Dieser legt fest, ob der Wert innerhalb eines Rastereintrags das "beste" Flag aus den zum Aggregat herangezogenen Zeitreihen haben soll, oder ob - wie üblich - das "schlechteste" Flag angenommen wird. Es is möglich, mehrere, durch Beistriche getrennte Attribute zu übergeben. Es werden dann nur jene Zeitreihen aggregiert, denen alle übergebenen Attribute zugeordnet wurden. |
TSCA | TSCA(Unit As String, ParamArray Attributes() As String) TSCA(Unit As String, bestStatus As Boolean, ParamArray Attributes() As String) TSCA(TimeSeriesName As String, Unit As String, bestStatus As Boolean, ParamArray Attributes() As String) | TSCA("kW","DocCategory") TSCA("kW",true, "DocCategory","DocCategory_2") TSCA("Doku ZR%","kW",true) TSCA("Doku ZR%","kW",true,"DocCategory","DocCategory_2") | Die TSCA Formel funktioniert ähnlich der TSA Formel. Außerdem kann ein Boolean übergeben werden. Dieser legt fest, ob der Wert innerhalb eines Rastereintrags das "beste" Flag aus den zum Aggregat herangezogenen Zeitreihen haben soll, oder ob - wie üblich - das "schlechteste" Flag angenommen wird. Es ist möglich, mehrere, durch Beistriche getrennte Attribute zu übergeben. Es werden dann nur jene Zeitreihen aggregiert, denen alle übergebenen Attribute zugeordnet wurden. Es besteht auch die Möglichkeit, die TSCA Formel mit einem Zeitreihennamen (auch inkl. Wildcard) aufzurufen. Die Formelzeitreihe selbst sollte den in der TSCA Formel angegebenen Kriterien (Attribute oder Zeitreihenname) nicht entsprechen, da es ansonsten zu einem "Zirkelbezug" kommt. |
UntilNow | UntilNow(ByVal value As Double) | UntilNow(100) | Schreibt den angegebenen Wert in die Formelzeitreihe, solange der Rastereintrag < der aktuellen Zeit ist, ansonsten 0. Am 01.01.2019 um 18.00 hat die Zeitreihe in jedem Rastereintrag bis 01.01.2019,18.00 den Wert "100". Ab dem nächsten Raster hat sie den Wert "0". |
ValidAvg | ValidAvg(ByVal data As Data)* | ValidAvg([2342]) | Liefert die Durchschnittswerte der aggregierten Zeitreihendaten konvertiert in das vordefinierte Raster (Stunde). Es werden nur Werte berücksichtigt, deren Flag nicht "fehlend" ist. |
ValidAvgLeadLag | ValidAvgLeadLag(ByVal data As Data, ByVal Shift As Int32)* | ValidAvgLeadLag([2342],6) | Funktioniert wie ValidAvg, allerdings um einen Shift-Parameter erweitert. |
ValidIntegral | ValidIntegral(ByVal data As Data)* | ValidIntegral([195829]) | Aggregiert die Werte der übergebenen Zeitreihe in das vordefinierte Raster (Stunden) und summiert alle Werte, die nicht die Flag "fehlend" haben. |
ValidMax | ValidMax(ByVal data As Data)* | ValidMax([195829]) | Aggregiert die Werte der übergebenen Zeitreihe in das vordefinierte Raster (Stunden) und übernimmt den höchsten Wert, der nicht die Flag "ungültig" hat. |
ValidMin | ValidMin(ByVal data As Data)* | ValidMin([195829]) | Aggregiert die Werte der übergebenen Zeitreihe in das vordefinierte Raster (Stunden) und übernimmt den niedrigsten Wert, der nicht die Flag "ungültig" hat. |
XChange | XChange(ByVal Name As String, ByVal Unit As String) | XChange("Doku ZR_3","kWh") | Rechnet die übergebene Zeitreihe in die übergebene Einheit um. |
*Diesen Funktionen kann anstelle eines Data-Types ein Integer übergeben werden. Bsp.: Statt Lag([123]) ist es möglich Lag([123].Index) anzugeben.
Beispiele
Für die nachfolgenden Beispiele gelten folgende Definitionen:
Es gibt vier Versionen von "ConstandMaturity_Daten": Am 01.01.2020 viertelstündlich zwischen 06:00:00 und 06:45:00.
Das Raster von beider Zeitreihen ist eine Viertelstunde.
Beispiel 1: Die ConstantMaturity Funktion
ConstantMaturity([ConstandMaturity_Daten],0)
Wie kommen die Werte für "ConstantMaturity_Formel" zustande?
Die Funktion überprüft, ob für den aktuellen Rastereintrag eine Version der übergebenen Zeitreihe existiert. Für 06:00-06:15 wird also überprüft, ob es von "ConstantMaturity_Daten" eine Version von 01.01.2019 06:00 existiert. Da dies der Fall ist, wird der Parameter "maturity", der einen Shift darstellt, auf diese Version angewandt. Da dieser in diesem Beispiel = 0 ist, wird nicht geshiftet und der Wert der Version von 06:00-06:15 übernommen.
Danach wird für den nächsten Rastereintrag (06:15-06:30) wieder überprüft, ob es eine Version für diesen Zeitpunkt gibt. Das ist der Fall und es wird der Wert der entsprechenden Version für diesen Rastereintrag übernommen.
Ab 07:00 gibt es keine Version mehr von "ConstantMaturity_Daten"und die Werte sind daher = 0, missing.
Beispiel 2: Die ConstantMaturity Funktion mit Verschiebung
ConstantMaturity([ConstantMaturity_Daten],4)
Die Werte der Formelzeitreihe werden hier wie in Beispiel 1 ermittelt. Einzig der Parameter "maturity" unterscheidet sich. Das hat folgende Auswirkungen:
Es wird nun nicht mehr der Wert der Version zum Startzeitpunkt des aktuellen Rastereintrags übernommen. Stattdessen wird um die mit maturity übergebene Anzahl an Schritte innerhalb der Version geshiftet. In diesem Beispiel ist maturity = 4, daher wird für den Rastereintrag von 06:00-06:15 nicht der Wert dieses Rastereintrags der Version von 06:00 übernommen, sondern jener von 07:00-07:15, weil vier mal um eine Viertelstunde verschoben wurde.
Weil es keine Version vor jener von 06:00 gibt, bleibt der Wert der Formelzeitreihe von 06:00-07:00 = 0, missing.
Beispiel 3: Die ConstantMaturity Funktion mit Verschiebung um Rasterintervall
ConstantMaturity([ConstantMaturity_Daten],2,Components2016.TimeSeries.TimeSeriesInterval.Hour)
In diesem Beispiel wurde der Funktion zusätzlich ein Interval (Components2016.TimeSeries.TimeSeriesInterval) übergeben. Maturity ist nun = 2 und das Interval = Stunde. Daher werden die Werte der jeweiligen Rastereinträge den entsprechenden Versionen entnommen und um zwei Stunden verschoben.
Wir empfehlen folgende Videos unter Video Tutorials:
- Standard Functions
- Formula Time Series
- Ad Hoc Calculation