Komplexe Logik zusammen mit Openhab und HTTP Request

Hallo zusammen

Ich bin mich gerade ein wenig in homegear am einarbeiten bzw. ist ev. schon fast übertrieben… es läuft zumindestens mal :wink:

Folgende Ausgangssituation:

Aktuell haben ich ein Boiler mit Homematic Temeratur sensoren. Diese werden über die CCU2 per OpenHab abgefragt.
Dann haben ich eine Solaranlage, welche Stromproduktion sowie momentanen Verbrauch per HTTP Request ebenfalls an OpenHab liefert.

In OpenHab habe ich eine relative komplexe Logik welche aus den Solarwerten den überschuss von Strom ausrechnet. Aufgrund der überschüssigen Leistung der Solaranlage wird der Boiler über ein Thyristor gesteuert um diese Leistung möglichst zu “verbrennen”. Dies natürlich nur bis zu einer bestimmten Temparatur des Boilers.
Da der Verbrauch des Boilers leider nicht linear zum Stellwert des Thyristor ist, musste ich über eine (ausgemessene) Tabelle die Stellkurve (Relation Stellwert zu Verbrauch) entsprechend berücksichtigen.

Da nun noch eine Heizröhre für die Wärmepumpe in das ganze mit eingebunden werden soll, um in 2. Priorität nach dem Boiler die Restenergie in die Wärmepumpe zu stofen, würde dies nun noch komplexer werden.

Aktuelle Probleme:
[ul][li]Da die CCU2 leider nicht so stabil ist wie ich dies gerne hätte und ich auch bzgl. Wartung und Stabilität (Fehlerquellen) die eingesetzten Komponenten möglichst gering halten will, möchte ich die CCU2 durch homegear ersetzen. Somit läuft dann alles auf dem Intel NUC welcher bereits für OpenHab verwendet wird.[/li]
[li]OpenHab erlaubt leider keine “Funktionen” (wiederverwendbaren Code mit Rückgabewert), dadruch muss wird die Logik umsetzung mit der OpenHab Rule Engine relativ unübersichtlich.[/li]
[li]Durch den Loop über die Stellwert-Tabelle für die nicht lineare Steuerung des Thyristor, kommt die Rule-Engine in OpenHab selbst auf dem i3 NUC an seine grenzen… aktuell dauert die Abarbeitung der Logik bis zu 1000ms. Hier natürlich die Verzögerungen der Abfragewerte (Polling) der neusten Strommesswerte noch nicht eingerechnet. Dadurch hinkt natürlich die Stellung des Thyristor immer den aktuellen Werten ziemlich hinterher, was zu einer schlechteren Ausnutzung der Solarleistung führt.[/li][/ul]

1. Schritt
CCU2 ersetzen durch Homegear (eins zu eins), sehe ich keine Probleme, homegear läuft bereits mit hmland und einem HM-CFG-USB2. Testweise konnte ich bereits ein Relais anlernen, abfragen und auch Kanäle setzen. Somit kann ich mal die CCU2 sicherlich in der Bucht verschwinden lassen :slight_smile:

2. Schritt
Nun hier stellt sich vor allem die Frage an euch… was Ihr noch optimieren würdet?
Da ich aktuell vermute, dass sich mit PHP hier einiges performanter die Logik umsetzen liese, wäre meine Idee, alle Logik in PHP Skripte und somit mit Homegear zu erledigen und Openhab eigentlich nur noch als Web-Interface und Datentopf für Werte-Historisierung zu verwenden.

Für diesen Ansatz, hätte ich zu mindestens ein paar Fragen…
[ul]
[li]Da ich möglichst Modular die die Logik aufteilen möchte, müsste ich die Zwischenschritte ja irgendwie speichern. Wie würdet Ihr die errechneten Stromwerte (Überschuss=Produktion-Verbrauch) speichern?[/li]
[li]Ev. als virtuelles Device oder einfach als System Variable?[/li]
[li]Geht dies überhaupt wie ich mir das vorstelle? :slight_smile:[/li]
[li]Muss ja dann auf Änderungen des errechneten Wertes mittels Event reagieren können, geht dies überhaupt mit System Variablen? Da ich die CCU2 ja eigentlich immer nur als Datenlieferant missbraucht habe, kenne ich mich leider auch nicht mit den Homematic “Philosophie” gut aus und kann somit nicht wirklich den vergleich zu Homegear herstellen.[/li]
[li]Was haltet Ihr davon bzw. hättet Ihr bessere Lösungsvorschläge?[/li][/ul]

Bin euch dankbar für Tipps, nicht dass ich von Anfang an ein komplett falschen Ansatz wähle.
Und Sorry für das halbe Buch welches ich hier geschrieben habe :slight_smile:

