Bin aufgrund von persönlichen Umständen im letzten Jahr nicht zu viel gekommen. Ich habe aber vor, mir - ggf. ab Anfang des Jahres - das Plugin wie ja mal angedacht genauer anzusehen. Derzeit arbeite ich noch mit vcontrold, vclient und dem network-Plugin...
Ankündigung
Einklappen
Keine Ankündigung bisher.
Plugin: Viessmann Heizung auslesen (Vitodens200 / 300 mit Vitotronic 200 (HO1))
Einklappen
X
-
Zitat von loeserman Beitrag anzeigennein es gibt kein Update. Nutze es immer noch so. Läuft nun schon ewig ohne Probleme.
Würde eigentlich was dagegen sprechen, das Plugin zum offiziellen Bestandteil von shNG zu machen?
Gibt es auch schon die Funktion, die Heizung zu steuern?
Kommentar
-
Von meiner Seite spricht da nichts gegen. Wie kann man es denn da einbringen und was ist ggf. zu tun?
Für das Schreiben hatte ich schon etwas vorbereitet, das setze ich aber nicht ein. Das einzige was mich interessiert hätte wäre die Zirkulationspumpe, aber die kann ich wohl bei meiner Heizung nicht extern steuern. Sie reagiert nur auf die Zeitkurve, die man in der Heizung einstellt. Auch weiß ich nicht, wie oft man etwas einstellen kann (Stichwort RAM und ROM).
Kommentar
-
Zitat von loeserman Beitrag anzeigenHast du es denn mal probiert? Geht es bei Dir denn?
Ziel ist sicher die Werte auszulesen, aber auch diverse Werte setzen. Dazu gehören die Betriebsart, aber auch die Sollraumtemperatur.
Im Plugin hattest Du ja schon etwas vorbereitet. Was muss ich tun, um das zu nutzen?
Laut openv wiki würde es bspw so gehen:
Beispiel Vitodens 333 Betriebsart schreiben:- Senden 0x41 06 00 02 23 23 01 XY xx
- Empfangen 0x06 41 06 01 02 23 23 01 01 xx
- XY:
- 0 = Abschalten
- 1 = nur WW
- 2 = Heizen mit WW
- 3 = immer Reduziert
- 4 = immer Normal
- XY:
Kommentar
-
Hi,
also ich habe nochmal nachgesehen. Ehrlich gesagt habe ich da nur einen Test gemacht um einen Wert zu schreiben. Ich denke auch das das so geht. Mein einziges Ziel war es, dass ich die Zirkulationspumpe von der Hausautomation aus einschalten und abschalten wollte. Es stand zwar überall, dass genau dieser Wert leider nicht geschrieben werden kann aber ich wollte es dennoch probieren. Leider ist der Wert aber wirklich nicht schreibbar :-(
Aber die Art und Weise sollte schon so gehen für die Werte die beschrieben werden dürfen. Aber ich habe das nicht über die Config selbst gelöst sondern hatte hier eine dedizierte Funktion im Plugin nur für diesen einen Wert, den ich schreiben wollte. Vielleicht hilft es Dir aber trotzdem etwas weiter.
Auszug aus item.conf
Code:[ZAEHLER] [[HEIZUNG]] [MARKIEREN][[[SET_ZIRKULATION]]][/MARKIEREN] name = Zirkulationspumpe ein/ausschalten type = bool value = False pluginusage = viessmann # Wird vom angegebenen Plugin verwendet [MARKIEREN]pluginfct = setcirculationpump # Funktion, dieses items[/MARKIEREN]
Code:# Def: parse_item # Beschreibung von: https://github.com/mknx/smarthome/wiki/Write-a-plugin-5-minutes # The function parse_item is called for each item during startup when # smarthome.py reads the item.conf file. You can access item parameters # and start according action here. For example you have the following # item defined in …/items/smarthome.conf # # Items für dieses Plugin verfügen über mehrere Attribute # + pluginusage = viessmann # + plugintagid = z.B. brennerstarts # + pluginreduction = 1 # + ... # Ist es ein Item für dieses Plugin so trägt es auch ein weiteres Attribut namens "plugintagid" # Hierüber können mehrere zu einem Plugin gehörende Items klar definiert und verwendet werden # ohne, dass der eigentliche Item Name/Pfad eine bestimmte Nomenklatur aufweisen müssen. def parse_item(self, item): # Prüfung ob ein Item existiert mit dem attribut "pluginusage" if (('pluginusage' in item.conf) and ('plugintagid' in item.conf) and ('pluginvcode' in item.conf) and ('pluginreduction' in item.conf)): # Prüfung ob dieses Attribut den Namen "viessmann" trägt if ((item.conf['pluginusage'] == 'viessmann') and ('pluginvcode' in item.conf)): # String aus der Config wird in einen bytestring gewandelt # Beispiel: "4105000108A704B9" --> b'\x41\x05\x00\x01\x08\xA7\x04\xB9' vcodebytestring = binascii.a2b_hex(item.conf['pluginvcode']) if (self._checkChecksum(vcodebytestring) == True): # Speichern des Items unter seinem "plugintagid" Namen im # Plugin eigenen Item-Dictionary self._items[item.conf['plugintagid']] = item # Maximale Untersetzung ermitteln anhand der Daten aus der Config # Dient dazu den aktuellen Zähler immer wieder von 1 zu starten. self._maxreduction = max(self._maxreduction, int(item.conf['pluginreduction'])) # Eintrag in den Log self.logger.info('Plugin viessmann - Item added: {}'.format(item.conf['plugintagid'])) else: # Checksumme für das Item (Sendecode) ist nicht korrekt messagetext = 'Plugin viessmann - Falsche Checksumme für den vcode (Sendecode {}}, Item not added: {}, '.format(vcodebytestring, item.conf['plugintagid']) self.logger.error(messagetext) elif (('pluginusage' in item.conf) and ('pluginfct' in item.conf) ): if ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'lastreadtime')): self._itemlastread = item elif ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'readtrigger')): return self.update_item [MARKIEREN]elif ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'setcirculationpump')):[/MARKIEREN] [MARKIEREN]return self.update_item[/MARKIEREN] return None ... # Def: update_item # Nur der Vollständigkeit halber hier mit aufgelistet def update_item(self, item, caller=None, source=None, dest=None): #if caller != 'plugin': self.logger.info("Plugin viessmann - Item update item: {0}".format(item.id())) if (('pluginusage' in item.conf) and ('pluginfct' in item.conf)): # Prüfung ob dieses Attribut den Namen "viessmann" trägt und es sich um das # Item zum erneuten Lesen handelt if ((item() == True) and (item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'readtrigger')): # Damit alle Werte gelesen werden muss die Untersetzung # auf den Inititialisierungswert gesetzt werden. self._actreduction = 0 # Lese Funktion manuell ausführen self._readCyclicData() # Rücksetzen des Trigger Items item('off') [MARKIEREN]if ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'setcirculationpump')):[/MARKIEREN] [MARKIEREN]# Zirkulationspumpe schalten[/MARKIEREN] [MARKIEREN]self._writeCircPump(item())[/MARKIEREN] [MARKIEREN]# Lese Funktion manuell ausführen[/MARKIEREN] [MARKIEREN]self._readCyclicData()[/MARKIEREN] ... # Schreiben der Zirkulationspumpe [MARKIEREN]def _writeCircPump(self, seton):[/MARKIEREN] self.logger.info('Plugin viessmann - WRITE - Write circulation pump : {}'.format(seton)) # Standard Rückgabewert definieren (Lesen nicht erfolgreich) returnvalue = False if (seton == True): # Code on vcodestring = "410600026515010386" else: vcodestring = "410600026515010285" # String aus der Config wird in einen bytestring gewandelt # Beispiel: "410600026515010184" --> b'\x41\x06\x00\x02\x65\x15\x01\x01\x84' vcodebytestring = binascii.a2b_hex(vcodestring) # Vorvorletztes Byte ermitteln # Anfrage 41 06 00 02 65 15 01 03 86 # -- # LÄNGE vcodelengthbyte = vcodebytestring[-3:] vcodelengthbyte = vcodelengthbyte[:1] # Aus dem Byte den ASCII-Zahlenwert ermitteln. Diese Länge wird für den Dateninhalt der Antwort genutzt # Es müssen noch die Zusatzdaten mit addiert werden (diese sind immer +9) # Antwort 06 41 06 01 02 65 15 01 01 85 # -- -- -- -- # OK DA CS vcode_responselen = ord(vcodelengthbyte) vcode_responsetotallen1 = vcode_responselen + 9 vcode_responsetotallen = 10 # ByteString für den Rückgabewert bytestring = b'' # Schnittstelle ist bereit. Kommando kann gesendet werden. vcodestring = vcodestring # String aus der Config wird in einen bytestring gewandelt # Beispiel: "410600026515010184" --> b'\x41\x06\x00\x02\x65\x15\x01\x01\x84' vcodebytestring = binascii.a2b_hex(vcodestring) self.logger.error('Plugin viessmann - WRITE - --------- Write zirkulation, sende bytestring : {}, erwartete antwortlänge : {}'.format(vcodebytestring, vcode_responsetotallen1)) self._writeBytes(vcodebytestring) # Rückgabebytestring einlesen k = 0 while k < vcode_responsetotallen: # Byte von Schnittstelle lesen self.logger.debug('Plugin viessmann - WRITE - --------- Write zirkulation, Read byte for : {}, index k : {}, kmax : {}, responselen : {}, lengthbyte : {}'.format(vcodebytestring, k, vcode_responsetotallen, vcode_responselen, vcodelengthbyte)) readbyte = self._readByte() self.logger.debug('Plugin viessmann - WRITE - --------- Write zirkulation, Readed byte : {}'.format(readbyte)) # Erstes und letztes Byte muss b'\x06' sein (Bedeutung: OK der Daten) # Wenn dies nicht der Fall ist, wird abgebrochen #if ((k == 0) or (k == (vcode_responsetotallen - 1))): if (k == 0): if not (self._lastbyte == b'\x06'): # Bytestring zurücksetzen bytestring = b'' break else: # Schreiben des Readbyte Strings bestehend aus # allen gelesenen Bytes bis auf b'\x06' am # Anfang und am Ende (Bsp.: 41 06 01 02 65 15 01 01 85) bytestring = bytestring + self._lastbyte # Schleifenzähler inkrementieren k = k + 1 self.logger.debug('Plugin viessmann - WRITE - --------- Write zirkulation, Empfangs bytestring : {}'.format(bytestring)) # Prüfung ob alle Daten gelesen wurden. Hierzu kann geprüft werden # ob die Länge der Bytestring der erwarteten Länge minus die beiden # b'\x06' Bytes am Anfang und Ende entspricht. if (len(bytestring) == (vcode_responsetotallen - 1)): # Entspricht das erste Byte b'\x41' bytestring_extract = bytestring[:1] if (bytestring_extract == b'\x41'): # Bytestring startet mit dem Identifier für den Telegramstart # Mit dem String kann weiter gearbeitet werden # Prüfung ob die Checksumme in Ordnung ist if (self._checkChecksum(bytestring) == True): # Gelesene Bytes aus dem Array auswerten # Datenbytes extrahieren bytestring_extract = bytestring[(((-1) * vcode_responselen) - 1):] bytestring_extract = bytestring_extract[:vcode_responselen] messagetext = 'Plugin viessmann - WRITE - Datenbytes extrahiert. Read Databytes : {}'.format(bytestring_extract) self.logger.info(messagetext) # Wert wurde erfolgreich gelesen und das Item geschrieben returnvalue = True else: messagetext = 'Plugin viessmann - WRITE - Checksumme fehlerhaft. Readed bytestring : {}'.format(bytestring) self.logger.error(messagetext) else: messagetext = 'Plugin viessmann - WRITE - Gelesener Bytestring startet nicht mit \x41. Readed bytestring : {}'.format(bytestring) self.logger.error(messagetext) else: messagetext = 'Plugin viessmann - WRITE - Gelesener Bytestring hat nicht die korrekte Länge. Erwartete Länge : {}, Readed bytestring : {}'.format((vcode_responsetotallen - 1), bytestring) self.logger.error(messagetext) # Rückgabe, ob der Wert erfolgreich gelesen und das Item geschrieben wurde return returnvalue
Kommentar
-
Zitat von loeserman Beitrag anzeigenWie ich gesehen habe baust Du ja gerade ein verbessertes viessmann plugin. Sollte das auch für meine Heizung gehen? Dann kann ich das ja auch mal ausprobieren.
Ja, ich baue gerade basierend auf deinem Plugin eine andere Version des Plugin. Vieles geht schon.
Gern kannst Du es testen. Ich melde mich, wenn ich soweit bin.
Beste Grüße
Kommentar
Kommentar