Ankündigung

Einklappen
Keine Ankündigung bisher.

Plugin: Viessmann Heizung auslesen (Vitodens200 / 300 mit Vitotronic 200 (HO1))

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #16
    Bin aufgrund von persönlichen Umständen im letzten Jahr nicht zu viel gekommen. Ich habe aber vor, mir - ggf. ab Anfang des Jahres - das Plugin wie ja mal angedacht genauer anzusehen. Derzeit arbeite ich noch mit vcontrold, vclient und dem network-Plugin...

    Kommentar


      #17
      Zitat von loeserman Beitrag anzeigen
      nein es gibt kein Update. Nutze es immer noch so. Läuft nun schon ewig ohne Probleme.
      Danke.
      Würde eigentlich was dagegen sprechen, das Plugin zum offiziellen Bestandteil von shNG zu machen?

      Gibt es auch schon die Funktion, die Heizung zu steuern?

      Kommentar


        #18
        Von meiner Seite spricht da nichts gegen. Wie kann man es denn da einbringen und was ist ggf. zu tun?
        Für das Schreiben hatte ich schon etwas vorbereitet, das setze ich aber nicht ein. Das einzige was mich interessiert hätte wäre die Zirkulationspumpe, aber die kann ich wohl bei meiner Heizung nicht extern steuern. Sie reagiert nur auf die Zeitkurve, die man in der Heizung einstellt. Auch weiß ich nicht, wie oft man etwas einstellen kann (Stichwort RAM und ROM).

        Kommentar


          #19
          Hast du es denn mal probiert? Geht es bei Dir denn?

          Kommentar


            #20
            Zitat von loeserman Beitrag anzeigen
            Hast du es denn mal probiert? Geht es bei Dir denn?
            Ehrlich gesagt bin ich noch in der Vorbereitung. Ich habe mir eine Steuerung Vitotronic 200 KO1B gekauft und möchte nun die Heizung an shNG anbinden.
            Ziel ist sicher die Werte auszulesen, aber auch diverse Werte setzen. Dazu gehören die Betriebsart, aber auch die Sollraumtemperatur.

            Im Plugin hattest Du ja schon etwas vorbereitet. Was muss ich tun, um das zu nutzen?
            Laut openv wiki würde es bspw so gehen:

            Beispiel Vitodens 333 Betriebsart schreiben:
            • Senden 0x41 06 00 02 23 23 01 XY xx
            • Empfangen 0x06 41 06 01 02 23 23 01 01 xx
              • XY:
                • 0 = Abschalten
                • 1 = nur WW
                • 2 = Heizen mit WW
                • 3 = immer Reduziert
                • 4 = immer Normal
            Dankeschön

            Kommentar


              #21
              Hi,
              also ich habe nochmal nachgesehen. Ehrlich gesagt habe ich da nur einen Test gemacht um einen Wert zu schreiben. Ich denke auch das das so geht. Mein einziges Ziel war es, dass ich die Zirkulationspumpe von der Hausautomation aus einschalten und abschalten wollte. Es stand zwar überall, dass genau dieser Wert leider nicht geschrieben werden kann aber ich wollte es dennoch probieren. Leider ist der Wert aber wirklich nicht schreibbar :-(

              Aber die Art und Weise sollte schon so gehen für die Werte die beschrieben werden dürfen. Aber ich habe das nicht über die Config selbst gelöst sondern hatte hier eine dedizierte Funktion im Plugin nur für diesen einen Wert, den ich schreiben wollte. Vielleicht hilft es Dir aber trotzdem etwas weiter.

              Auszug aus item.conf
              Code:
              [ZAEHLER]
                  [[HEIZUNG]]
                      [[[SET_ZIRKULATION]]]
                          name = Zirkulationspumpe ein/ausschalten
                          type = bool
                          value = False
                          pluginusage = viessmann           # Wird vom angegebenen Plugin verwendet
                          pluginfct = setcirculationpump    # Funktion, dieses items
              Auszüge aus dem plugin code
              Code:
                  # Def: parse_item
                  # Beschreibung von: https://github.com/mknx/smarthome/wiki/Write-a-plugin-5-minutes
                  # The function parse_item is called for each item during startup when
                  # smarthome.py reads the item.conf file. You can access item parameters
                  # and start according action here. For example you have the following
                  # item defined in …/items/smarthome.conf
                  #
                  # Items für dieses Plugin verfügen über mehrere Attribute
                  # + pluginusage     = viessmann
                  # + plugintagid     = z.B. brennerstarts
                  # + pluginreduction = 1
                  # + ...
                  # Ist es ein Item für dieses Plugin so trägt es auch ein weiteres Attribut namens "plugintagid"
                  # Hierüber können mehrere zu einem Plugin gehörende Items klar definiert und verwendet werden
                  # ohne, dass der eigentliche Item Name/Pfad eine bestimmte Nomenklatur aufweisen müssen.
                  def parse_item(self, item):
                      # Prüfung ob ein Item existiert mit dem attribut "pluginusage"
                      if (('pluginusage' in item.conf) and ('plugintagid' in item.conf) and ('pluginvcode' in item.conf) and ('pluginreduction' in item.conf)):
                          # Prüfung ob dieses Attribut den Namen "viessmann" trägt
                          if ((item.conf['pluginusage'] == 'viessmann') and ('pluginvcode' in item.conf)):
                              # String aus der Config wird in einen bytestring gewandelt
                              # Beispiel: "4105000108A704B9" --> b'\x41\x05\x00\x01\x08\xA7\x04\xB9'
                              vcodebytestring = binascii.a2b_hex(item.conf['pluginvcode'])
                              if (self._checkChecksum(vcodebytestring) == True):
                                  # Speichern des Items unter seinem "plugintagid" Namen im
                                  # Plugin eigenen Item-Dictionary
                                  self._items[item.conf['plugintagid']] = item
                                  # Maximale Untersetzung ermitteln anhand der Daten aus der Config
                                  # Dient dazu den aktuellen Zähler immer wieder von 1 zu starten.
                                  self._maxreduction = max(self._maxreduction, int(item.conf['pluginreduction']))
                                  # Eintrag in den Log
                                  self.logger.info('Plugin viessmann - Item added: {}'.format(item.conf['plugintagid']))
                              else:
                                  # Checksumme für das Item (Sendecode) ist nicht korrekt
                                  messagetext = 'Plugin viessmann - Falsche Checksumme für den vcode (Sendecode {}}, Item not added: {}, '.format(vcodebytestring, item.conf['plugintagid'])
                                  self.logger.error(messagetext)
                      elif (('pluginusage' in item.conf) and ('pluginfct' in item.conf) ):
                          if ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'lastreadtime')):
                              self._itemlastread = item
                          elif ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'readtrigger')):
                              return self.update_item
                          elif ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'setcirculationpump')):
                              return self.update_item
                      return None
              
              ...
              
                  # Def: update_item
                  # Nur der Vollständigkeit halber hier mit aufgelistet
                  def update_item(self, item, caller=None, source=None, dest=None):
                      #if caller != 'plugin':
                      self.logger.info("Plugin viessmann - Item update item: {0}".format(item.id()))
                      if (('pluginusage' in item.conf) and ('pluginfct' in item.conf)):
                          # Prüfung ob dieses Attribut den Namen "viessmann" trägt und es sich um das
                          # Item zum erneuten Lesen handelt
                          if ((item() == True) and (item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'readtrigger')):
                              # Damit alle Werte gelesen werden muss die Untersetzung
                              # auf den Inititialisierungswert gesetzt werden.
                              self._actreduction = 0
                              # Lese Funktion manuell ausführen
                              self._readCyclicData()
                              # Rücksetzen des Trigger Items
                              item('off')
                          if ((item.conf['pluginusage'] == 'viessmann') and (item.conf['pluginfct'] == 'setcirculationpump')):
                              # Zirkulationspumpe schalten
                              self._writeCircPump(item())
                              # Lese Funktion manuell ausführen
                              self._readCyclicData()
              
              ...
              
                  # Schreiben der Zirkulationspumpe
                  def _writeCircPump(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
              Wie ich gesehen habe baust Du ja gerade ein verbessertes viessmann plugin. Sollte das auch für meine Heizung gehen? Dann kann ich das ja auch mal ausprobieren.

              Kommentar


                #22
                Zitat von loeserman Beitrag anzeigen
                Wie ich gesehen habe baust Du ja gerade ein verbessertes viessmann plugin. Sollte das auch für meine Heizung gehen? Dann kann ich das ja auch mal ausprobieren.
                Danke.

                Ja, ich baue gerade basierend auf deinem Plugin eine andere Version des Plugin. Vieles geht schon.
                Gern kannst Du es testen. Ich melde mich, wenn ich soweit bin.

                Beste Grüße

                Kommentar

                Lädt...
                X