Hallo grandslam,

ja :wink:! Du solltest die gesamte Logik ohne Probleme durch PHP-Code ersetzen können. Ich würde dafür Homegear’s PH7-Skript-Engine verwenden [1]. Diese unterstützt zwar nicht alle PHP-Funktionen ist aber um Längen performanter und sollte für deine Anforderungen auch alles Nötige mitbringen. Alternativ lässt sich natürlich auch “normales” PHP verwenden, falls du Werte beispielsweise in einer MySQL-Datenbank speichern möchtest. Bei vielen RPC-Anfragen leidet jedoch die Performance.

Als Systemvariable.

Auf die Änderungen würde ich direkt aus deinem Skript heraus nach Berechnung der Werte mit entsprechenden Funktionsaufrufen reagieren.

Das Ganze sollte dann auf jeden Fall deutlich weniger als eine Sekunde zum Berechnen brauchen :stuck_out_tongue:.

Falls du irgendwelche Fragen hast, einfach hier posten.

Liebe Grüße

Sathya

Nachtrag: Die HTTP-Requests hatte ich vergessen. Die versteht Homegear leider nicht. Entweder kannst du ein PHP-Skript über einen kleinen Webserver aufrufen, welches eine Systemvariable in Homegear setzt und eventuell weitere Skripte aufruft oder eine Systemvariable in Homegear über OpenHAB setzen.

[1] http://ph7.symisc.net/

Erstmals, danke für die prompte und ausführliche Antwort.

Das mit dem speichern in der DB überlasse ich dann glaube ich eh OpenHab, da ich die History (zumindestens bis jetzt) noch nicht in der Logik benötige… demnach reicht wenn es losgelöst ist in OpenHab.

Dachte ich mir schon fast :slight_smile:
aber rein aus Interesse, wenn ich nun dann mal die einzelnen Logikbausteine trennen will und dann über Events arbeiten… (gehe davon aus gibt kein Event der auf Systemvariablen-Änderungen reagiert). Kann ich theoretisch dafür ein virtuelles gerät missbrauchen, in dem ich dort die Werte setze, und dann über ein Event dann wiederum darauf reagiere?
Habe irgendwie das Gefühl das wäre “schöner” ( = modularer und transparenter). Klar natürlich auf kosten von Verzögerungen, da auf die Events ja erstmal reagiert werden muss.
Aber das ist so ein Tick von mir… alles möglichst perfekt Modular und voneinander losgelöst zu machen :slight_smile: Aber natürlich wenn ich dies in Funktionen packe wäre es praktisch das gleiche nur halt nicht losgelöst :slight_smile:

Geht wiederum bisschen ins gleiche wie oben schon geschrieben…Ich müsste halt einfach mal ausprobieren was dies an Verlust bedeutet wenn ich es über ein virtuelles Device mache (sofern dies überhaupt geht).

Das hätte ich gedacht, könnte ich mittels einem PHP Skript in Homegear lösen. Irgendwo habe ich schon ein Timer Beispiel gesehen… welches dann z.B. jede Sekunde die Werte abfragt und dann entsprechend deinem Vorschlag in eine Systemvariable schreibt. Da eine HTTP abfrage sowieso ein paar Milisekunden benötigt, gehe ich nicht davon aus, dass ich hier (relativ zur Abfrage) ein riesen Zeitverlust habe wenn ich dies nicht mit PH7 mache.

Ja, du kannst ein virtuelles Gerät dazu missbrauchen, ich finde die Lösung aber etwas unschön. Hab mal ein GitHub-Issue dazu erzeugt [1] und werde mal schauen, ob ich die Tage nicht Ereignisse bei Systemvariablenänderungen eingebaut bekomme :wink:.

Die sollten minimal sein.

Ach so, das hatte ich missverstanden. Ich dachte, die Solaranlage sendet den Request an OpenHAB. Natürlich geht das aus einem Skript heraus, welches du regelmäßig aufrufst.

Stimmt.

Liebe Grüße

Sathya

[1] https://github.com/Homegear/Homegear/issues/151

[quote=“sathya”]Hab mal ein GitHub-Issue dazu erzeugt [1] und werde mal schauen, ob ich die Tage nicht Ereignisse bei Systemvariablenänderungen eingebaut bekomme :wink:.
[/quote]
Wäre natürlich auch eine Möglichkeit… wusste nicht, dass dies als Option existiert, da ich dachte du willst dich nicht zu weit von der original CCU entfernen aus kompatibilitäts Gründen.

