Hallo zusammen,
in einem anderen Thread kam die Frage nach meinem viessmann Plugin. Daher möchte ich es hier gern vorstellen. Ich bin selbst mit den vcontrold und dem vclient nicht zurechtgekommen, daher habe ich mich dann selbst ans Werk gemacht und habe ein eigenes Plugin geschrieben. Es ist natürlich auf meine Heizung und Konfiguration zugeschnitten aber ich denke es kann auch anderen helfen eine Viessmann Heizung auszulesen.
Zunächst an der Stelle vielen Dank an die Seite https://github.com/openv/openv über die ich die meisten Informationen bezogen habe.
Leider nicht alle, es musst auch einiges "ertüftelt" werden.
Ich habe eine Vitodens 343F (Gas-Brennwertkessel mit witterungsgeführter Kessel- und Heizkreisregelung für 2 Heizkreise). Hiervon ist einer mit Mischer und einer ohne.
Der folgende Screeshot zeigt, was ich alles auslese. Dies habe ich gemacht, da ich viele Probleme im Vorfeld mit der Heizung hatte und nun immer up to date bleiben wollte, ob es der Heizung gut geht oder nicht.
screenshot.jpg
Als Auslesegerät verwende ich den USB Optolink von der folgenden Seite, der hier auch kostengünstig bestellt werden kann.
https://github.com/openv/openv/wiki/Bauanleitung-USB
Mit diesem habe ich dann mal mit einem Windows System einen ersten Test gemacht. Hierzu habe ich das Programm vControl verwendet.
https://github.com/openv/openv/wiki/v-control
Schaut man sich hier den Log an, sieht man schon in etwa, wie die Heizung kommuniziert.
Der folgende Block gibt Auskunft über das Protokoll und die Heizung selbst:
Ein Blick in die Geräteliste https://github.com/openv/openv/wiki/Ger%C3%A4te zeigt, dass es sich um die folgende Heizung handelt:
20 CB = VScotHO1, 300,KW, Vitodens200 / 300 mit Vitotronic 200 (HO1), Gas-Brennwertkessel mit witterungsgeführter Kessel- und Heizkreisregelung für 2 Heizkreise mit Mischer und 1 Heizkreis ohne Mischer
Um die Nutzdaten genauer zu verstehen lohnt sich ein Blick in den Telegrammaufbau, der ebenfalls auf der Seite openv beschrieben ist:
https://github.com/openv/openv/wiki/Protokoll-300
Das Schwierige ist es später herauszufinden, wie die Datenpunkte genau heißen, die abgefragt werden sollen. Auch hier gibt es Listen auf der nun viel zitierten Seite. Allerdings habe ich hier nicht alles finden können und musste mir das über die verschiedensten Seiten zusammensuchen.
https://github.com/openv/openv/wiki/Adressen
Nun aber zum eigentlichen Plugin. Es funktioniert genau für meine Heizung und läuft schon sehr lange absolut reibungslos. Das USB Interface habe ich mit einem Link versehen, so dass ich es immer unter dem Namen "ttyUSB_HEIZUNG" ansprechen kann. Hier muss dann natürlich euer Device entsprechend eingetragen sein.
Wichtig zu verstehen ist, dass dieses Plugin aktuell nur Daten liest. Es ist etwas vorbereitet für das Schreiben, allerdings habe ich hier nicht weitergemacht. Ich wollte meine Zirkulationspumpe manuell starten. Das ist aber wohl bei dem Modell nicht möglich. Schade, ansonsten hätte ich es morgens einfach eingeschaltet, wenn ich auch warmes Wasser brauche und nicht einfach nach der integrierten Zeitschaltuhr.
Das Plugin ermittelt die zugehörigen items selbst. Diese haben ein paar zusätzliche Parameter. Somit ist es dem Plugin egal, wie die Items in euren Config Files benannt werden. Die zusätzlichen Parameter sind ebenfalls kommentiert. Wichtig ist hier noch der Parameter "pluginreduction". Hiermit kann man die Abfrage untersetzen. So wird dieser Wert nicht bei jeder Abfrage abgefragt.
Beispiel für die item:
Die vollständige Liste meiner Items hänge ich auch mal an. Da kann man ggf. die Codes entnehmen.
Plugin code
\plugins\viessmann\__init__.py
Zum Schluss muss das Plugin dann noch in smarthome eingebettet und aufgerufen werden. Das passiert natürlich über die plugin.yaml
plugin.yaml
Das ist schon alles einige Zeit her. Ich denke einiges ist beschrieben. Die Fragen kommen sicherlich beim Probieren. Vielleicht kann ich dann helfen. Ansonsten einfach mal ausprobieren, wer es mag.
Gruß
loeserman
in einem anderen Thread kam die Frage nach meinem viessmann Plugin. Daher möchte ich es hier gern vorstellen. Ich bin selbst mit den vcontrold und dem vclient nicht zurechtgekommen, daher habe ich mich dann selbst ans Werk gemacht und habe ein eigenes Plugin geschrieben. Es ist natürlich auf meine Heizung und Konfiguration zugeschnitten aber ich denke es kann auch anderen helfen eine Viessmann Heizung auszulesen.
Zunächst an der Stelle vielen Dank an die Seite https://github.com/openv/openv über die ich die meisten Informationen bezogen habe.
Leider nicht alle, es musst auch einiges "ertüftelt" werden.
Ich habe eine Vitodens 343F (Gas-Brennwertkessel mit witterungsgeführter Kessel- und Heizkreisregelung für 2 Heizkreise). Hiervon ist einer mit Mischer und einer ohne.
Der folgende Screeshot zeigt, was ich alles auslese. Dies habe ich gemacht, da ich viele Probleme im Vorfeld mit der Heizung hatte und nun immer up to date bleiben wollte, ob es der Heizung gut geht oder nicht.
screenshot.jpg
Als Auslesegerät verwende ich den USB Optolink von der folgenden Seite, der hier auch kostengünstig bestellt werden kann.
https://github.com/openv/openv/wiki/Bauanleitung-USB
Mit diesem habe ich dann mal mit einem Windows System einen ersten Test gemacht. Hierzu habe ich das Programm vControl verwendet.
https://github.com/openv/openv/wiki/v-control
Schaut man sich hier den Log an, sieht man schon in etwa, wie die Heizung kommuniziert.
Code:
[FONT=courier new]22-11-2016 13:42:22 DATA Init 22-11-2016 13:42:22 COMM Init auf COM3 22-11-2016 13:42:22 DATA TX: 16 0 0 22-11-2016 13:42:23 COMM Comm Port OK 22-11-2016 13:42:23 COMM Verbunden: COM3 22-11-2016 13:42:24 DATA Lese: Version 22-11-2016 13:42:24 DATA TX: 41 5 0 1 0 F8 2 0 22-11-2016 13:42:24 DATA RX: 6 41 7 1 1 22-11-2016 13:42:24 DATA RX: 0 F8 2 20 CB EE 22-11-2016 13:42:24 SYS Version: VScotHO1 22-11-2016 13:42:25 DATA Lese Daten 22-11-2016 13:42:25 DATA TX: 41 5 0 1 8 8A 4 9C 22-11-2016 13:42:25 DATA RX: 6 41 22-11-2016 13:42:25 DATA RX: 9 1 1 8 8A 4 80 22-11-2016 13:42:25 DATA RX: 5 1 0 27 22-11-2016 13:42:25 DATA TX: 41 5 0 1 55 25 2 82 22-11-2016 13:42:25 DATA RX: 6 22-11-2016 13:42:25 DATA RX: 41 7 1 1 55 25 22-11-2016 13:42:25 DATA RX: 2 70 0 F5 22-11-2016 13:42:25 DATA TX: 41 5 0 1 55 27 2 84 22-11-2016 13:42:25 DATA RX: 6 41 7 1 22-11-2016 13:42:25 DATA RX: 1 55 27 2 61 0 22-11-2016 13:42:25 DATA RX: E8 22-11-2016 13:42:25 DATA TX: 41 5 0 1 55 5A 2 B7 22-11-2016 13:42:25 DATA RX: 6 41 7 1 22-11-2016 13:42:25 DATA RX: 1 55 5A 2 32 0 22-11-2016 13:42:25 DATA RX: EC 22-11-2016 13:42:25 DATA TX: 41 5 0 1 8 10 2 20 22-11-2016 13:42:25 DATA RX: 6 22-11-2016 13:42:25 DATA RX: 41 7 1 1 8 10 22-11-2016 13:42:25 DATA RX: 2 8D 2 B2 22-11-2016 13:42:25 DATA TX: 41 5 0 1 8 8 2 18 22-11-2016 13:42:25 DATA RX: 6 41 7 22-11-2016 13:42:25 DATA RX: 1 1 8 8 2 51 2 22-11-2016 13:42:25 DATA RX: 6E 22-11-2016 13:42:25 DATA TX: 41 5 0 1 8 96 2 A6 22-11-2016 13:42:25 DATA RX: 6 22-11-2016 13:42:25 DATA RX: 41 7 1 1 8 96 22-11-2016 13:42:25 DATA RX: 2 C8 0 71[/FONT]
Code:
[FONT=courier new]22-11-2016 13:42:24 DATA Lese: Version 22-11-2016 13:42:24 DATA TX: 41 5 0 1 0 F8 2 0 22-11-2016 13:42:24 DATA RX: 6 41 7 1 1 22-11-2016 13:42:24 DATA RX: 0 F8 2 [COLOR=#FF0000]20 CB[/COLOR] EE 22-11-2016 13:42:24 SYS Version: VScotHO1[/FONT]
20 CB = VScotHO1, 300,KW, Vitodens200 / 300 mit Vitotronic 200 (HO1), Gas-Brennwertkessel mit witterungsgeführter Kessel- und Heizkreisregelung für 2 Heizkreise mit Mischer und 1 Heizkreis ohne Mischer
Um die Nutzdaten genauer zu verstehen lohnt sich ein Blick in den Telegrammaufbau, der ebenfalls auf der Seite openv beschrieben ist:
https://github.com/openv/openv/wiki/Protokoll-300
Das Schwierige ist es später herauszufinden, wie die Datenpunkte genau heißen, die abgefragt werden sollen. Auch hier gibt es Listen auf der nun viel zitierten Seite. Allerdings habe ich hier nicht alles finden können und musste mir das über die verschiedensten Seiten zusammensuchen.
https://github.com/openv/openv/wiki/Adressen
Nun aber zum eigentlichen Plugin. Es funktioniert genau für meine Heizung und läuft schon sehr lange absolut reibungslos. Das USB Interface habe ich mit einem Link versehen, so dass ich es immer unter dem Namen "ttyUSB_HEIZUNG" ansprechen kann. Hier muss dann natürlich euer Device entsprechend eingetragen sein.
Wichtig zu verstehen ist, dass dieses Plugin aktuell nur Daten liest. Es ist etwas vorbereitet für das Schreiben, allerdings habe ich hier nicht weitergemacht. Ich wollte meine Zirkulationspumpe manuell starten. Das ist aber wohl bei dem Modell nicht möglich. Schade, ansonsten hätte ich es morgens einfach eingeschaltet, wenn ich auch warmes Wasser brauche und nicht einfach nach der integrierten Zeitschaltuhr.
Das Plugin ermittelt die zugehörigen items selbst. Diese haben ein paar zusätzliche Parameter. Somit ist es dem Plugin egal, wie die Items in euren Config Files benannt werden. Die zusätzlichen Parameter sind ebenfalls kommentiert. Wichtig ist hier noch der Parameter "pluginreduction". Hiermit kann man die Abfrage untersetzen. So wird dieser Wert nicht bei jeder Abfrage abgefragt.
Beispiel für die item:
Code:
[ZAEHLER]
[[HEIZUNG]]
[[[AUSSENTEMPERATUR]]]
# Information Kessel Außentemperatur read 2-Byte -60..60 0x5525
# DATA TX: 41 5 0 1 55 25 2 82
# DATA RX: 41 7 1 1 55 25 2 EF 0 74 --> 00EF = 239 --> 23.9°C (Faktor 0.1)
# --> Senden 41 5 0 1 55 25 2 82
# -- - - - ----- - --
# | | | | | | +-- Prüfsumme (Summe über alley Bytes ohne die 41; [hex]5+0+1+55+25+2 = [dez]5+0+1+(5x16)+5+(2x16)+5+2 = 130dez = 82hex
# | | | | | +----- XX Anzahl der Bytes, die in der Antwort erwartet werden
# | | | | +--------- XX XX 2 byte Adresse der Daten oder Prozedur
# | | | +------------- XX 01 = ReadData, 02 = WriteData, 07 = Function Call
# | | +--------------- XX 00 = Anfrage, 01 = Antwort, 03 = Fehler
# | +----------------- Länge der Nutzdaten (Anzahl der Bytes zwischen dem Telegramm-Start-Byte (0x41) und der Prüfsumme)
# +------------------- Telegramm-Start-Byte
#
# --> Empfangen 6 41 7 1 1 55 25 2 EF 0 74
# - -- - - - ----- - ---- --
# | | | | | | | | +-- Prüfsumme (Summe über alley Bytes ohne die 41; [hex]7+1+1+55+25+2+EF+0 = [dez]7+1+1+(5x16)+5+(2x16)+5+2+(14*16)+(15*16)+0 = [dez]7+1+1+(80)+5+(32)+5+2+(224)+(15)+0 = 372dez = 1.74hex)
# | | | | | | | +------ Wert
# | | | | | | +---------- XX Anzahl der Bytes, die in der Antwort erwartet werden
# | | | | | +-------------- XX XX 2 byte Adresse der Daten oder Prozedur
# | | | | +------------------ XX 01 = ReadData, 02 = WriteData, 07 = Function Call
# | | | +-------------------- XX 00 = Anfrage, 01 = Antwort, 03 = Fehler
# | | +---------------------- Länge der Nutzdaten (Anzahl der Bytes zwischen dem Telegramm-Start-Byte (0x41) und der Prüfsumme)
# | +------------------------ Telegramm-Start-Byte
# +--------------------------- OK (Antwort auf 0x16 0x00 0x00 und auf korrekt empfangene Telegramme)
#
# --> Antwort: 0x00EF = 239 = 23.9°
name = Aussentemperatur [°C]
type = num
cache = True
database@mysqldb = init
knx_dpt = 9
knx_send = 5/2/0 # Temperatur auf den Bus schreiben für die Plus-Taster
[COLOR=#FF0000] pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = aussentemperatur # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = signed # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000155250282# Ende direkt hinter dem Byte String[/COLOR]
Code:
# -----------------------------------------------------------------------
# Items für die Heizung
# -----------------------------------------------------------------------
[ZAEHLER]
[[HEIZUNG]]
[[[READ]]]
name = Alle Werte sofort auslesen
type = bool
value = False
autotimer = 1 = False
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
pluginfct = readtrigger # Funktion, dieses items
[[[SET_ZIRKULATION]]]
name = Zirkulationspumpe ein/ausschalten
type = bool
value = False
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
pluginfct = setcirculationpump # Funktion, dieses items
[[[LAST_READ]]]
name = Letzter Lesevorgang
type = str
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
pluginfct = lastreadtime # Funktion, dieses items
[[[ALARMMESSAGE]]]
name = Heizung Alarmmeldung
type = bool
visu_acl = rw
value = False
[[[AUSSENTEMPERATUR]]]
# Information Kessel Außentemperatur read 2-Byte -60..60 0x5525
# DATA TX: 41 5 0 1 55 25 2 82
# DATA RX: 41 7 1 1 55 25 2 EF 0 74 --> 00EF = 239 --> 23.9°C (Faktor 0.1)
# --> Senden 41 5 0 1 55 25 2 82
# -- - - - ----- - --
# | | | | | | +-- Prüfsumme (Summe über alley Bytes ohne die 41; [hex]5+0+1+55+25+2 = [dez]5+0+1+(5x16)+5+(2x16)+5+2 = 130dez = 82hex
# | | | | | +----- XX Anzahl der Bytes, die in der Antwort erwartet werden
# | | | | +--------- XX XX 2 byte Adresse der Daten oder Prozedur
# | | | +------------- XX 01 = ReadData, 02 = WriteData, 07 = Function Call
# | | +--------------- XX 00 = Anfrage, 01 = Antwort, 03 = Fehler
# | +----------------- Länge der Nutzdaten (Anzahl der Bytes zwischen dem Telegramm-Start-Byte (0x41) und der Prüfsumme)
# +------------------- Telegramm-Start-Byte
#
# --> Empfangen 6 41 7 1 1 55 25 2 EF 0 74
# - -- - - - ----- - ---- --
# | | | | | | | | +-- Prüfsumme (Summe über alley Bytes ohne die 41; [hex]7+1+1+55+25+2+EF+0 = [dez]7+1+1+(5x16)+5+(2x16)+5+2+(14*16)+(15*16)+0 = [dez]7+1+1+(80)+5+(32)+5+2+(224)+(15)+0 = 372dez = 1.74hex)
# | | | | | | | +------ Wert
# | | | | | | +---------- XX Anzahl der Bytes, die in der Antwort erwartet werden
# | | | | | +-------------- XX XX 2 byte Adresse der Daten oder Prozedur
# | | | | +------------------ XX 01 = ReadData, 02 = WriteData, 07 = Function Call
# | | | +-------------------- XX 00 = Anfrage, 01 = Antwort, 03 = Fehler
# | | +---------------------- Länge der Nutzdaten (Anzahl der Bytes zwischen dem Telegramm-Start-Byte (0x41) und der Prüfsumme)
# | +------------------------ Telegramm-Start-Byte
# +--------------------------- OK (Antwort auf 0x16 0x00 0x00 und auf korrekt empfangene Telegramme)
#
# --> Antwort: 0x00EF = 239 = 23.9°
name = Aussentemperatur [°C]
type = num
cache = True
database@mysqldb = init
knx_dpt = 9
knx_send = 5/2/0 # Temperatur auf den Bus schreiben für die Plus-Taster
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = aussentemperatur # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = signed # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000155250282# Ende direkt hinter dem Byte String
[[[AUSSENTEMPERATUR_GEDAEMPFT]]]
# Information Kessel Außentemperatur gedaempft read 2-Byte -60..60 0x557
# DATA TX: 41 5 0 1 55 27 2 84
# DATA RX: 41 7 1 1 55 27 2 F5 0 7C --> 00F5 = 245 --> 24.5°C (Faktor 0.1)
name = Aussentemperatur gedaempft [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = aussentempgedaempft # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = signed # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000155270284# Ende direkt hinter dem Byte String
[[[BRENNERSTATUS]]]
# Brenner eingesachaltet
name = Brennerstatus
type = bool
cache = True
eval = True if (sh.ZAEHLER.HEIZUNG.BRENNER_LEISTUNG() > 0.0) else False
eval_trigger = ZAEHLER.HEIZUNG.BRENNER_LEISTUNG
[[[[ALTER]]]]
# Brenner eingesachaltet
name = Dauer des aktuellen Brennerstatus
type = num
# Berechnung minütlich
crontab = * * * * = 1 # crontab Minütlich - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = (sh.ZAEHLER.HEIZUNG.BRENNERSTATUS.age() / 60)
[[[[PREV_ALTER]]]]
# Brenner eingesachaltet
name = Dauer des Brennerstatus zuvor
type = num
# Berechnung minütlich
crontab = * * * * = 1 # crontab Minütlich - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = (sh.ZAEHLER.HEIZUNG.BRENNERSTATUS.prev_age() / 60)
[[[BRENNERSTARTS]]]
# Information Kessel Brennerstarts read 4-Byte 0..64000 0x088A
# DATA TX: 41 5 0 1 8 8A 4 9C
# DATA RX: 41 9 1 1 8 8A 4 48 F0 0 0 D9 --> 0000F048 = 61512 --> 61512 (Faktor 1)
name = Brennerstarts
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = brennerstarts # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001088A049C# Ende direkt hinter dem Byte String
[[[[LETZTE_STUNDE]]]]
name = Brennertstarts innerhalb der letzten Stunde
type = num
cache = True
# Berechnung stündlich
crontab = 0 * * * = 1 # crontab Stündlich - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = round((sh.ZAEHLER.HEIZUNG.BRENNERSTARTS() - sh.ZAEHLER.HEIZUNG.BRENNERSTARTS.db('min', '1h')), 1)
[[[[LETZTER_TAG]]]]
name = Brennertstarts innerhalb des letzten Tages
type = num
cache = True
database@mysqldb = init
# Berechnung täglich
crontab = 0 0 * * = 1 # crontab Täglich 0 Uhr - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = round((sh.ZAEHLER.HEIZUNG.BRENNERSTARTS() - sh.ZAEHLER.HEIZUNG.BRENNERSTARTS.db('min', '1d')), 1)
[[[ANLAGEN_LEISTUNG]]]
# Brenner Leistung
# DATA TX: 41 5 0 1 A3 8F 2 3A
# DATA RX: 41 7 1 1 A3 8F 2 0 0 3D --> 0000 = 0 --> Aus (Faktor 0.1)
name = Anlagenleistung
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = anlagenleistung # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001A38F023A# Ende direkt hinter dem Byte String
[[[BRENNER_LEISTUNG]]]
# Brenner Leistung
# DATA TX: 41 5 0 1 A3 05 2 B0
# DATA RX: 41 7 1 1 A3 05 2 0 0 B3 --> 0000 = 0 --> Aus (Faktor 0.1)
name = Brennerleistung
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = brennerleistung # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001A30502B0# Ende direkt hinter dem Byte String
[[[BETRIEBSSTUNDEN]]]
# Information Kessel Brenner Betriebsstunden read 4-Byte 0..64000 0x08A7
# DATA TX: 41 5 0 1 8 A7 4 B9
# DATA RX: 41 9 1 1 8 A7 4 CE 47 DD 0 B0 --> 00DD47CE = 14501838 --> 4028,28h (Faktor 1/3600)
name = Betriebsstunden [h]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = betriebsstunden # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 3600 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000108A704B9# Ende direkt hinter dem Byte String
[[[[LETZTE_STUNDE]]]]
name = Betriebsstunden innerhalb der letzten Stunde
type = num
cache = True
# Berechnung stündlich
crontab = 0 * * * = 1 # crontab Stündlich - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = round((sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN() - sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN.db('min', '1h')), 1)
[[[[LETZTER_TAG]]]]
name = Betriebsstunden innerhalb des letzten Tages
type = num
cache = True
database@mysqldb = init
# Berechnung täglich
crontab = 0 0 * * = 1 # crontab Täglich 0 Uhr - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = round((sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN() - sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN.db('min', '1d')), 1)
[[[BETRIEB_ZU_STARTS]]]
name = Brennertstarts / Betriebsstunden gesamt
type = num
cache = True
# Berechnung bei Änderung
eval = round((sh.ZAEHLER.HEIZUNG.BRENNERSTARTS() / sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN()), 1)
eval_trigger = ZAEHLER.HEIZUNG.BRENNERSTARTS | ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN
[[[[LETZTE_STUNDE]]]]
name = Brennertstarts / Betriebsstunden innerhalb der letzten Stunde
type = num
cache = True
# Berechnung stündlich
crontab = 0 * * * = 1 # crontab Stündlich - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = round(((sh.ZAEHLER.HEIZUNG.BRENNERSTARTS() - sh.ZAEHLER.HEIZUNG.BRENNERSTARTS.db('min', '1h')) / (sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN() - sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN.db('min', '1h'))), 1)
[[[[LETZTER_TAG]]]]
name = Brennertstarts / Betriebsstunden innerhalb des letzten Tages
type = num
cache = True
database@mysqldb = init
# Berechnung täglich
crontab = 0 0 * * = 1 # crontab Täglich 0 Uhr - Aufbau: mm(0..59) hh day(0..28) wday(0=Mo, 1=Di, 2=Mi, 3=Do, 4=Fr, 5=Sa, 6=So)
enforce_updates = True # Updates True, da der Crontab immer mit 1 ausführt und die Berechnung durchgeführt werden soll.
eval = round(((sh.ZAEHLER.HEIZUNG.BRENNERSTARTS() - sh.ZAEHLER.HEIZUNG.BRENNERSTARTS.db('min', '1d')) / (sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN() - sh.ZAEHLER.HEIZUNG.BETRIEBSSTUNDEN.db('min', '1d'))), 1)
[[[KESSELSOLLTEMPERATUR]]]
# Diagnose Kessel Kesselsolltemperatur read 2-Byte 0..127 0x555A
# DATA TX: 41 5 0 1 55 5A 2 B7
# DATA RX: 41 7 1 1 55 5A 2 32 0 EC --> 0032 = 50 --> 5.0°C (Faktor: 0.1)
name = Kesselsolltemperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = kesselsolltemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001555A02B7# Ende direkt hinter dem Byte String
[[[KESSELTEMPERATUR]]]
# Information Kessel Kesseltemperatur read 2-Byte 0..150 0x0810
# DATA TX: 41 5 0 1 8 10 2 20
# DATA RX: 41 7 1 1 8 10 2 7C 1 A0 --> 017C = 380 --> 38.0°C (Faktor: 0.1)
name = Kesseltemperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = kesseltemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000108100220# Ende direkt hinter dem Byte String
[[[ABGASTEMPERATUR]]]
# Abgastemperatur read 2-Byte 0..500 0x0816
# DATA TX: 41 5 0 1 8 16 2 26
# DATA RX: 41 7 1 1 8 16 2 7C 1 A6 --> 017C = 380 --> 38.0°C (Faktor: 0.1)
name = Abgastemperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = abgastemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000108160226# Ende direkt hinter dem Byte String
[[[WARMWASSERSOLLTEMPERATUR]]]
# Bedienung HK1 Betriebsdaten HK1 Warmwassersolltemperatur write 1-Byte 10 60 (90) 0x6300
# DATA TX: 41 5 0 1 63 0 1 6A
# DATA RX: 41 7 1 1 63 0 1 36 A2 --> 36 = 54 --> 54°C (Faktor: 1)
name = Warmwassertemperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = warmwassersolltemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 410500016300016A# Ende direkt hinter dem Byte String
[[[WARMWASSERISTTEMPERATUR]]]
# Information Warmwasser Temperatur Speicher-/ Lade-/ Komfortsensor read 2-Byte 0 150 0x0812
# DATA TX: 41 5 0 1 8 12 2 22
# DATA RX: 41 7 1 1 8 12 2 1F 2 46 --> 021F = 543 --> 54.3°C (Faktor: 0.1)
name = Warmwassertemperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = warmwasseristtemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000108120222# Ende direkt hinter dem Byte String
[[[WARMWASSERAUSTRITTSTEMPERATUR]]]
# Information Warmwasser Austrittstemperatur read 2-Byte 0 150 0x0814
# DATA TX: 41 5 0 1 8 14 2 24
# DATA RX: 41 7 1 1 8 14 2 1F 2 48 --> 021F = 543 --> 54.3°C (Faktor: 0.1)
name = Warmwasseraustrittstemperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = warmwasserausttemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000108140224# Ende direkt hinter dem Byte String
[[[BETRIEBSART]]]
[[[[HK1]]]]
# Information Heizkreis HK1 Aktuelle Betriebsart read 1-Byte 0 3 0x2500
# VALUE: 0 - Abschaltbetr. (Dauernd) 0x00
# VALUE: 1 - Red. Betrieb (Schaltuhr) 0x01
# VALUE: 2 - Normalbetrieb (Schaltuhr) 0x02
# VALUE: 3 - Normalbetrieb (Dauernd) 0x03
# DATA TX: 41 5 0 1 25 0 1 2C
# DATA RX: 41 7 1 1 25 0 1 2 31 --> 02 = 2 --> Normalbetrieb (Schaltuhr)
name = Betriebasart 0..3
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk1betriebsart # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 3 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 410500012500012C# Ende direkt hinter dem Byte String
[[[[HK2]]]]
# Information Heizkreis HK2 Aktuelle Betriebsart read 1-Byte 0 3 0x2500
# VALUE: 0 - Abschaltbetr. (Dauernd) 0x00
# VALUE: 1 - Red. Betrieb (Schaltuhr) 0x01
# VALUE: 2 - Normalbetrieb (Schaltuhr) 0x02
# VALUE: 3 - Normalbetrieb (Dauernd) 0x03
# DATA TX: 41 5 0 1 35 0 1 3C
# DATA RX: 41 7 1 1 35 0 1 2 41 --> 02 = 2 --> Normalbetrieb (Schaltuhr)
name = Betriebasart 0..3
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk2betriebsart # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 3 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 410500013500013C# Ende direkt hinter dem Byte String
[[[HEIZART]]]
[[[[HK1]]]]
# Information Heizkreis HK1 Aktuelle Heizart read 1-Byte 0 3 0x2323
# VALUE: 0 - Abschaltbetrieb 0x00
# VALUE: 1 - Nur Warmwasser 0x01
# VALUE: 2 - Heizen und Warmwasser 0x02
# VALUE: 3 - Normalbetrieb (Dauernd) 0x03
# DATA TX: 41 5 0 1 23 23 1 4D
# DATA RX: 41 7 1 1 23 23 1 2 52 --> 02 = 2 --> Heizen und Warmwasser
name = Betriebasart 0..3
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk1heizsart # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 3 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 410500012323014D# Ende direkt hinter dem Byte String
[[[[HK2]]]]
# Information Heizkreis HK2 Aktuelle Heizart read 1-Byte 0 3 0x3323
# VALUE: 0 - Abschaltbetrieb 0x00
# VALUE: 1 - Nur Warmwasser 0x01
# VALUE: 2 - Heizen und Warmwasser 0x02
# VALUE: 3 - Normalbetrieb (Dauernd) 0x03
# DATA TX: 41 5 0 1 33 23 1 5D
# DATA RX: 41 7 1 1 33 23 1 2 62 --> 02 = 2 --> Heizen und Warmwasser
name = Betriebasart 0..3
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk2heizsart # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 3 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 410500013323015D# Ende direkt hinter dem Byte String
[[[VORLAUFSOLLTEMPERATUR]]]
[[[[HK1]]]]
# Diagnose Heizkreis HK1 Vorlaufsolltemperatur read 2-Byte 0 127 0x2544
# DATA TX: 41 5 0 1 25 44 2 71
# DATA RX: 41 7 1 1 25 44 2 0 0 74 --> 0000 = 0 --> 0.0°C (Faktor: 0.1)
name = Vorlaufsolltemperatur HK1 [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk1vorlaufsolltemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000125440271# Ende direkt hinter dem Byte String
[[[[HK2]]]]
# Diagnose Heizkreis HK2 Vorlaufsolltemperatur read 2-Byte 0 127 0x3544
# DATA TX: 41 5 0 1 35 44 2 81
# DATA RX: 41 7 1 1 35 44 2 0 0 84 --> 0000 = 0 --> 0.0°C (Faktor: 0.1)
name = Vorlaufsolltemperatur HK1 [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk2vorlaufsolltemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000135440281# Ende direkt hinter dem Byte String
[[[VORLAUFISTTEMPERATUR]]]
[[[[HK1]]]]
# Diagnose Heizkreis HK1 Vorlaufisttemperatur read 2-Byte 0 127 0x2544
# DATA TX: 41 5 0 1 29 0 2 31
# DATA RX: 41 7 1 1 29 0 2 0 034 --> 0000 = 0 --> 0.0°C (Faktor: 0.1)
name = Vorlaufisttemperatur HK1 [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk1vorlaufisttemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000129000231# Ende direkt hinter dem Byte String
[[[[HK2]]]]
# Diagnose Heizkreis HK2 Vorlaufisttemperatur read 2-Byte 0 127 0x3544
# DATA TX: 41 5 0 1 39 0 2 41
# DATA RX: 41 7 1 1 39 0 2 0 0 44 --> 0000 = 0 --> 0.0°C (Faktor: 0.1)
name = Vorlaufisttemperatur HK1 [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk2vorlaufisttemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 4105000139000241# Ende direkt hinter dem Byte String
[[[PUMPE]]]
[[[[HK1]]]]
# Diagnose Heizkreis HK1 Umwälzpumpe read 1-Byte 0 1 0x2906
# DATA TX: 41 5 0 1 29 06 1 36
# DATA RX: 41 7 1 1 29 06 1 1 3A --> 1 --> TRUE
name = Umwälzpumpe HK1
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk1umwaelzpumpe # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 4105000129060136# Ende direkt hinter dem Byte String
[[[[HK2]]]]
# Diagnose Heizkreis HK2 Umwälzpumpe read 1-Byte 0 1 0x2906
# DATA TX: 41 5 0 1 39 06 1 46
# DATA RX: 41 7 1 1 39 06 1 1 4A --> 1 --> TRUE
name = Umwälzpumpe HK1
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = hk2umwaelzpumpe # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 4105000139060146# Ende direkt hinter dem Byte String
[[[[WARMWASSER]]]]
# Information Warmwasser Speicherladepumpe read 1-Bit 0 1 0x6513
# DATA TX: 41 5 0 1 65 13 1 7F
# DATA RX: 41 7 1 1 65 13 1 1 83 --> 1 --> TRUE
name = Warmwasserpumpe
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = warmwasserpumpe # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 410500016513017F# Ende direkt hinter dem Byte String
[[[[ZIRKULATION]]]]
# Zirkulationspumpe read 1-Byte TRUE/FALSE 0x6515
# DATA TX: 41 5 0 1 65 15 1 81
# DATA RX: 41 7 1 1 65 15 1 0 83 --> 0 --> FALSE
name = Zirkulations Pumpe
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = ausgang28_zirkpumpe # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 4105000165150181# Ende direkt hinter dem Byte String
[[[[SOLAR]]]]
# Solarpumpe read 1-Byte TRUE/FALSE 0x6552
# DATA TX: 41 5 0 1 65 52 1 BE
# DATA RX: 41 7 1 1 65 52 1 1 C2 --> 1 --> TRUE
name = Solar Pumpe
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = solarpump # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 41050001655201BE# Ende direkt hinter dem Byte String
[[[[INTERN]]]]
# Interne Pumpe
# DATA TX: 41 5 0 1 76 60 1 DD
# DATA RX: 41 7 1 1 76 60 1 1 E1 --> 1 --> TRUE
name = Interne Pumpe
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = intern # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 41050001766001DD# Ende direkt hinter dem Byte String
[[[SOLARKOLLEKTORTEMPERATUR]]]
# Solar Kollektortemperatur read 2-Byte -50..240 0x6564
# DATA TX: 41 5 0 1 65 64 2 D1
# DATA RX: 41 7 1 1 65 64 2 2 0 D6 --> 0002 = 2 --> 0.2°C (Faktor 0.1)
name = Solarkollektor Temperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = solarkollektortemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = signed # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001656402D1# Ende direkt hinter dem Byte String
[[[SOLARSPEICHERTEMPERATUR]]]
# Solar Speichertemperatur read 2-Byte 0..130 0x6566
# DATA TX: 41 5 0 1 65 66 2 D3
# DATA RX: 41 7 1 1 65 66 2 2 0 D8 --> 0002 = 2 --> 0.2°C (Faktor 0.1)
name = Solarspeicher Temperatur [°C]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = solarspeichertemp # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 10 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001656602D3# Ende direkt hinter dem Byte String
[[[SOLARBETRIEBSSTUNDEN]]]
# Solar Betriebsstunden read 2-Byte 0..64000 0x6568
# DATA TX: 41 5 0 1 65 68 2 D5
# DATA RX: 41 9 1 1 65 68 2 F 0 E7 --> 000F = 15 --> 15 (Faktor 1)
name = Solar Betriebsstunden [h]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = solarbetriebsstunden# Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001656802D5# Ende direkt hinter dem Byte String
[[[SOLARWAERMEMENGE]]]
# Solar Wärmemenge read 2-Byte 0..64000 0x6560
# DATA TX: 41 5 0 1 65 60 2 CD
# DATA RX: 41 9 1 1 65 60 2 F 0 DF --> 000F = 15 --> 15kWh (Faktor 1)
name = Solar Wärmemenge [kWh]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = solarwaermemenge # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001656002CD# Ende direkt hinter dem Byte String
[[[SOLARAUSBEUTE]]]
# Solar Ausbeute heute read 4-Byte 0..1150000 0xCF30
# DATA TX: 41 5 0 1 CF 30 4 09
# DATA RX: 41 9 1 1 CF 30 4 F 0 0 0 1B --> 0000.000F = 15 --> 15Wh (Faktor 1)
name = Solar Ausbeute heute [Wh]
type = num
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = solarausbeute # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = num # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginsigned = unsigned # Ist der Analogdatentyp mit Vorzeichen behaftet (Möglichkeiten "signed", "unsigned")
pluginreduction = 1 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginfactor = 1 # Übertragener Integerwert muss durch den gegebenen Faktor geteilt werden bevor der Wert im Item gespeichert wird
pluginvcode = 41050001CF300409# Ende direkt hinter dem Byte String
[[[FROSTGEFAHR]]]
# Frostgefahr read 1-Byte TRUE/FALSE 0x2510
# DATA TX: 41 5 0 1 25 10 1 3C
# DATA RX: 41 7 1 1 25 10 1 0 3F --> 0 --> FALSE
name = Frostgefahr
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = frostgefahr # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 3 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 410500012510013C# Ende direkt hinter dem Byte String
[[[SAMMELSTOERUNG]]]
# Sammelstoerung read 1-Byte TRUE/FALSE 0x0A82
# DATA TX: 41 5 0 1 0A 82 1 93
# DATA RX: 41 7 1 1 0A 82 1 0 96 --> 0 --> FALSE
name = Sammelstoerung
type = bool
cache = True
database@mysqldb = init
pluginusage = viessmann # Wird vom angegebenen Plugin verwendet
plugintagid = sammelstoerung # Im Plugin wird das Item im Dictionary unter dem defineirten Namen geführt. So ist es unabhängig vom Item Namen und Pfad
plugintype = bool # Datentyp dieses Items (num=Numerische Werte, bool=Binärwert)
pluginreduction = 3 # Untersetzung: 1=bei jedem Aufruf den Wert auslesen, 2= bei jedem 2. Aufruf, 3=bei jedem 3. Aufruf ...
pluginvcode = 410500010A820193# Ende direkt hinter dem Byte String
[[[ICON_STATUS]]]
# 0 = Störung Icon = control_x.svg (rot)
# 1 = Solarpumpe Icon = sani_solar.svg (weiss)
# 2 = Brenner Icon = sani_boiler_temp.svg (weiss)
# 3 = Brenner aus Icon = sani_boiler_temp.svg (weiss)
name = Iconstatus für die Heizung
type = num
cache = True
eval = 0 if (sh.ZAEHLER.HEIZUNG.SAMMELSTOERUNG() == True) else 1 if (sh.ZAEHLER.HEIZUNG.PUMPE.SOLAR() == True) else 2 if (sh.ZAEHLER.HEIZUNG.BRENNER_LEISTUNG() > 0.0) else 3
eval_trigger = ZAEHLER.HEIZUNG.SAMMELSTOERUNG | ZAEHLER.HEIZUNG.PUMPE.SOLAR | ZAEHLER.HEIZUNG.BRENNER_LEISTUNG
\plugins\viessmann\__init__.py
Code:
#!/usr/bin/env python3
# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
#
# Viessmann Heizung, Auswertung
# Vitodens200 / 300 mit Vitotronic 200 (HO1)
# Gas-Brennwertkessel mit witterungsgeführter Kessel- und Heizkreisregelung für 2 Heizkreise mit Mischer und 1 Heizkreis ohne Mischer
# 20CB = VScotHO1
#
# Version | Datum | Author | Beschreibung
# --------|------------|--------|---------------------------------------------------------
# 1.00 | 24.11.2016 | LC | Initialversion
# 1.01 | 29.12.2017 | LC | Logger besser angepasst self.logger = logging.getLogger(__name__), initialisiert in def ___init___
#
#
# Beispiel
#
# Senden 41 5 0 1 55 25 2 82
# Read Request -- - - - ----- - --
# | | | | | | +------- Prüfsumme (Summe über alley Bytes ohne die 41; [hex]5+0+1+55+25+2 = [dez]5+0+1+(5x16)+5+(2x16)+5+2 = 130dez = 82hex
# | | | | | +---------- XX Anzahl der Bytes, die in der Antwort erwartet werden
# | | | | +-------------- XX XX 2 byte Adresse der Daten oder Prozedur
# | | | +------------------ XX 01 = ReadData, 02 = WriteData, 07 = Function Call
# | | +-------------------- XX 00 = Anfrage, 01 = Antwort, 03 = Fehler
# | +---------------------- Länge der Nutzdaten (Anzahl der Bytes zwischen dem Telegramm-Start-Byte (0x41) und der Prüfsumme)
# +------------------------ Telegramm-Start-Byte
#
# Empfangen : 6 ----------------------- OK (Antwort auf 0x16 0x00 0x00 und auf korrekt empfangene Telegramme)
# 5 ----------------------- Schnittstelle ist aktiv und wartet auf eine Initialisierung
# 15 ----------------------- Schnittstelle meldet einen Fehler zurück
#
# 41 7 1 1 55 25 2 EF 0 74
# -- - - - ----- - ---- --
# | | | | | | | +-- Prüfsumme (Summe über alley Bytes ohne die 41; [hex]7+1+1+55+25+2+EF+0 = [dez]7+1+1+(5x16)+5+(2x16)+5+2+(14*16)+(15*16)+0 = [dez]7+1+1+(80)+5+(32)+5+2+(224)+(15)+0 = 372dez = 1.74hex)
# | | | | | | +------ Wert
# | | | | | +---------- XX Anzahl der Bytes, die in der Antwort erwartet werden
# | | | | +-------------- XX XX 2 byte Adresse der Daten oder Prozedur
# | | | +------------------ XX 01 = ReadData, 02 = WriteData, 07 = Function Call
# | | +-------------------- XX 00 = Anfrage, 01 = Antwort, 03 = Fehler
# | +---------------------- Länge der Nutzdaten (Anzahl der Bytes zwischen dem Telegramm-Start-Byte (0x41) und der Prüfsumme)
# +------------------------ Telegramm-Start-Byte
#
#
# Protokollbeschreibung
# http://openv.wikispaces.com/Protokoll+300
import logging
import serial
import time
import binascii
# Plugin Klasse
class viessmann():
# Def: __init__
# Beschreibung von: https://github.com/mknx/smarthome/wiki/Write-a-plugin-5-minutes
# The function init is called once when smarthome.py initializes before the
# items are loaded. Here you place the code that is needed to initialize you
# plugin. For example you can open a serial port if you need to communicate
# to an external device, open files, initialize other variables you need and
# so on. The function receives the parameter “smarthome” which gives access to
# the smarthome.py functions. You should save the value in a variable for later
# use like in the example above. Other parameter values are received from the
# file plugin.conf. You can default values for the case that the parameter is
# not defined in the plugin.conf file. It is a good practice to log your plugin
# name to the smarthome.log file.
def __init__(self, smarthome, serialport="/dev/ttyUSB_HEIZUNG", update_cycle="900"):
# Logger festlegen
self.logger = logging.getLogger(__name__)
# Eintrag in den Log
self.logger.info('Plugin viessmann - Initialisierung gestartet')
# Grundwerte festlegen
self._sh = smarthome
self._update_cycle = int(update_cycle)
self._serial = serial.Serial(
port=serialport,
timeout=1,
baudrate=4800,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_TWO)
self._items = dict()
self._lastbyte = b''
self._lastbytetime = time.time()
# Untersetzung: Aktueller Zähler, 0=Init, 1=bei jedem Zyklus, 2=jeden 2. Zyklus, 3=jeden 3. Zyklus
# Der Zähler ist nur bei Systemstart = 0
# Anschließend zählt dieser immer von 1..maxreduction
self._actreduction = 0
# Untersetzung: Maximaler Wert, der über die Konfig projektiert wurde. Wird dynamisch ermittelt
# Begrenzt auch den actreduction Zähler, dieser wird läuft immer von 1..maxreduction
self._maxreduction = 0
# Def: run
# Beschreibung von: https://github.com/mknx/smarthome/wiki/Write-a-plugin-5-minutes
# The function run is called once when smarthome.py starts.
# Run is executed after all items are loaded.
# You need to set the variable self.alive=True here.
def run(self):
# Eigenen Scheduler Eintrag erzeugen und diese Logik alle 2sek
# selbständig aufrufen, um keine Umdrehung des Zählers zu verpassen.
self._sh.scheduler.add(
'viessmann', self._readCyclicData, cycle=self._update_cycle)
# Alive Variable für das System auf True setzen
self.alive = True
# Def: stop
# Beschreibung von: https://github.com/mknx/smarthome/wiki/Write-a-plugin-5-minutes
# This is called when smarthome.py shuts down.
# This is the right place to close files and data connections.
# You need to set the variable self.alive=False here.
def stop(self):
# Alive Variable für das System auf False setzen
self.alive = False
# Serielle Schnittstelle schließen
self._serial.close()
# Scheduler selbständig entfernen
self._sh.scheduler.remove('viessmann')
# 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
elif ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'setcirculationpump')):
return self.update_item
return None
# Def: parse_logic
# Nur der Vollständigkeit halber hier mit aufgelistet
def parse_logic(self, logic):
if 'xxx' in logic.conf:
# self.function(logic['name'])
pass
# 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')
if ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'setcirculationpump')):
# Zirkulationspumpe schalten
self._writeCircPump(item())
# Lese Funktion manuell ausführen
self._readCyclicData()
def _checkChecksum(self, bytestring):
# Returnvalue vorbelegen (Checksumme falsch)
returnvalue = False
# Checksummen Variable für die Berechnung
checksum = 0
# Es wurde das Startbyte gefunden
startbytefound = False
# Sofern die Länge vom bytestring größer als
# die Mindestlänge 2 ist, kann die Aktion
# ausgeführt werden.
bytestringwork = bytestring
if ((len(bytestringwork)) > 1):
# Bytestring Byte für Byte auswerten. Wenn nur
# noch ein Byte übrig ist, dann stoppen. Dies
# ist dann das Checksummen Byte
while ((len(bytestringwork)) > 1):
# Erstes Byte zwischenspeichern
leftbyte = bytestringwork[:1]
# Sofern das Startbyte bereits gefunden wurde
# muss das aktuelle Byte mit in die Berechnung
# einbezogen werden.
if (startbytefound == True):
# Checksumme berechnen. Sie bildet sich aus der
# Aufsummierung der einzelenen Bytes
checksum = checksum + ord(leftbyte)
# Suche nach dem Startbyte b'\x41'
elif (leftbyte == b'\x41'):
# Es handelt sich um das Startbyte.
# Ab dem nächsten Byte handelt es sich um
# Nutzdaten, die mit in die Checksumme einfließen.
startbytefound = True
# Bytestring um das erste Byte verkürzen
bytestringwork = bytestringwork[1:]
# Checksumme prüfen
if ((checksum % 256) == ord(bytestringwork)):
# Berechnete Checksumme stimmt mit der angegebenen Checksumme überein
returnvalue = True
else:
# Checksummen passen nicht zusammen
messagetext = 'Plugin viessmann - Checksumme für Bytestring ist fehlerhaft. Bytestring : {}, CRC byte : {}, CRC Berechnet : {}, CRC im String : {}'.format(bytestring, bytestringwork, checksum, ord(bytestringwork))
self.logger.error(messagetext)
else:
messagetext = 'Plugin viessmann - Checksumme kann nicht berechnet werden. Bytestring zu kurz. Bytestring : {}'.format(bytestring)
self.logger.error(messagetext)
# Rückgabewert der Funktion zurückgeben
# True = Checksumme ist okay
# False = Checksumme falsch
return returnvalue
def _readByte(self):
self.logger.debug('Plugin viessmann - Read byte')
# Standard Rückgabewert definieren (leeres Byte)
returnvalue = b''
# Es wird per Schleife x-mal gelesen
j = 0
while (j < 5):
readbyte = self._serial.read(1)
self.logger.debug('Plugin viessmann --------- Read byte: {}'.format(readbyte))
# Prüfung, ob ein Byte empfangen wurde
if (readbyte != b''):
# Ein Byte wurde empfangen. Dieses wird gespeichert
self._lastbyte = readbyte
# Zeit des Empfangs ebenfalls speichern
self._lastbytetime = time.time()
# Schleife abbrechen
break
# Schleifenzähler inkrementieren
j = j + 1
# Wert zurückgeben. Wenn kein Byte empfangen wurde, wird b'' zurückgeliefert.
return returnvalue
def _writeBytes(self, bytestring):
self.logger.debug('Plugin viessmann - Write bytestring: {}'.format(bytestring))
# Sendepuffer leeren (Sicherheitsfunktion)
self._serial.flushInput()
# Übergebenen Bytestring senden
self._serial.write(bytestring)
# Sendepuffer leeren
self._serial.flushInput()
def _initCommunication(self):
self.logger.info('Plugin viessmann - Init Communication')
# Standard Rückgabewert definieren (Initialisierung fehlgeschlagen)
returnvalue = False
# Merker: Wurde der Initialisierungsstring b'\x16\x00\x00' gesendet.
# Wird hierauf dann mit b'\x06' geantwortet ist die Komunikation aufgebaut.
initstringsent = False
# Schnittstelle zurücksetzen
self._writeBytes(b'\x04')
# Lesen eines Bytes
self._readByte()
# Initialisierung ca. 10mal probieren
i = 0
while (i < 10):
if ((initstringsent == True) and (self._lastbyte == b'\x06')):
# Schnittstelle hat auf den Initialisierungsstring mit OK
# geantwortet. Die Abfrage von Werten kann beginnen. Diese
# Funktion meldet hierzu True zurück.
returnvalue = True
# Schleife abbrechen, da Initialisierung erfolgreich
break
if ((self._lastbyte == b'\x06') or (self._lastbyte == b'\x05')):
# Schnittstelle ist zurückgesetzt und wartet auf Daten
# b'\x05' = Warten auf Initialisierungsstring
# b'\x06' = Schnittstelle initialisiert
# In beiden Fällen wird zur Sicherheit der Initialisierungsstring gesendet.
self._writeBytes(b'\x16\x00\x00')
# Merker setzen: Initialisierungstring wurde zuletzt gesendet
initstringsent = True
elif (self._lastbyte == b'\x15'):
# Die Schnittstelle hat einen Fehler zurückgemeldet.
messagetext = 'Plugin viessmann - Die Schnittstelle hat einen Fehler zurückgemeldet (\x15), Schleifenindex {}'.format(i)
self.logger.error(messagetext)
# Schnittstelle zurücksetzen
self._writeBytes(b'\x04')
# Merker rücksetzen: Initialisierungstring wurde nicht zuletzt gesendet
initstringsent = False
else:
# Letzter Wert ist undefiniert
# Schnittstelle zurücksetzen
self._writeBytes(b'\x04')
# Merker rücksetzen: Initialisierungstring wurde nicht zuletzt gesendet
initstringsent = False
# Lesen eines Bytes
self._readByte()
# Counter hochzählen
i = i + 1
# Zurückgeben, ob die Initialisierung erfolgreich war
# True = Initialisierung erfolgreich. Letztes Byte war \x06 und nicht zu lange her
# False = Initialisierung fehlgeschlagen.
return returnvalue
def _setItem(self, item, databytes):
# Standard Rückgabewert definieren (Schreiben des Items nicht erfolgreich)
returnvalue = False
if (len(databytes) > 0):
# In Abhängigkeit vom Datentyp die Datenbytes auswerten und das Item schreiben
if (item.conf['plugintype'] == 'num'):
# Faktor für das Item ermitteln
factor = float(item.conf['pluginfactor'])
# Initialisierung der internen Variablen
longvalue = 0
floatvalue = 0.0
byteindex = 0
databytes_work = databytes
while (len(databytes_work) > 0):
# Erstes Byte zwischenspeichern
leftbyte = databytes_work[:1]
# Wert des Bytes ermitteln
value = int(ord(leftbyte))
# Gewichten / Multiplizieren
if (byteindex > 0):
value = int(value * pow(256, byteindex))
# Aufaddieren der einzelnen Bytes
longvalue = longvalue + value
# Byteindex hochzählen, damit das Byte mit
# netsprechend mit 1, 256, 65536, 16777216, usw.
# multipliziert werden kann
byteindex = byteindex + 1
# Bytestring um das erste Byte verkürzen
databytes_work = databytes_work[1:]
# Signed/Unsigned berücksichtigen
if (item.conf['pluginsigned'] == 'signed'):
if ((byteindex == 1) and (longvalue > 127)):
longvalue = (256 - longvalue) * (-1)
elif ((byteindex == 2) and (longvalue > 32767)):
longvalue = (65536 - longvalue) * (-1)
#elif ((byteindex == 4) and (longvalue > *2147483647)):
# longvalue = (*4294967295 - longvalue) * (-1)
# Faktor berücksichtigen
floatvalue = round(float(longvalue / factor), 2)
# Item schreiben
item(floatvalue)
# Debug Meldung über das erfolgreiche Schreiben
self.logger.debug('Plugin viessmann - Analogwert geschrieben : {}, Float-Wert : {}, Long-Wert : {}, Rohbytes : {}'.format(item.conf['plugintagid'], floatvalue, longvalue, databytes))
# Item korrek geschrieben
returnvalue = True
elif (item.conf['plugintype'] == 'bool'):
# Datenbyte Binärzustand prüfen
if ((databytes == b'\x01') or (databytes == b'\x03')):
# Item aktivieren
item('on')
# Debug Meldung über das erfolgreiche Schreiben
self.logger.debug('Plugin viessmann - Binärwert geschrieben : {}, Wert : {}, Rohbytes : {}'.format(item.conf['plugintagid'], 'True', databytes))
# Item korrek geschrieben
returnvalue = True
elif ((databytes == b'\x00') or (databytes == b'\x02')):
# Item deaktivieren
item('off')
# Debug Meldung über das erfolgreiche Schreiben
self.logger.debug('Plugin viessmann - Binärwert geschrieben : {}, Wert : {}, Rohbytes : {}'.format(item.conf['plugintagid'], 'False', databytes))
# Item korrek geschrieben
returnvalue = True
else:
messagetext = 'Plugin viessmann - Item kann nicht geschrieben werden, da Binärwert nicht klar. Read value : {}, Datenbytes : {}'.format(item.conf['plugintagid'], databytes)
self.logger.error(messagetext)
else:
messagetext = 'Plugin viessmann - Item kann nicht geschrieben werden, da Datentyp undefiniert. Read value : {}, Datentyp : {}'.format(item.conf['plugintagid'], item.conf['plugintype'])
self.logger.error(messagetext)
else:
messagetext = 'Plugin viessmann - Item kann nicht geschrieben werden, übergebener Bytestring leer ist. Read value : {}'.format(item.conf['plugintagid'])
self.logger.error(messagetext)
# Rückgabewert ausgeben
# True : Schreiben des Items war erfolgreich
# False : Schreiben des Items fehlerhaft
return returnvalue
def _readValue(self, item):
# self.logger.debug('Plugin viessmann - Read value : {}, Type : {}'.format(item.conf['plugintagid'], item.conf['plugintype']))
# Standard Rückgabewert definieren (Lesen nicht erfolgreich)
returnvalue = False
# Übergebenen Sende Bytestring auswerten
vcodestring = item.conf['pluginvcode']
# String aus der Config wird in einen bytestring gewandelt
# Beispiel: "4105000108A704B9" --> b'\x41\x05\x00\x01\x08\xA7\x04\xB9'
vcodebytestring = binascii.a2b_hex(vcodestring)
# Vorletztes Byte ermitteln
# Anfrage 41 05 00 01 55 25 02 82
# --
# LÄNGE
vcodelengthbyte = vcodebytestring[-2:]
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 07 01 01 55 25 02 EF 00 74
# -- ----- --
# OK DATEN CS
vcode_responselen = ord(vcodelengthbyte)
vcode_responsetotallen = vcode_responselen + 9
# ByteString für den Rückgabewert
bytestring = b''
# Schnittstelle ist bereit. Kommando kann gesendet werden.
vcodestring = item.conf['pluginvcode']
# String aus der Config wird in einen bytestring gewandelt
# Beispiel: "4105000108A704B9" --> b'\x41\x05\x00\x01\x08\xA7\x04\xB9'
vcodebytestring = binascii.a2b_hex(vcodestring)
self._writeBytes(vcodebytestring)
# Rückgabebytestring einlesen
k = 0
while k < vcode_responsetotallen:
# Byte von Schnittstelle lesen
self.logger.debug('Plugin viessmann --------- Read byte for : {}, index k : {}, kmax : {}, responselen : {}, lengthbyte : {}'.format(vcodebytestring, k, vcode_responsetotallen, vcode_responselen, vcodelengthbyte))
readbyte = self._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 07 01 01 55 25 02 EF 00 74)
bytestring = bytestring + self._lastbyte
# Schleifenzähler inkrementieren
k = k + 1
self.logger.debug('Plugin viessmann --------- 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 - Datenbytes extrahiert. Read value : {}, Databytes : {}'.format(item.conf['plugintagid'], bytestring_extract)
# self.logger.debug(messagetext)
# Wert aus den datenbytes ermitteln und mit Faktor in das Item schreiben
self._setItem(item, bytestring_extract)
# Wert wurde erfolgreich gelesen und das Item geschrieben
returnvalue = True
else:
messagetext = 'Plugin viessmann - Checksumme fehlerhaft. Read value : {}, Readed bytestring : {}'.format(item.conf['plugintagid'], bytestring)
self.logger.error(messagetext)
else:
messagetext = 'Plugin viessmann - Gelesener Bytestring startet nicht mit \x41. Read value : {}, Readed bytestring : {}'.format(item.conf['plugintagid'], bytestring)
self.logger.error(messagetext)
else:
messagetext = 'Plugin viessmann - Gelesener Bytestring hat nicht die korrekte Länge. Read value : {}, Erwartete Länge : {}, Readed bytestring : {}'.format(item.conf['plugintagid'], (vcode_responsetotallen - 1), bytestring)
self.logger.error(messagetext)
# Rückgabe, ob der Wert erfolgreich gelesen und das Item geschrieben wurde
return returnvalue
# Schreiben der Zirkulationspumpe
# Dummy: Wert wird nicht geschrieben. Dient nur dazu zu prüfen, ob die Funktion aufgerufen wird, wenn das Item sich ändert
# Soll der Wert tatsächlich geschrieben werden, so muss die vollständige Implementierung entsprechend umbenannt werden.
# Siehe direkt hierunter
# _writeCircPump() --> _writeCircPump_DUMMY() und _writeCircPump_DEACTIVE() --> _writeCircPump()
def _writeCircPump(self, seton):
self.logger.info('Plugin viessmann - WRITE TEST (Wert wird nicht geschrieben) - Write circulation pump : {}'.format(seton))
def _writeCircPump_DEACTIVE(self, seton):
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
# Def: _readCyclicData(zyklische Funktion)
# Zu Beginn werden alle Werte ausgelesen, anschließend mit entsprechenden Untersetzungen
# die wichtigen und die weniger wichtigen Daten
def _readCyclicData(self):
# Alle Einträge aus dem Distionary durchlaufen und für jedes Item prüfen,
# ob dieses in dem Zyklus (Untersetzung) ausgelesen werden soll.
for name in sorted(self._items.keys(), reverse=True):
item = self._items[name]
# Prüfung ob dieses Item in dem Zyklus ausgwertet werden soll
if ((self._actreduction % int(item.conf['pluginreduction'])) == 0):
self.logger.debug('Plugin viessmann')
self.logger.debug('Plugin viessmann - Reduction act: {} - Read item: {}'.format(self._actreduction, item.conf['plugintagid']))
# Lesen
readsuccess = False
# 1. Versuch den Wert von der Heizung zu lesen
if ((time.time() - 500) > self._lastbytetime):
# Der letzte Lesevorgang ist länger als 500ms her.
# Daher wird die Schnittstelle zur Sicherheit initialisiert.
self._initCommunication()
# Lesen der Daten (1. versuch)
readsuccess = self._readValue(item)
if (readsuccess == False):
# Erster Leseversuch hat nicht funktioniert
# Initialisierung der Schnittstelle vornehmen
inited = self._initCommunication()
# Prüfung, ob die Initialisierung erfolgreich war
if (inited == True):
# 2. Versuch den Wert von der Heizung zu lesen
readsuccess = self._readValue(item)
if (readsuccess == False):
# Wert konnte nicht gelesen oder das Item nicht geschrieben werden
messagetext = 'Plugin viessmann - Wert konnte nicht gelesen und Item geschrieben werden. Read value : {}, Schnittstelle initialisiert : {}'.format(item.conf['plugintagid'], readsuccess)
self.logger.error(messagetext)
else:
# Korrekt gelesen und Item geschrieben
messagetext = 'Plugin viessmann - Wert korrekt gelesen und Item geschrieben. Read value : {}'.format(item.conf['plugintagid'])
self.logger.info(messagetext)
# Untersetzungscounter um 1 hochzählen
self._actreduction = self._actreduction + 1
# Sofern der Untersetzungscounter größer ist als der Maximalwert,
# wird dieser auf 1 zurückgesetzt
if self._actreduction > self._maxreduction:
self._actreduction = 1
# Letzte Zeit vom Lesen setzen
timestring = '' + time.strftime('%d.%m.%Y %H:%M:%S')
self._itemlastread(timestring)
plugin.yaml
Code:
viessmann:
class_name: viessmann
class_path: plugins.viessmann
serialport: /dev/ttyUSB_HEIZUNG
update_cycle: 300
Gruß
loeserman



Wenn der Parser entsprechend steht, wird sicher auch die Schreib-Funktionalität wesentlich einfacher umzusetzen sein...
Kommentar