Hallo erstmal!
In diesem Thread versuch ich einmal mit Unterstützung von Waldemar (@mumpf) zu zeigen, wie wir uns die notwendige Logik zum Auslesen des web2com-Interfaces inkl. Der passenden Widgets basteln.
Ziel war bzw. ist es gewesen eine Wärmepumpe inkl. web2com-Interface auszulesen und darzustellen.
(in meinem Fall eine Ochsner GMSW – Erdwärme Sole)
Das Ergebnis sieht am iPhone bzw. iPad so aus:
2017-01-13 16.58.32.pngDatei 13.01.17, 17 11 18.jpeg
Bzw. mit einem zweiten Widget:

Was man grob dafür braucht:
-------
1. Schritt: Ausgangspunkt die Weboberfläche/Schnittstelle der Wärmepumpe
Bildschirmfoto vom 2017-01-13 14-29-11.png
Die rechts dargestellten Daten wollen wir möglichst alle auslesen.
Und an der Wärmepumpe gibt es z.B. folgende Ansichten, die ich gerne auch in CD in der Übersicht hätte:
Ochsner-AnzeigeWP.png
2. Schritt: Parsen der Daten
Wie komm ich an die Daten aus der web2com-Weboberfläche? Einmal im Baum (Mitte) einen Wert ausgewählt, lässt sich in Chrome über "Einstellungen"/"weitere Tools" die "Entwicklertools" öffnen.
Chrome-Entwicklertools.png
Und dort kann ein Element mit Rechtsklick -> Copy ->Copy as cURL ein Kommando bekommen, das ich mit cURL testen kann (z.B. Konsole unter Linux)(Curl ist ein Programm, das es ermöglicht, ohne Benutzerinteraktion Dateien von oder zu einem Server zu übertragen).
Chrome-cURL.png
Dann bekomm ich folgendes:
<oid> sind die Elemente im Menübaum. Also /1/2/1/125/4 entspricht:
Hier passe ich den "Autentifizierungsteil" noch an die realen Nutzerdaten und ein paar andere Dinge an:
Damit bekomm ich auf der Konsole (in meinem Fall unter Linux) folgende Rückmeldung:
Da steckt doch schon mal zw. <value> und </value> der gesuchte Wert für die zugehörige Adresse (<oid>).
Im Fall eines Fehlers (z.B. wenn die Autentifizierung nicht passt) bekomm ich folgende Rückmeldung
Da kann man doch den String <faultcode> oder <faultstring> gleich zur Auswertung mit auswerten 
3. Schritt: cURL Befehl in Python umsetzen
Hier hab ich nun auch etwas grübeln müssen, was ich alles benötige um obigen cURL Befehl nun in einem Python-Skript unterzubringen.
Letztendlich kam dabei folgendes raus:
Einfach den cURL-Befehl mit der Library "requests" in Python nachgebaut und gleich in eine Funktion mit Variablen gepackt, damit ich die Routine für alle Werte nutzen kann.
4. Schritt: Notwendige Items in Callidomus (CD) anlegen und diese füllen
Damit ich alle Werte in CD nutzen kann, müssen wir für die gewünschten Werte Items anlegen.
Das funktioniert hier dann ganz gut mit dem gesamten Skript:
Dabei hab ich mir fleissig alle Einträge der Statustexte mit den Entwicklertools extrahiert und eingetragen.
Die folgende Zeile ist vielleicht auch noch interessant:
Hier berechne ich mir auf Grundlage des Volumenstroms (der Wasserfördermenge aus der WP in m³/h), der Temperaturdifferenz (Spreizung in Kelvin), der Dichte von Wasser (hier mit 1t/m³ angenommen) und der spezifischen Wärme von Wasser (in 1.163 Wh/(kg*K)) die Heizleistung meiner Wärmepumpe in Watt (W). Also im Detail:
cd.WP.Waermepumpe.Betriebsdaten.VolumenstromWaerme quelle -> liegt in l/min vor -> also erstmal durch 1000, damit wir m³/min bekommen -> dann mal 60 für m³/h
alle weiteren Werte bleiben und die Einheiten lassen sich wunderbar soweit wegkürzen, dass nur noch "Watt" übrig bleiben.
Jetzt haben wir die Logik als Grundlage.
Die nutze ich schon mal für die Detailanzeigen in CD:
Detailansicht.png
5. Schritt: Grafiken erstellen
Wie oben gezeigt, möchte ich gerne die beiden Grafiken in die Visu integrieren:
Ochsner-AnzeigeWP.png
Dafür hab ich beide in LibreOffice Draw einfach nachgezeichnet und als SVG einzeln exportiert.
Draw-Widgetanzeige.png
Da kommt dann erstmal ganz viel Müll in der SVG mit an (Nur ein Auszug daraus):
Da muss man doch noch einiges drinn aufräumen, damit es am Ende wie folgt aussieht (Beipielhaft am Fussbodenheizungsteil):
example.png
--------
Ab hier übergebe ich an Waldemar für die Erstellung der zugehörigen:
Grüße
Thorsten
In diesem Thread versuch ich einmal mit Unterstützung von Waldemar (@mumpf) zu zeigen, wie wir uns die notwendige Logik zum Auslesen des web2com-Interfaces inkl. Der passenden Widgets basteln.
Ziel war bzw. ist es gewesen eine Wärmepumpe inkl. web2com-Interface auszulesen und darzustellen.
(in meinem Fall eine Ochsner GMSW – Erdwärme Sole)
Das Ergebnis sieht am iPhone bzw. iPad so aus:
2017-01-13 16.58.32.pngDatei 13.01.17, 17 11 18.jpeg
Bzw. mit einem zweiten Widget:
Was man grob dafür braucht:
- eine Idee und vielleicht schon die Logik, die umgesetzt werden soll
- Bilddaten in einer (aufgeräumten) SVG, in der man Werte/Texte ersetzen kann
- ein __init__.py zum erzeugen des Widgets
- für jeden darzustellenden Wert ein Item (falls man will: Ein komplexes Item mit allen Werten)
- ein widget.js für die Darstellung der Item-Werte und evtl. zum setzen der class-Attribute der html-tags
- ein widget.css für die eingentliche Darstellung (Font, Farbe etc.) der class-Attribute
-------
1. Schritt: Ausgangspunkt die Weboberfläche/Schnittstelle der Wärmepumpe
Bildschirmfoto vom 2017-01-13 14-29-11.png
Die rechts dargestellten Daten wollen wir möglichst alle auslesen.
Und an der Wärmepumpe gibt es z.B. folgende Ansichten, die ich gerne auch in CD in der Übersicht hätte:
Ochsner-AnzeigeWP.png
2. Schritt: Parsen der Daten
Wie komm ich an die Daten aus der web2com-Weboberfläche? Einmal im Baum (Mitte) einen Wert ausgewählt, lässt sich in Chrome über "Einstellungen"/"weitere Tools" die "Entwicklertools" öffnen.
Chrome-Entwicklertools.png
Und dort kann ein Element mit Rechtsklick -> Copy ->Copy as cURL ein Kommando bekommen, das ich mit cURL testen kann (z.B. Konsole unter Linux)(Curl ist ein Programm, das es ermöglicht, ohne Benutzerinteraktion Dateien von oder zu einem Server zu übertragen).
Chrome-cURL.png
Dann bekomm ich folgendes:
Code:
curl 'http://192.168.1.200/ws' -H 'Authorization: Basic VVNxxxxxMjM=' -H 'Origin: http://192.168.1.200' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.90 Safari/537.36' -H 'Content-Type: text/xml; charset=UTF-8' -H 'Accept: */*' -H 'Referer: http://192.168.1.200/RC7000.html?locale=de' -H 'Connection: keep-alive' -H 'SOAPAction: http://ws01.lom.ch/soap/getDP' --data-binary $'<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://ws01.lom.ch/soap/">\n <SOAP-ENV:Body>\n <ns:getDpRequest>\n <ref>\n <oid>/1/2/1/125/4</oid>\n <prop/>\n </ref>\n <startIndex>0</startIndex>\n <count>-1</count>\n </ns:getDpRequest>\n\n </SOAP-ENV:Body>\n</SOAP-ENV:Envelope>' --compressed
Code:
/(1) EBusRoot/(2) 513200224/(1) WAERMEPUMPE/(125) Betriebsdaten/(4) 00:70 IST Temp.TQA
Code:
curl 'http://192.168.1.200/ws' --user "USER:xxx" -H 'Content-Type: text/xml; charset=UTF-8' -H 'SOAPAction: http://ws01.lom.ch/soap/getDP' --data-binary $'<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://ws01.lom.ch/soap/"><SOAP-ENV:Body><ns:getDpRequest><ref><oid>/1/2/1/125/4</oid><prop/></ref><startIndex>0</startIndex><count>1</count></ns:getDpRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>'
Code:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://ws01.lom.ch/soap/"><SOAP-ENV:Body><ns:getDpResponse><ref><oid>/(1) EBusRoot/(2) 513200224/(1) WAERMEPUMPE/(125) /(4) 00:70</oid><prop>-r--</prop></ref><dpCfg><index>4</index><name>00:70</name><prop>-r--</prop><desc>Scalar Var</desc><value>8.2</value><unit>°C</unit><type>13</type><step>0.1</step><minValue>0.0</minValue><maxValue>100.0</maxValue></dpCfg></ns:getDpResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
Im Fall eines Fehlers (z.B. wenn die Autentifizierung nicht passt) bekomm ich folgende Rückmeldung
Code:
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://ws01.lom.ch/soap/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>HTTP Error: 401 Unauthorized</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

3. Schritt: cURL Befehl in Python umsetzen
Hier hab ich nun auch etwas grübeln müssen, was ich alles benötige um obigen cURL Befehl nun in einem Python-Skript unterzubringen.
Letztendlich kam dabei folgendes raus:
Code:
import requests url='http://192.168.1.200/ws' username="USER" password="xxx" headers = { 'Content-Type': 'text/xml; charset=UTF-8', 'SOAPAction': 'http://ws01.lom.ch/soap/getDP', } def web2com_values(oid): data = '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://ws01.lom.ch/soap/"><SOAP-ENV:Body><ns:getDpRequest><ref><oid>' + oid + '</oid><prop/></ref><startIndex>0</startIndex><count>1</count></ns:getDpRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>' resp = requests.post(url, auth=(username,password), headers=headers, data=data) if resp.text.find("faultstring") < 0: return resp.text[(resp.text.index("<value>")+len("<value>")):resp.text.index("</value>")] else : return 0 cd.WP.Waermepumpe.Betriebsdaten.Betriebsstunden = web2com_values('/1/2/1/125/7')
4. Schritt: Notwendige Items in Callidomus (CD) anlegen und diese füllen
Damit ich alle Werte in CD nutzen kann, müssen wir für die gewünschten Werte Items anlegen.
Das funktioniert hier dann ganz gut mit dem gesamten Skript:
Code:
import requests url='http://192.168.1.200/ws' username="USER" password="123" headers = { 'Content-Type': 'text/xml; charset=UTF-8', 'SOAPAction': 'http://ws01.lom.ch/soap/getDP', } def web2com_values(oid): data = '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://ws01.lom.ch/soap/"><SOAP-ENV:Body><ns:getDpRequest><ref><oid>' + oid + '</oid><prop/></ref><startIndex>0</startIndex><count>1</count></ns:getDpRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>' resp = requests.post(url, auth=(username,password), headers=headers, data=data) if resp.text.find("faultstring") < 0: return resp.text[(resp.text.index("<value>")+len("<value>")):resp.text.index("</value>")] else : return 0 cd.WP.Waermepumpe.Betriebsdaten.Betriebsstunden = web2com_values('/1/2/1/125/7') cd.WP.Waermepumpe.Betriebsdaten.IstTempTQA = web2com_values('/1/2/1/125/4') cd.WP.Waermepumpe.Betriebsdaten.IstTempTQE = web2com_values('/1/2/1/125/5') cd.WP.Waermepumpe.Betriebsdaten.IstTempTWV = web2com_values('/1/2/1/125/1') cd.WP.Waermepumpe.Betriebsdaten.IstTempTWR = web2com_values('/1/2/1/125/3') cd.WP.Waermepumpe.Betriebsdaten.Schaltzyklen = web2com_values('/1/2/1/125/6') cd.WP.Waermepumpe.Betriebsdaten.VolumenstromWaermenutzung = web2com_values('/1/2/1/125/8') cd.WP.Waermepumpe.Betriebsdaten.VolumenstromWaermequelle = web2com_values('/1/2/1/125/9') cd.WP.Waermepumpe.Betriebsdaten.VorlauftempSollwert = web2com_values('/1/2/1/125/2') cd.WP.Waermepumpe.Betriebsdaten.Leistung = 60/1000*cd.WP.Waermepumpe.Betriebsdaten.VolumenstromWaermequelle*abs(cd.WP.Waermepumpe.Betriebsdaten.IstTempTQA-cd.WP.Waermepumpe.Betriebsdaten.IstTempTQE)*1.163 temp = web2com_values('/1/2/1/125/0') cd.WP.Waermepumpe.Betriebsdaten.StatusWaermeerzeuger = temp if int(temp) == 0: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '0: Abgeschalten' elif int(temp) == 1: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '1: Heizbetrieb' elif int(temp) == 2: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '2: Vorlaufzeit Heizbetrieb' elif int(temp) == 3: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '3: Extern gesperrt' elif int(temp) == 4: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '4: Kühlbetrieb' elif int(temp) == 5: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '5: Vorlaufzeit Kühlbetrieb' elif int(temp) == 6: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '6: Vorlaufzeit Abtaubetrieb' elif int(temp) == 7: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '7: Abtaubetrieb' elif int(temp) == 8: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '8: Störung' elif int(temp) == 9: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '9: Abtropfen' elif int(temp) == 10: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '10: Abtausperrzeit' elif int(temp) == 11: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '11: Abtau Vorheizung' elif int(temp) == 12: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '12: Abtauen 1' elif int(temp) == 13: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '13: Abtauen 2' elif int(temp) == 14: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '14: Abtauen 3' elif int(temp) == 15: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '15: Alarm' elif int(temp) == 16: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '16: Störung - Wärmequelle zu kalt' elif int(temp) == 17: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '17: Blockiert' elif int(temp) == 18: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '18: Vorglühen' elif int(temp) == 19: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '19: Eindüsung Ein' elif int(temp) == 20: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '20: Eindüsung Aus' elif int(temp) == 22: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '22: TWVmax Abschaltung' elif int(temp) == 23: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '23: TWEmax Abschaltung' elif int(temp) == 24: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '24: TWAmin Abschaltung' elif int(temp) == 25: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '25: TKAmin Abschaltung' elif int(temp) == 26: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '26: Bivalzenabschaltung' elif int(temp) == 27: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '27: Warmwasser Ladesperre' elif int(temp) == 28: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '28: Minimale Auszeit' elif int(temp) == 29: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '29: Minimale Einzeit' elif int(temp) == 30: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '30: Anheizen' elif int(temp) == 31: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '31: Ausbrand' elif int(temp) == 32: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '32: Pumpen-Nachlauf' elif int(temp) == 33: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '33: Verzögerung Folge-WE' elif int(temp) == 34: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '34: Betrieb Übertemperatur' elif int(temp) == 35: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '35: Fülltüre geöffnet' elif int(temp) == 36: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '36: Passivkühlung' elif int(temp) == 37: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '37: Heizbetrieb angefordert' elif int(temp) == 38: cd.WP.Waermepumpe.Betriebsdaten.Statustext = '38: Kühlbetrieb angefordert' else: cd.WP.Waermepumpe.Betriebsdaten.Statustext = temp cd.WP.Fussbodenheizung.Betriebsdaten.Aussentemperatur = web2com_values('/1/2/5/119/1') cd.WP.Fussbodenheizung.Betriebsdaten.HeizkreisVorlauftemperatur = web2com_values('/1/2/5/119/5') cd.WP.Fussbodenheizung.Betriebsdaten.MittelwertAussentemperatur = web2com_values('/1/2/5/119/2') cd.WP.Fussbodenheizung.Betriebsdaten.Raumtemperatur = web2com_values('/1/2/5/119/3') cd.WP.Fussbodenheizung.Betriebsdaten.RelativeFeuchte = web2com_values('/1/2/5/119/7') cd.WP.Fussbodenheizung.Betriebsdaten.SollwertHeizkreisVorlauftemperatur = web2com_values('/1/2/5/119/6') cd.WP.Fussbodenheizung.Betriebsdaten.SollwertRaumtemperatur = web2com_values('/1/2/5/119/4') temp = web2com_values('/1/2/5/119/0') cd.WP.Fussbodenheizung.Betriebsdaten.StatusHeizkreis = temp if int(temp) == 0: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '0: Abgeschaltet' elif int(temp) == 1: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '1: Normal Heizbetrieb' elif int(temp) == 2: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '2: Komfort Heizbetrieb' elif int(temp) == 3: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '3: Spar Heizbetrieb' elif int(temp) == 4: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '4: Frostschutzbetrieb' elif int(temp) == 5: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '5: Zwangsabnahme' elif int(temp) == 6: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '6: Zwangsdrosselung' elif int(temp) == 7: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '7: Ferienbetrieb' elif int(temp) == 8: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '8: Partybetrieb' elif int(temp) == 9: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '9: Normal Kühlbetrieb' elif int(temp) == 10: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '10: Komfort Kühlbetrieb' elif int(temp) == 11: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '11: Spar Kühlbetrieb' elif int(temp) == 12: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '12: Störung' elif int(temp) == 13: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '13: Handbetrieb' elif int(temp) == 14: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '14: Schutz Kühlbetrieb' elif int(temp) == 15: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '15: Partybetrieb Kühlen' elif int(temp) == 16: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '16: Austrocknung Aufheizen' elif int(temp) == 17: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '17: Austrocknung Stationär' elif int(temp) == 18: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '18: Austrocknung Auskühlen' elif int(temp) == 19: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '19: Austrocknung Endphase' elif int(temp) == 20: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '20: Nachtlüftung' elif int(temp) == 21: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '21: Belüftung' elif int(temp) == 22: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '22: Kühlbetrieb extern' elif int(temp) == 23: cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = '23: Heizbetrieb extern' else : cd.WP.Fussbodenheizung.Betriebsdaten.Statustext = temp cd.WP.Waermeverteiler.Betriebsdaten.AnlageVorlauftemperatur = web2com_values('/1/2/8/122/2') cd.WP.Waermeverteiler.Betriebsdaten.HeizleistungHeizbetrieb = web2com_values('/1/2/8/122/4') cd.WP.Waermeverteiler.Betriebsdaten.HeizleistungWarmwasserbetrieb = web2com_values('/1/2/8/122/5') cd.WP.Waermeverteiler.Betriebsdaten.IstTempTPMPuffertemperatur = web2com_values('/1/2/8/122/1') cd.WP.Waermeverteiler.Betriebsdaten.IstTempTPOPuffertemperatur = web2com_values('/1/2/8/122/0') cd.WP.Waermeverteiler.Betriebsdaten.SollwertAnlagevorlauf = web2com_values('/1/2/8/122/3') temp = web2com_values('/1/2/8/122/6') cd.WP.Waermeverteiler.Betriebsdaten.StatusWaermemanager = temp if int(temp) == 0: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '0: Abgeschaltet' elif int(temp) == 1: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '1: Heizen' elif int(temp) == 2: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '2: Kühlen' elif int(temp) == 3: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '3: WWA' elif int(temp) == 4: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '4: PWA' elif int(temp) == 5: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '5: Heizen Kühlen' elif int(temp) == 6: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '6: Heizen WWA' elif int(temp) == 7: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '7: Heizen PWA' elif int(temp) == 8: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '8: Heizen Kühlen WWA' elif int(temp) == 9: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '9: Heizen Kühlen PWA' elif int(temp) == 10: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '10: Heizen WWA PWA' elif int(temp) == 11: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '11: Heizen Kühlen WWA PWA' elif int(temp) == 12: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '12: Kühlen WWA' elif int(temp) == 13: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '13: Kühlen PWA' elif int(temp) == 14: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '14: Kühlen WWA PWA' elif int(temp) == 15: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '15: WWA PWA' elif int(temp) == 16: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = '16: Störung' else: cd.WP.Waermeverteiler.Betriebsdaten.Statustext = temp cd.WP.Warmwasserkreis.Betriebsdaten.IstTempTBWarmwasser = web2com_values('/1/2/7/121/1') cd.WP.Warmwasserkreis.Betriebsdaten.SollwertWarmwassertemperatur = web2com_values('/1/2/7/121/2') temp = web2com_values('/1/2/7/121/0') cd.WP.Warmwasserkreis.Betriebsdaten.StatusWarmwasser = temp if int(temp) == 0: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '0: Abgeschaltet' elif int(temp) == 1: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '1: Normal Ladebetrieb' elif int(temp) == 2: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '2: Komfort Ladebetrieb' elif int(temp) == 3: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '3: Zwangsdrosselung' elif int(temp) == 4: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '4: Zwangsladung' elif int(temp) == 5: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '5: Störung' elif int(temp) == 6: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '6: WW Entnahme aktiv' elif int(temp) == 7: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = '7: Warnung' else: cd.WP.Warmwasserkreis.Betriebsdaten.Statustext = temp cd.WP.Zusatzheizung.Betriebsdaten.Betriebsstunden = web2com_values('/1/2/2/126/4') cd.WP.Zusatzheizung.Betriebsdaten.HeizenergieMWh = web2com_values('/1/2/2/126/6') cd.WP.Zusatzheizung.Betriebsdaten.HeizenergiekWh = web2com_values('/1/2/2/126/5') cd.WP.Zusatzheizung.Betriebsdaten.IstTempVWV = web2com_values('/1/2/2/126/1') cd.WP.Zusatzheizung.Betriebsdaten.Schaltzyklen = web2com_values('/1/2/2/126/3') cd.WP.Zusatzheizung.Betriebsdaten.VorlauftempSollwertAnforderung = web2com_values('/1/2/2/126/2') temp = web2com_values('/1/2/2/126/0') cd.WP.Zusatzheizung.Betriebsdaten.StatusWaermeerzeuger = temp if int(temp) == 0: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '0: Abgeschalten' elif int(temp) == 1: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '1: Heizbetrieb' elif int(temp) == 2: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '2: Vorlaufzeit Heizbetrieb' elif int(temp) == 3: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '3: Extern gesperrt' elif int(temp) == 4: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '4: Kühlbetrieb' elif int(temp) == 5: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '5: Vorlaufzeit Kühlbetrieb' elif int(temp) == 6: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '6: Vorlaufzeit Abtaubetrieb' elif int(temp) == 7: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '7: Abtaubetrieb' elif int(temp) == 8: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '8: Störung' elif int(temp) == 9: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '9: Abtropfen' elif int(temp) == 10: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '10: Abtausperrzeit' elif int(temp) == 11: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '11: Abtau Vorheizung' elif int(temp) == 12: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '12: Abtauen 1' elif int(temp) == 13: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '13: Abtauen 2' elif int(temp) == 14: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '14: Abtauen 3' elif int(temp) == 15: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '15: Alarm' elif int(temp) == 16: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '16: Störung' elif int(temp) == 17: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '17: Blockiert' elif int(temp) == 18: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '18: Vorglühen' elif int(temp) == 19: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '19: Eindüsung Ein' elif int(temp) == 20: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '20: Eindüsung Aus' elif int(temp) == 21: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '21: TWVmax Abschaltung' elif int(temp) == 22: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '22: TWVsoll Abschaltung' elif int(temp) == 23: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '23: TWEmax Abschaltung' elif int(temp) == 24: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '24: TWAmin Abschaltung' elif int(temp) == 25: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '25: TKAmin Abschaltung' elif int(temp) == 26: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '26: Bivalenzabschaltung' elif int(temp) == 27: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '27: Warmwasser Ladesperre' elif int(temp) == 28: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '28: Minimale Auszeit' elif int(temp) == 29: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '29: Minimale Einzeit' elif int(temp) == 30: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '30: Anheizen' elif int(temp) == 31: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '31: Ausbrand' elif int(temp) == 32: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '32: Pumpen-Nachlauf' elif int(temp) == 33: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '33: Verzögerung Folge-WE' elif int(temp) == 34: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '34: Betrieb Uebertemperatur' elif int(temp) == 35: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '35: Fülltüre geöffnet' elif int(temp) == 36: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '36: Passivkühlung' elif int(temp) == 37: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '37: Heizbetrieb angefordert' elif int(temp) == 38: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = '38: Kühlbetrieb angefordert' else: cd.WP.Zusatzheizung.Betriebsdaten.Statustext = temp
Die folgende Zeile ist vielleicht auch noch interessant:
Code:
cd.WP.Waermepumpe.Betriebsdaten.Leistung = 60/1000*cd.WP.Waermepumpe.Betriebsdaten.VolumenstromWaermequelle*abs(cd.WP.Waermepumpe.Betriebsdaten.IstTempTQA-cd.WP.Waermepumpe.Betriebsdaten.IstTempTQE)*1.163
cd.WP.Waermepumpe.Betriebsdaten.VolumenstromWaerme quelle -> liegt in l/min vor -> also erstmal durch 1000, damit wir m³/min bekommen -> dann mal 60 für m³/h
alle weiteren Werte bleiben und die Einheiten lassen sich wunderbar soweit wegkürzen, dass nur noch "Watt" übrig bleiben.
Jetzt haben wir die Logik als Grundlage.
Die nutze ich schon mal für die Detailanzeigen in CD:
Detailansicht.png
5. Schritt: Grafiken erstellen
Wie oben gezeigt, möchte ich gerne die beiden Grafiken in die Visu integrieren:
Ochsner-AnzeigeWP.png
Dafür hab ich beide in LibreOffice Draw einfach nachgezeichnet und als SVG einzeln exportiert.
Draw-Widgetanzeige.png
Da kommt dann erstmal ganz viel Müll in der SVG mit an (Nur ein Auszug daraus):
Code:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.2" width="103mm" height="51.12mm" viewBox="2900 6000 10300 5112" preserveAspectRatio="xMidYMid" fill-rule="evenodd" stroke-width="28.222" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" xmlns:ooo="http://xml.openoffice.org/svg/export" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:presentation="http://sun.com/xmlns/staroffice/presentation" xmlns:smil="http://www.w3.org/2001/SMIL20/" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xml:space="preserve"> <defs class="ClipPathGroup"> <clipPath id="presentation_clip_path" clipPathUnits="userSpaceOnUse"> <rect x="2900" y="6000" width="10300" height="5112"/> </clipPath> </defs> <defs> <font id="EmbeddedFont_1" horiz-adv-x="2048"> <font-face font-family="Liberation Sans embedded" units-per-em="2048" font-weight="normal" font-style="normal" ascent="1852" descent="423"/> <missing-glyph horiz-adv-x="2048" d="M 0,0 L 2047,0 2047,2047 0,2047 0,0 Z"/> <glyph unicode="°" horiz-adv-x="609" d="M 696,1145 C 696,1106 689,1069 674,1034 659,999 638,969 612,944 586,918 556,898 521,883 486,868 448,860 409,860 370,860 333,868 298,883 263,898 233,918 207,944 181,969 160,999 145,1034 130,1069 122,1106 122,1145 122,1185 130,1222 145,1257 160,1292 181,1322 207,1348 233,1373 263,1393 298,1408 333,1423 370,1430 409,1430 448,1430 486,1423 521,1408 556,1393 586,1373 612,1348 638,1322 659,1292 674,1257 689,1222 696,1185 696,1145 Z M 587,1145 C 587,1170 583,1193 574,1215 565,1237 552,1256 536,1273 520,1289 501,1302 480,1311 458,1320 434,1325 409,1325 384,1325 361,1320 340,1311 318,1302 299,1289 283,1273 267,1256 254,1237 245,1215 236,1193 231,1170 231,1145 231,1120 236,1097 245,1076 254,1054 267,1035 283,1019 299,1002 318,989 340,980 361,970 384,965 409,965 434,965 458,970 480,980 501,989 520,1002 536,1019 552,1035 565,1054 574,1076 583,1097 587,1120 587,1145 Z"/> <glyph unicode="t" horiz-adv-x="531" d="M 554,8 C 527,1 499,-5 471,-10 442,-14 409,-16 372,-16 228,-16 156,66 156,229 L 156,951 31,951 31,1082 163,1082 216,1324 336,1324 336,1082 536,1082 536,951 336,951 336,268 C 336,216 345,180 362,159 379,138 408,127 450,127 467,127 484,128 501,131 517,134 535,137 554,141 L 554,8 Z"/> .....
example.png
Code:
<svg width="300" height="168" viewBox="0 0 900 500"> <text class="Fussbodenheizung" font-family="sans-serif" font-size="63px" x="485" y="329">-°C</text> <text class="Aussentemperatur" font-family="sans-serif" font-size="63px" x="5" y="159">-°C</text> <text class="Warmwasser" font-family="sans-serif" font-size="63px" x="705" y="192">-°C</text> <text class="Innentemp" font-family="sans-serif" font-size="63px" x="425" y="192">-°C</text> <text class="Status" font-family="sans-serif" font-size="63px" x="200" y="492">...</text> <g fill="none" stroke="rgb(0,0,0)" stroke-width="20"> <path d="M 290,130 L 520,10"/> <path d="M 350,400 L 350,100"/> <path d="M 300,400 L 1020,400"/> </g> <g fill="none" stroke="rgb(0,0,0)" stroke-width="10"> <path d="M 390,250 L 760,250"/> <path d="M 440,290 L 470,290"/> <path d="M 390,370 L 760,370"/> <path d="M 759,250 C 759,250 759,250 760,250 763,250 766,250 770,252 773,254 775,256 777,260 779,263 780,266 780,270 780,273 779,276 777,280 775,283 773,285 770,287 766,289 763,290 760,290 759,290 759,290 759,290"/> <path d="M 759,330 C 759,330 759,330 760,330 763,330 766,330 770,332 773,334 775,336 777,340 779,343 780,346 780,350 780,353 779,356 777,360 775,363 773,365 770,367 766,369 763,370 760,370 759,370 759,370 759,370"/> <path d="M 441,330 C 440,330 440,330 440,330 436,330 433,329 430,327 427,325 424,323 423,320 421,316 420,313 420,310 420,306 421,303 423,300 424,296 427,294 430,292 433,290 436,290 440,290 440,290 440,290 441,290"/> <path d="M 690,290 L 760,290"/> <path d="M 440,330 L 470,330"/> <path d="M 690,330 L 760,330"/> </g> <g fill="none" stroke="rgb(0,0,0)" stroke-width="5"> <path d="M 191,45 C 200,45 206,52 206,60 206,69 200,75 191,75 183,75 176,69 176,60 176,52 183,45 191,45 Z"/> <path d="M 196,45 L 206,25"/> <path d="M 206,55 L 226,45"/> <path d="M 206,65 L 226,75"/> <path d="M 196,75 L 206,95"/> <path d="M 186,75 L 176,95"/> <path d="M 94,29 C 97,26 100,23 103,21 106,20 109,18 112,17 115,16 117,14 121,14 124,14 127,14 130,14 133,14 136,16 139,17 142,19 144,23 147,24 150,26 153,28 156,28 159,29 162,31 165,32 167,33 171,33 174,34 177,36 179,38 181,41 182,44 182,47 181,50 179,53 175,54 172,56 169,58 166,60 163,62 160,63 157,62 154,64 152,66 149,67 147,70 146,74 142,75 139,77 136,79 133,80 130,81 127,81 124,81 121,80 118,78 116,78 113,77 110,76 106,75 104,73 101,71 99,67 96,65 92,63 90,62 87,60 84,59 81,58 79,55 77,52 77,49 77,46 77,43 79,40 82,38 84,36 88,35 90,33 L 93,31 95,29 94,29 Z"/> <path d="M 394,179 L 387,179 387,155 400,155 400,179 394,179 Z"/> <path d="M 394,176 C 403,176 409,183 409,191 409,200 403,206 394,206 386,206 379,200 379,191 379,183 386,176 394,176 Z"/> <path d="M 388,136 L 388,179"/> <path d="M 400,136 L 400,179"/> <path d="M 388,136 C 388,135 388,134 388,133 389,132 390,131 391,130 392,130 393,130 394,130 395,130 396,130 397,130 398,131 399,132 400,133 400,134 400,135 400,136 400,136 400,136 400,136"/> <path d="M 400,177 C 401,178 403,178 404,179 406,181 408,183 409,186 410,188 410,191 409,193 409,196 408,198 406,201 405,203 403,204 400,205 397,206 395,206 392,206 389,206 387,205 385,203 383,201 381,199 380,197 379,194 379,192 380,189 380,186 381,184 383,182 384,180 386,178 389,177"/> <path d="M 831,109 L 739,109 762,87 808,87 831,109 Z"/> <path d="M 761,109 L 740,130"/> <path d="M 782,109 L 768,130"/> <path d="M 831,130 L 810,109"/> <path d="M 803,130 L 789,109"/> <path d="M 785,88 L 785,67"/> <path d="M 785,67 C 785,60 792,60 792,60 L 813,60 820,60"/> </g> <g fill="rgb(0,0,0)" stroke="none"> <path d="M 394,179 L 387,179 387,155 400,155 400,179 394,179 Z"/> <path d="M 394,176 C 403,176 409,183 409,191 409,200 403,206 394,206 386,206 379,200 379,191 379,183 386,176 394,176 Z M 379,176 L 379,176 Z M 410,207 L 410,207 Z"/> </g> </svg>
Ab hier übergebe ich an Waldemar für die Erstellung der zugehörigen:
- __init__.py
- widget.js für die Darstellung der Item-Werte
- widget.css für die eingentliche Darstellung (Font, Farbe etc.) der class-Attribute
Grüße
Thorsten
Merken
Merken
Kommentar