Wenn wir schon dabei sind :wink:
Was ich an den Variablen unschön finde, die lassen sich nicht gescheit strukturieren… darum würde mit ein Device irgendwie besser gefallen, weil dann mache ich ein Device für die Solaranlage mit Kanälen für die Werte welche ich Abfragen kann und Kanälen mit den Werten die ich dann daraus ausrechne.
Dies entspricht viel mehr dem Objektorientierten Ansatz bzw. wiederspiegelt ziemlich genau die Realität. Und da es dann ein Skript ist welches alle Kanäle setzt, würde es mich dann auch nicht mehr so stören, wenn ich die HTTP Request und das Rechnen im gleichen Skript mache. Es würde ja dem gleichen Device entsprechen was schlussendlich ja sogar stimmt (abgesehen davon, das es die Werte nicht selber liefert) :slight_smile:

Variablen sind für mich mehr so ein Konstrukt welches man wirklich nur noch für nicht gruppierbare und einzelne Werte nutzen sollte… aber das ist sicherlich eine Philosophie frage und Geschmacksache :slight_smile:

Nicht das ich glaube, dass es nötig ist (kann ich ja per CLI machen für mein Fall)… aber habe keine RPC Methode gefunden um ein virtuelles Device zu erstellen… fände ich fast die schönere Verbesserung :slight_smile: Damit könnte man generell “externen nicht Homematic Geräten” die Möglichkeit zur Verfügung stellen, sich selber mit Devices zu registrieren.
Dies würde ev. ganz neue Möglichkeiten eröffnen und Homegear zugänglicher für “fremde” Geräte/Lösungen machen.

An der Stelle besteht sowieso keine Kompatibilität zur CCU. Von daher spielt es keine Rolle. Ist jetzt auch schon drin :wink:. Waren nur wenige Zeilen Code.

Jein. Du kannst auch “Strukturen” (also assoziative Arrays) in Systemvariablen speichern. Nur wird’s dann mit den Ereignissen ein bisschen schwierig und diese müssen immer als Ganzes gelesen und geschrieben werden. Von daher keine schöne Lösung.

In diesem Fall tatsächlich wohl die beste Möglichkeit. Ich denke mal darüber nach, wie sich das am besten Implementieren lässt. Das ist leider etwas aufwändiger als die Systemvariablenereignisse.

Ich bin jedenfalls auch ein Freund objektorientierter Programmierung :wink:.

Die RPC-Methode zu erstellen ist das kleinste Problem.

Liebe Grüße

Sathya

[quote=“sathya”]Ist jetzt auch schon drin :wink:. Waren nur wenige Zeilen Code.
[/quote]
Danke!

Das wäre dann natürlich die ultimative Lösung und sicherlich eine Bereicherung für Homegear.
Aber blöde Frage ist dies mit den virtuellen Devices nicht schon gegeben, oder verhalten diese sich nicht schon wie ein richtiges Device?
Falls nicht… wenn ich es richtig verstanden habe definieren ja XML Files ein Device. Demnach müsste man die Möglichkeit haben über ein XML ein Device zu definieren welches halt einfach nicht kommuniziert. Dann könnte jeder sich per XML ein Device mit benötigten Kanälen selber zusammen stricken. Homegear müsste dann diese “nur” ein wenig speziell behandeln, da diese ja nicht Kommunizieren, sondern nur durch die Homegear per API angesteuert werden. Ev. ist dies dann weniger Arbeit, als irgend etwas von neu auf zu erfinden.

Nicht wirklich. Die virtuellen Geräte haben bisher alle sehr spezielle Aufgaben und lassen sich nur durch Quelltextänderung erweitern.

Genau. So wird es auch laufen müssen. Die Gerätedefinition per RPC zu senden wäre vermutlich zu komplex. Vermutlich wird das Ganze sogar jetzt schon funktionieren, wenn du eine passende XML-Datei für deine Solaranlage anlegst. Danach kannst du die Solaranlage mit “peers add” hinzufügen. Das einzige Problem ist, das auf ein “setValue” bisher keine Ereignisse ausgelöst wurden. Das ändere ich heute mal :wink:.

Liebe Grüße

Sathya

Nachtrag: Setz “interface” für die Variablen auf “store”. Dann sollte es mit der aktuellen GitHub-Version bzw. dem nächsten Nightly klappen.

Ok muss mich dann mal hinter so eine XML Datei klemmen… ehrlich gesagt habe noch nicht mal in eine rein geschaut :blush:
Aber habe in dem Fall ja Zeit bis der nightly durch ist :smiley:

Wenn ich etwas Zeit habe heute Abend, bastele ich dir eine Vorlage :wink:.

