Speichern von Snapshots oder Checkpoints von Algorithmen während des EMS-Laufs

Hallo Community,

Ich laüfe das OpenEMS für unser Projekt auf einem iPC aus - das unter Windows läuft. Mit Hilfe der “Task Scheduler”-Option war ich in der Lage, Windows so zu konfigurieren, dass OpenEMS automatisch startet, wenn der PC aus irgendeinem unbekannten Grund neu gestartet wird, z. B. bei einem Stromausfall.

Ich habe hier eine neue Problemstellung (zumindest glaube ich das). Ist es möglich, einen Snapshot der Zustände von Algorithmen oder anderen wichtigen Parametern von verschiedene Komponenten zu speichern, die sich normalerweise während des EMS-Laufs ständig ändern. Dies sollte dann wie die Konfigurationswerte funktionieren, die, wie ich sehe, von OpenEMS automatisch in C:// gespeichert werden. Meine Idee ist, dass das EMS, sobald es wieder online ist, nach vorhandenen Algorithmus-Parametern sucht und mit diesen Werten (als Last Checkpoints) anstelle der Standard-Initialisierungen initialisiert.

Wenn so etwas bereits angedacht war oder fallengelassen wurde, würde ich mich über Ihr Feedback freuen.

viele Grüße
Laksh

Hi Laksh,

klingt spannend,
aktuell “resetten” wir selbst die angeschlossenen Geräte bei einem neustart, also fahren Mischer an “feste” Positionen etc. weil wir uns nicht sicher sein können, was der letzte Zustand war.
Daher wäre die Idee ganz nett.

möglich soltle das auch sein, wenn man einfach die Daten eh in der “Influx” hat, also wenn es nur “channel” daten sind und keine anderen verwendet werden. Dann müsste man natürlich noch die Daten beim aufruf “abfragen”, soetwas gibt es meines Wissens nach noch nicht.

Schönen Gruß

Paul

1 Like

Hallo Paul,

Danke für deine Antwort

Du hast recht. Ich habe nicht daran gedacht, dass ich die Details (nicht alle, aber einige) bereits in der Datenbank gespeichert habe. Vielleicht werde ich es ausprobieren.

Auch dein anderer Punkt macht Sinn. Wir können nicht immer sicher sein, dass der letzte Standpunkt noch gültig ist. Es muss auch hier wieder eine Art von Intelligenz geben, die entscheidet.

Eine Idee, die mir schon in den Sinn kommt, ist, dass die jeweilige Komponente bei der Aktivierung die zuletzt eingegebenen Sollwerte (z.B. LIB-Ausgangsleistung) in der Datenbank prüft, und wenn der Zeitstempel des zuletzt aktualisierten Wertes nahe genug dran ist, sagen wir die letzten 5 Minuten oder so, dann würde die Batterie auf diesen Sollwert gesetzt werden. Aber auch hier gibt es wieder so viele andere Parameter, die berücksichtigt werden müssen, bevor man das tut.

Grüß
Laksh

Hallo zusammen,

es gibt eine Funktion, die in etwa so arbeitet, wie Paul das beschrieben hat. Der Use-Case für den wir das umgesetzt haben ist, dass wir Geräte haben, die intern die Be-/Entladeenergie (z. B. ACTIVE_CHARGE_ENERGY) nicht richtig mitrechnen. Deshalb rechnen wir die Energie selbst anhand der Leistung auf (ACTIVE_POWER). Allerdings soll der erechnete Wert natürlich bei einem Neustart nicht wieder bei 0 anfangen. Deshalb lesen wir erst aus einem existierenden Timedata-Service - z. B. RRD4j oder InfluxDB - den letzten Wert aus und rechnen von dem Wert weiter.

Beispiel: Battery-Inverter.Kaco.BlueplanetGridsave:

Gruß,
Stefan

2 Likes

@stefan.feilmeier

Ich versuche gerade zu verstehen, wie das obige Beispiel funktioniert. Dazu benötige ich deine Hilfe. Ich sehe, dass die Komponente Battery-Inverter.Kaco.BlueplanetGridsave sich mit der DB verbindet, um den letzten gespeicherten Wert zu erhalten, indem sie eine Timedata-Variable verwendet. Aber was ich nicht verstehe, ist, wie wird die Variable zugewiesen, die Timedata-Komponente zu verbinden. Die Variable timedata ist, wie ich sehe, als Null initialisiert.

Ich meine, zum Beispiel habe ich eine InfluxDb Timedata Komponente influx0, dann wie versteht die Implementierung Battery-Inverter.Kaco.BlueplanetGridsave, dass die Timedata mit der Instanz influx0 gefüllt werden muss.

Ich danke dir im Voraus für deine Hilfe
Laksh

Hallo Laksh,

die Variable timedata hat eine Reference-Annotation:

@Reference(policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.OPTIONAL)
private volatile Timedata timedata = null;

Diese Declarative Services Annotation sorgt dafür, dass das OSGi Framework zur Laufzeit einen Service injiziert, der das Timedata-Interface implementiert.

Declarative Services werden an sehr vielen Stellen in OpenEMS verwendet, um die Komponenten miteinander zu verbinden. Es lohnt sich hier auf jeden Fall, sich etwas tiefer einzulesen:

http://blog.vogella.com/2016/06/21/getting-started-with-osgi-declarative-services/

http://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html

Gruß,
Stefan

1 Like