Wenn dies dein erster Besuch hier ist, lies bitte zuerst die Hilfe - Häufig gestellte Fragen durch. Du musst dich vermutlich registrieren, bevor du Beiträge verfassen kannst. Klicke oben auf 'Registrieren', um den Registrierungsprozess zu starten. Du kannst auch jetzt schon Beiträge lesen. Suche dir einfach das Forum aus, das dich am meisten interessiert.
Die dritte Seite ist schon genial.
Allerdings ist finde ich die Plugin-Funktionen fast noch genialer. Da kann ich jetzt per Script einfach mal schauen, auf welche Adressen meine Heizung noch so reagiert.
Michael hatte mir Feedback gegeben, dass die Timer nicht so in die Items übertragen werden, wie er das wollte; es war aber nicht sicher, ob das ggf. schon vorher nicht geklappt hatte...
Also, ich habe jetzt den Codelauf nochmal detailliert und gründlich parallel verfolgt (aktuelle Version und die, bevor ich parse_response() zerlegt habe) --
Wenn nicht bei der Über- und Rückgabe von Variablen, Werten, Dicts und Items etwas verändert wird, ohne dass ich das jetzt erkennen konnte, sollten beide Varianten dasselbe tun. Ergo müsste das Verhalten "nach außen" unverändert sein.
Ich habe mal eine Version angehängt, die etwas aggressiver loggt - vorsicht, bewusst alles zusätzliche Logging auf ERROR und beginnt mit '#####'. Bitte nicht für was anderes benutzen; die ist ansonsten identisch mit der aktuellen von GitHub.
Vielleicht fällt die ja schon selber was auf, wenn du ins Log schaust, ansonsten poste mir das hier rein, dann schau ich das mal durch. Wär' doch gelacht, wenn wir das nicht bis Weihnachten geklärt kriegen
Das Attribut kann genutzt werden, um alle Items neu aus der Heizung auszulesen, d.h. wenn das Item geändert wird, wird ein Update-Zyklus angestoßen.
Ich nutze es mit autotimer: 1 = 0, um das Item wieder auf 0 zu setzten. Dadurch wird aber ein zweiter Lesezyklus angestoßen. Kannst Du das im Plugin noch abfangen, dass der Lesezyklus nur gestartet wird, wenn der Wert des Items == 1 ist?
Timer:
Bei den Timern soll es 2 Varianten geben.
A) Alle Timer einer Applikation in einem DICT im UZSU-Format
Das Attribut im Item ist "viess_timer" mit der Wert der jeweiligen Applikation ("Timer_A1M1"). Das Plugin sich sich anhand des Wertes die Datenpunkte (alle, die so beginnen, wieder Wert ist) aus der command zusammen, sortiert das Mo - So und fragt dann dieses DICT nach einander ab.
Das funktioniert.
B) Alle Viessmann-Timer einzeln (Applikation und Tage einzeln)
Das Attribut hier ist das normale "viess-read" mit dem Wert des Namen des Datenpunktes aus der command. Hier erfolgt ein normales Auslesen und über die Unit die entsprechende Formatierung.
Nach meinem DEBUG Log wird der Wert aus gelesen, formatiert und in das Item geschrieben. Nur dort kommt er nicht an.
Hier mal ein Log:
Code:
2020-12-23 06:39:56 DEBUG plugins.viessmann _send_command Got a new read job: Command Timer_Warmwasser_Mi
2020-12-23 06:39:56 DEBUG plugins.viessmann _build_command_packet Build read packet for command Timer_Warmwasser_Mi
2020-12-23 06:39:56 DEBUG plugins.viessmann _build_command_packet Created command Timer_Warmwasser_Mi to be sent as hexstring: 410500012110083f and as bytes: bytearray(b'A\x05\x00\x01!\x10\x08?')
2020-12-23 06:39:56 DEBUG plugins.viessmann _send_command_packet Successfully sent packet: 410500012110083f
2020-12-23 06:39:56 DEBUG plugins.viessmann _send_command_packet Trying to receive 17 bytes of the response
2020-12-23 06:39:56 DEBUG plugins.viessmann _send_command_packet Received 17 bytes chunk of response as hexstring 06410d010121100820248389ffffffff94 and as bytes b'\x06A\r\x01\x01!\x10\x08 $\x83\x89\xff\xff\xff\xff\x94'
2020-12-23 06:39:56 DEBUG plugins.viessmann _parse_response Response decoded to: commandcode: 2110, responsedatacode: 1, valuebytecount: 8, responsetypecode: 1
2020-12-23 06:39:56 DEBUG plugins.viessmann _parse_response Rawdatabytes formatted: 20248389ffffffff and unformatted: bytearray(b' $\x83\x89\xff\xff\xff\xff')
2020-12-23 06:39:56 DEBUG plugins.viessmann _parse_response Matched command Timer_Warmwasser_Mi and read transformed timer [{'An': '04:00', 'Aus': '04:40'}, {'An': '16:30', 'Aus': '17:10'}, {'An': '00:00', 'Aus': '00:00'}, {'An': '00:00', 'Aus': '00:00'}] and byte length 8
2020-12-23 06:39:56 DEBUG plugins.viessmann _process_response Corresponding item Timer_Warmwasser_Mi for command Timer_Warmwasser_Mi
2020-12-23 06:39:56 DEBUG plugins.viessmann _process_response Updating item Timer_Warmwasser_Mi with value [{'An': '04:00', 'Aus': '04:40'}, {'An': '16:30', 'Aus': '17:10'}, {'An': '00:00', 'Aus': '00:00'}, {'An': '00:00', 'Aus': '00:00'}]
2020-12-23 06:39:56 DEBUG plugins.viessmann _process_response process_response_timer: 2110
2020-12-23 06:39:56 DEBUG plugins.viessmann _process_response Viessmann timer dict: {'Timer_A1M1': {'Timer_A1M1_Mo': [{'An': '06:00', 'Aus': '07:30'}, {'An': '18:30', 'Aus': '19:30'}, {'An': '00:00', 'Aus': '00:00'}, {'An': '00:00', 'Aus': '00:00'}], 'T
das ist seltsam. 1. ist im Plugin schon (immer) eine Abfrage drin gewesen "if item(): ...", also eine boolesche Prüfung, die auf 1, True, 'X' reagieren sollte und auf 0, False, '' nicht. Geht bei mir auch genau so mit True/False und 1/0. Jede Änderungen kommt im Zweig "elif self.has_iattr(...)" an, aber die Prüfung lässt nur True/1 durch.
Wieso das bei dir so nicht geht, weiß ich nicht. Du könntest in der Zeile vor dem "if item():" (bei mir 311) Folgendes einfügen:
self.logger.debug(f'{item} called as viess_update with value {item()}')
Dann schreibt er dir immer ins Log, wenn das Item geändert wurde, und wenn er dann das Lesen anstößt, kommt die nächste Logzeile 'Reading of all values/items has been requested'. Dann könnte man nochmal untersuchen, ob oder was da genau passiert.
viess_update fehlte übrigens auch noch in der plugin.yaml, ich habs mal mit aufgenommen (dann allerdings logischerweise mit bool)
Ansonsten kannst du auch im item enforce_updates = True setzen und den autotimer rauslassen. Ob das Item auf True bleibt oder nicht, ist ja letztlich egal.
Timer:
Mit dem Log kann ich nicht wirklich was anfangen. Der letzte genannte Timer ist ein anderer (WW_Mi / A1M1_Mo) als der vorher berechnete, aber ich kann nicht sehe, woher das kommt. Dafür brauche ich das Logging aus der Datei, die ich oben angehängt habe.
Mit dem Log kann ich nicht wirklich was anfangen. Der letzte genannte Timer ist ein anderer (WW_Mi / A1M1_Mo) als der vorher berechnete, aber ich kann nicht sehe, woher das kommt. Dafür brauche ich das Logging aus der Datei, die ich oben angehängt habe.
Was ich damit sagen wollte, ist, dass alle Timer gelesen werden und auch dem entsprechenden Item zugewiesen werden
In der plugin.yaml war viess_update nicht beschrieben. Damit weiß niemand, dass es das gibt, und shng kann die Syntax nicht prüfen. Also habe ich es aufgenommen.
Allerdings habe ich es mit Typ "bool" aufgenommen, also viess_update möchte mit True / False gefüttert werden, nicht mit 1/0. Das müsste innerhalb shng relativ egal sein, weil sich jetzt Zahl != 0 in True und 0 in False wandeln lässt. Ich wollte nur drauf hinweisen, weil du geschrieben hast, dass du "1" und "0" zuweist
Was mir aber gerade einfällt: welche autotimer-Kompatibilität ist bei dir eingestellt? Die alte Variante weist nicht 0 zu (also die Zahl), sondern "0", einen String. Und str(0) ist nicht False, sondern True, also würde deshalb neu gelesen.
Probier mal
autotimer: 10 = 0 = latest
, damit könnte es dann gehen. (Dann kannst du den auch gleich auf eine Sekunde, setzen )
Da sehe ich jetzt keine Lücke - außer, dass er den IOError eben erst erkennt, wenn er zu schreiben versucht. Aber da wüsste ich noch nicht, wie ich das anders lösen sollte.
Das würde doch so reichen. Solange der Filter auf IOError reicht? Denn ich nutze zB. noch nicht Version 3.5 von pyserial die so wie ich das verstanden habe keine Exception vom Typ IOError wirft, sondern SerialException wirft.
Habt ihr noch Ideen, gibt es noch offene Probleme oder Fehler?
Die Plugin Funktion zum testen von nicht definierten Adressen könnte man auch noch ins WebIF einbauen, falls du das nicht schon drin hast (habe noch nicht die aktuelle Änderung getestet).
Hmm.. ich hab es einfach mal getestet, in dem ich das USB-Gerät mit dem Skript von hier kurz neu gestartet habe.
Dec 23 17:04:29 heizung kernel: [159019.164772] cp210x ttyUSB1: cp210x converter now disconnected from ttyUSB1
Dec 23 17:04:29 heizung kernel: [159019.164895] cp210x 1-1.5:1.0: device disconnected
Dec 23 17:04:30 heizung kernel: [159019.693706] cp210x 1-1.5:1.0: cp210x converter detected
Dec 23 17:04:30 heizung kernel: [159019.698356] usb 1-1.5: cp210x converter now attached to ttyUSB0
Dec 23 17:04:30 heizung kernel: [159019.698991] usb 1-1.5: authorized to connect
Das würde doch so reichen. Solange der Filter auf IOError reicht? Denn ich nutze zB. noch nicht Version 3.5 von pyserial die so wie ich das verstanden habe keine Exception vom Typ IOError wirft, sondern SerialException wirft.
Nä.
1. Die Vererbung war "früher" Exception -> SerialException, "jetzt" Exception -> IOError -> SerialException. Aber: das ist nicht "erst" seit 3.5, sondern 2.5 (ZWEI-Fünf), also schon eine ganze Weile her. Halte ich daher für unerheblich. btw - ich weiß gar nicht, ob es 3.5 schon gibt; ich habe selbst noch 3.4 drauf.
2. Mit IOError fange ich SerialException auch ein, weil die von IOError abgeleitet ist. Jede SerialException IST auch ein IOError. (steht übrigens auch auf der von dir verlinkten Seite, an der gleichen Stelle )
Und was der OSError da jetzt soll, verstehe ich nicht ganz.
Ich sehe das derzeit auch nicht als Problem - wenn meinetwegen beim Schreiben oder auch in "Leerlaufzeiten" die serielle Verbindung abraucht, dann ist mit das - im Prinzip - egal, weil ich es eh erst beim nächsten Schreiben feststellen kann. Und wenn ich dann feststelle, dass es nicht geht, verbinde ich neu. Wenn das nicht klappt (weil das device noch nicht wieder da ist zB), dann kann ich es eh nicht ändern.
Wenn du in der Kette noch Verbesseungsmöglichkeiten siehst, dann immer her damit.
Was ja bedeutet, dass er nicht in den disconnect Code rein läuft... oder irre ich mich da?
Du irrst, s.o.
Die Plugin Funktion zum testen von nicht definierten Adressen könnte man auch noch ins WebIF einbauen, falls du das nicht schon drin hast (habe noch nicht die aktuelle Änderung getestet).
Ach und schreiben ist auch untergegangen im WebIF
Die ist schon drin, ist nur noch nicht hochgeladen. Und Schreiben vom WebIf sehe ich jetzt nicht so als vordringliche Geschichte an. Schreiben würde ich sowieso erst, wenn ich sicher bin, was die Datenpunkte tun und welche Werte es da gibt. Und dann hätte ich sie - hoffentlich - sowieso schon in der commands.py und könnte (notfalls) übers AdminUI schreiben, wenns denn sein muss. Die Heizung ist ja nu kein Teil, auf das ich - mal eben, spontan - willkürliche Werte werfen wollte. Bei nem Lichtschalter oder meinetwegen einem RGB-Dimmer wäre das was anderes.
Ich schreibe zweimal im Jahr auf meine Heizung - einmal im Frühjahr (Heizung aus) und einmal im Herbst (Heizung an). Meistens geht es aber schneller, das per Hand am Gerät zu machen, als erst irgenwo ein Item zu schreiben. Und das sind auch Fälle, die ich nicht algorithmisch lösen kann. Kein SciPy kann ermitteln, ob mir schon zu kühl an den Füßen ist oder nicht
Vielleicht bau ich das Schreiben später mal ein, wenn alle danach schreien und ansonsten kannst du mir gern jederzeit nen PR dazu schicken
Hat wer das mit den Timern (zb: Timer_A1M1_Mo) irgendwie umgesetzt und ist Bereit das mal zu teilen.
Das kann ich gern machen. Die Implementierung ist auch von mir.
Zur Erklärung:
Es gibt prinzipiell 2 Möglichkeiten, die Timer auszulesen.
A) Jeden Timer einzeln, also den Datenpunkten entsprechend. D.h. Es gibt Einen Datenpunkt pro Timer-Anwendung und Tag. Dort sind die bis zu 4 Schaltzeiten hinterlegt. Dies funktioniert normal mit viess_read für jeden Datenpunkt. Zusätzlich kann man noch das mitgelieferte struct für den timer anwenden. Dann werden die Timer noch in einzelne Zeiten (AN1, AUS1, AN2, AUS2, ....) zerlegt jede Zeit einem Items zugewiesen.
B) Alle Timer einer Anwendung werden zusammengefasst und in das UZSU-Format umgesetzt. Dafür gibt es das Attribut viess_timer. Diesem wird in der item.yaml der "Oberbegriff" der entsprechenden Timer aus der command.py zugewiesen. Sind die Datenpunkte für den Timer in der command.py mit Timer_A1M1_Mo, Timer_A1M1_DI, Timer_A1M1_MI etc beschrieben, ist der Oberbegriff Timer_A1M1 und damit der Wert für das Attribut.
Hier wird aber nur die UZSU als Ein- und Ausgabemaske benutzt. Deswegen ist der Zustand der UZSU (Aktiv oder oder aus) auch egel. Es werden nur die Timer ausgelesen und angezeigt und bei Änderung in shNG wieder in die Heizung geschrieben.
Meine Konfig:
Code:
heizung:
heizkreis_a1m1:
schaltzeiten:
type: foo
schaltuhr:
name: Schaltzeiten im UZSU dict Format
type: dict
visu_acl: rw
cache: yes
viess_timer: Timer_A1M1
In der Visu nutze ich das das UZSU-Widget, einmal als icon und einmal als table:
So wie ich das sehe, nimmer alle Timer mit in das Dict zu abzufragenden Datenpunkte mit auf, führt auch die Abfrage durch.
Dann scheint es aber so, dass er den Wert nicht dem Item also bspw "heizung.heizkreis_m2.schaltzeiten.montag" zuweist, sondern es im timer_dict hinterlegt.
Es sollte so sein, dass beides parallel gefüllt wird. Könntest Du dir das nochmal anschauen?
Ich wollte die Betriebsart schreiben und bekomme einen Fehler. Das Debug-Log zeigt:
Code:
2020-12-27 19:14:57 INFO plugins.viessmann update_item Update item: heizung.heizkreis_a1m1.betriebsart.betriebsart, item has been changed outside this plugin
2020-12-27 19:14:57 DEBUG plugins.viessmann update_item update_item was called with item Betriebsart_A1M1 from caller admin, source None and dest None
2020-12-27 19:14:57 DEBUG plugins.viessmann update_item Got item value to be written: 2 on command name Betriebsart_A1M1
2020-12-27 19:14:57 DEBUG plugins.viessmann _send_command Got a new write job: Command Betriebsart_A1M1 with value 2
2020-12-27 19:14:57 DEBUG plugins.viessmann _build_command_packet Build write packet for command Betriebsart_A1M1
2020-12-27 19:14:57 DEBUG plugins.viessmann _build_valuebytes_from_value Unit defined to IUINT with config{'unit_de': 'INT unsigned int', 'type': 'integer', 'signed': False, 'read_value_transform': 'int'}
2020-12-27 19:14:57 DEBUG plugins.viessmann _build_valuebytes_from_value _build_valuebytes_from_value failed with unexpected error: invalid literal for int() with base 10: 'int'
2020-12-27 19:14:57 DEBUG plugins.viessmann update_item Write for Betriebsart_A1M1 with value 2 failed, reverting value, canceling followup actions
Wir verarbeiten personenbezogene Daten über die Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen. Weitere Informationen findest Du in unserer Datenschutzerklärung.
Indem Du unten auf "ICH stimme zu" klickst, stimmst Du unserer Datenschutzerklärung und unseren persönlichen Datenverarbeitungs- und Cookie-Praktiken zu, wie darin beschrieben. Du erkennst außerdem an, dass dieses Forum möglicherweise außerhalb Deines Landes gehostet wird und bist damit einverstanden, dass Deine Daten in dem Land, in dem dieses Forum gehostet wird, gesammelt, gespeichert und verarbeitet werden.
Kommentar