Ganz vergessen, ich hatte noch eine Minimal-Vorlage. Hab sie für deine Zwecke mal etwas angepasst:

<?xml version="1.0" encoding="UTF-8"?>
<device version="1">
	<supported_types>
		<!-- change name and id as you like-->
		<type name="MyVirtualDevice" id="HM-Virtual" priority="2">
			<parameter index="9.0" size="1.0" cond_op="GE" const_value="0x10"/>
			<!-- const_value contains the device type. It is mandatory to change that to an unused value. -->
			<parameter index="10.0" size="2.0" const_value="0xFF01"/>
		</type>
	</supported_types>
	<channels>
		<!-- Keep this channel unchanged -->
		<channel index="0" type="MAINTENANCE" ui_flags="internal" class="maintenance" count="1">
			<paramset type="MASTER" id="maint_ch_master"/>
			<paramset type="VALUES" id="maint_ch_values">
				<parameter id="UNREACH" operations="read,event" ui_flags="service">
					<logical type="boolean"/>
					<physical type="integer" interface="internal" value_id="UNREACH"/>
				</parameter>
				<parameter id="STICKY_UNREACH" operations="read,write,event" ui_flags="service,sticky">
					<logical type="boolean"/>
					<physical type="integer" interface="internal" value_id="STICKY_UNREACH"/>
				</parameter>
				<parameter id="CONFIG_PENDING" operations="read,event" ui_flags="service">
					<logical type="boolean"/>
					<physical type="integer" interface="internal" value_id="CONFIG_PENDING"/>
				</parameter>
				<parameter id="LOWBAT" operations="read,event" ui_flags="service">
					<logical type="boolean"/>
					<physical type="integer" interface="internal" value_id="LOWBAT"/>
				</parameter>
				<parameter id="RSSI_DEVICE" operations="read,event">
					<logical type="integer"/>
					<physical type="integer" interface="internal" value_id="RSSI_DEVICE"/>
				</parameter>
				<parameter id="RSSI_PEER" operations="read,event">
					<logical type="integer"/>
					<physical type="integer" interface="internal" value_id="RSSI_PEER"/>
				</parameter>
			</paramset>
		</channel>
		<!-- Add as many channels as you like -->
		<channel index="1" type="CUSTOM">
			<paramset type="VALUES" id="custom_ch1_values">
				<parameter id="MY_BOOLEAN" operations="read,write,event">
					<logical type="boolean" default="false" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
				<parameter id="MY_INTEGER" operations="read,write,event">
					<logical type="integer" default="0" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
				<parameter id="MY_FLOAT" operations="read,write,event">
					<logical type="float" default="0.0" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
				<parameter id="MY_STRING" operations="read,write,event">
					<logical type="string" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
			</paramset>
		</channel>
		<channel index="2" type="CUSTOM">
			<paramset type="VALUES" id="custom_ch2_values">
				<parameter id="MY_BOOLEAN" operations="read,write,event">
					<logical type="boolean" default="false" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
				<parameter id="MY_INTEGER" operations="read,write,event">
					<logical type="integer" default="0" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
				<parameter id="MY_FLOAT" operations="read,write,event">
					<logical type="float" default="0.0" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
				<parameter id="MY_STRING" operations="read,write,event">
					<logical type="string" />
					<physical interface="store" />
					<conversion type="rpc_binary" />
				</parameter>
			</paramset>
		</channel>
	</channels>
</device>

danke, bin erst jetzt dazu gekommen es aus zu probieren.
Aber ich kann das virtuelle Device nicht erstellen.
Ich habe das XML nach /etc/homegear/devices/0 geschmissen. Gemäss Debug log wird das file auch gelesen.
Ich bekomme immer Unknown device type.
Wenn ich bei Device Typ eines der bereits existierenden virtuellen Devices angebe, klappt das erstellen.
Habe es auch mal mit verschiedenen Type Id’s für das Beispiel versucht, leider auch ohne Erfolg.

Folgende funktionieren:

FFFFFFFD: Central device FFFFFFFE: Spy device 39: HM-CC-TC 3A: HM-CC-VD

Dein Beispiel jedoch nicht :frowning:
Hast du zufällig eine Idee oder muss ich eine bestehende XML dafür missbrauchen?

Hey,

du musst eine Ebene tiefer. Für Homegear ist das Ganze kein virtuelles, sondern ein reales Gerät. Also:

ds c
peers add XXX

Liebe Grüße

Sathya

Du bist ja schnell :slight_smile:
Hat für exakt dein Beispiel geklappt mitpeers add FF01 FFFFFF HM-Virtual 1F
Jetzt mache ich mich mal daran das Device meinen Bedürfnissen an zu passen.