Ankündigung

Einklappen
Keine Ankündigung bisher.

Seltsames item- Verhalten

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

    Seltsames item- Verhalten

    Hallo!

    Mein item
    Code:
    [[Luft1]]
                type = num
                lux2_p = 894
            visu_acl = rw
            enforce_updates = yes
    kann 4 verschiedene Werte erhalten. (0, 1, 2, oder 3)

    Erhält das item die Werte 1, 2, oder 3 wird´s in der Visu korrekt angezeigt.

    Code:
    Luft: {{ basic.value('Luft1', 'StatusWP.Luft1') }}
    Erhält das item aber den Wert 0, wird´s in der Visu erst nach einem Neustart von smarthome.py angezeigt.


    Woran liegt das?
    Habt ihr eine Idee?

    Lg Max

    #2
    Hallo,

    ich denke es liegt an der Visu. Debuglog von sh.py? Debuginformation (JavaScript-Log) der smartVISU?

    Bis bald

    Marcus

    Kommentar


      #3
      Hallo,

      danke für die Antwort.
      Komme wahrscheinlich erst nächste Woche dazu, die Logs zu posten.

      Eine Frage noch. Passt zwar nicht zum Thema...
      Kann man per Logik ein Plugin beenden oder starten??

      Lg Max

      Kommentar


        #4
        Hallo,

        Offiziell: Nein, kann man nicht.
        Inoffiziell: könnte man, sollte man aber nicht.

        Einfach eine Plugin-Funktion aufrufen bzw. in eine packen. Damit sollte sich das gewünschte Verhalten abbilden lassen.

        Bis bald

        Marcus

        Kommentar


          #5
          Hallo!

          OK, das ist dann glaub ich, doch zu steil für mich.

          Kurz zu meinem Problem:
          Das Luxtronik- Plugin verliert sehr oft am Tag die Verbindung zur Wärmepumpe.
          Code:
          2015-10-02 11:37:06,417 WARNING  Luxtronic2   Luxtronic2: failed to retrieve parameters -- __init__.py:refresh_parameters:172
          Nach einem Neustart von sh passt wieder alles. Das kommt aber schätzungsweise 10mal am Tag vor.
          Deshalb war mein Gedanke:
          Wenn sh eine gewisse Zeit keine Daten mehr empfängt, einfach Plugin neu starten.

          Lg Max

          Kommentar


            #6
            Zitat von Max2612 Beitrag anzeigen
            Wenn sh eine gewisse Zeit keine Daten mehr empfängt, einfach Plugin neu starten.
            Moin,
            das ist aber sehr dirty. Wenn es ein Problem gibt, sollte man das lösen. Du machst dein Auto ja während der Fahrt auch nicht regelmäßig aus und wieder an, weil irgendetwas nicht funktioniert.
            Man sollte besser den Grund für den Fehler finden. Evtl. ist es ein Timeout Problem. Dann hilft möglicherweise ein Verkürzung des Abfragezeitraumes.

            Gruß, Sebastian
            Baustelle 2.0 (Detailprogrammierung und Restarbeiten)
            Ruhri? -> Komm zum Stammtisch

            Kommentar


              #7
              Morgen,

              danke für den Tipp mit dem Timeout Problem.
              Ich habe den Abfrageintervall von 300 auf 120 gesetzt. Am Sonntag war kein Ausfall. Jedoch in der Nacht zu Heute zwischen 0:00 und 2:00.
              Soll ich den Intervall nochmal verkürzen?

              Code:
              #!/usr/bin/env python3
              # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
              #
              # Copyright 2012-2013 KNX-User-Forum e.V.       https://knx-user-forum.de/
              #
              #  This file is part of SmartHome.py.    http://mknx.github.io/smarthome/
              #
              #  SmartHome.py is free software: you can redistribute it and/or modify
              #  it under the terms of the GNU General Public License as published by
              #  the Free Software Foundation, either version 3 of the License, or
              #  (at your option) any later version.
              #
              #  SmartHome.py is distributed in the hope that it will be useful,
              #  but WITHOUT ANY WARRANTY; without even the implied warranty of
              #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
              #  GNU General Public License for more details.
              #
              #  You should have received a copy of the GNU General Public License
              #  along with SmartHome.py. If not, see <http://www.gnu.org/licenses/>.
              #
              
              import sys
              import logging
              import socket
              import threading
              import struct
              import time
              
              logger = logging.getLogger('')
              
              
              class luxex(Exception):
                  pass
              
              
              class LuxBase():
              
                  def __init__(self, host, port=8888):
                      self.host = host
                      self.port = int(port)
                      self._sock = False
                      self._lock = threading.Lock()
                      self.is_connected = False
                      self._connection_attempts = 0
                      self._connection_errorlog = 60
                      self._params = []
                      self._attrs = []
                      self._calc = []
              
                  def get_attribute(self, identifier):
                      return self._attrs[identifier] if identifier < len(self._attrs) else None
              
                  def get_parameter(self, identifier):
                      return self._params[identifier] if identifier < len(self._params) else None
              
                  def get_calculated(self, identifier):
                      return self._calc[identifier] if identifier < len(self._calc) else None
              
                  def get_attribute_count(self):
                      return len(self._attrs)
              
                  def get_parameter_count(self):
                      return len(self._params)
              
                  def get_calculated_count(self):
                      return len(self._calc)
              
                  def connect(self):
                      self._lock.acquire()
                      try:
                          self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                          self._sock.settimeout(2)
                          self._sock.connect((self.host, self.port))
                      except Exception as e:
                          self._connection_attempts -= 1
                          if self._connection_attempts <= 0:
                              logger.error(
                                  'Luxtronic2: could not connect to {0}:{1}: {2}'.format(self.host, self.port, e))
                              self._connection_attempts = self._connection_errorlog
                          return
                      finally:
                          self._lock.release()
                      logger.info(
                          'Luxtronic2: connected to {0}:{1}'.format(self.host, self.port))
                      self.is_connected = True
                      self._connection_attempts = 0
              
                  def close(self):
                      self.is_connected = False
                      try:
                          self._sock.close()
                          self._sock = False
                      except:
                          pass
              
                  def _request(self, request, length):
                      if not self.is_connected:
                          raise luxex("no connection to luxtronic.")
                      try:
                          self._sock.send(request)
                      except Exception as e:
                          self._lock.release()
                          self.close()
                          raise luxex("error sending request: {0}".format(e))
                      try:
                          answer = self._sock.recv(length)
                      except socket.timeout:
                          self._lock.release()
                          raise luxex("error receiving answer: timeout")
                      except Exception as e:
                          self._lock.release()
                          self.close()
                          raise luxex("error receiving answer: {0}".format(e))
                      return answer
              
                  def _request_more(self, length):
                      try:
                          return self._sock.recv(length)
                      except socket.timeout:
                          self._lock.release()
                          raise luxex("error receiving payload: timeout")
                      except Exception as e:
                          self._lock.release()
                          self.close()
                          raise luxex("error receifing payload: {0}".format(e))
              
                  def set_param(self, param, value):
                      param = int(param)
              #       old = self._params[param] if param < len(self._params) else 0
                      payload = struct.pack('!iii', 3002, int(param), int(value))
                      self._lock.acquire()
                      answer = self._request(payload, 8)
                      self._lock.release()
                      if len(answer) != 8:
                          self.close()
                          raise luxex("error receiving answer: no data")
                      answer = struct.unpack('!ii', answer)
                      fields = ['cmd', 'param']
                      answer = dict(list(zip(fields, answer)))
                      if answer['cmd'] == 3002 and answer['param'] == param:
                          logger.debug(
                              "Luxtronic2: value {0} for parameter {1} stored".format(value, param))
                          return True
                      else:
                          logger.warning(
                              "Luxtronic2: value {0} for parameter {1} not stored".format(value, param))
                          return False
              
                  def refresh_parameters(self):
                      request = struct.pack('!ii', 3003, 0)
                      self._lock.acquire()
                      answer = self._request(request, 8)
                      if len(answer) != 8:
                          self._lock.release()
                          self.close()
                          raise luxex("error receiving answer: no data")
                      answer = struct.unpack('!ii', answer)
                      fields = ['cmd', 'len']
                      answer = dict(list(zip(fields, answer)))
                      if answer['cmd'] == 3003:
                          params = []
                          for i in range(0, answer['len']):
                              param = self._request_more(4)
                              params.append(struct.unpack('!i', param)[0])
                          self._lock.release()
                          if len(params) > 0:
                              self._params = params
                              return True
                          return False
                      else:
                          self._lock.release()
                          logger.warning("Luxtronic2: failed to retrieve parameters")
                          return False
              
                  def refresh_attributes(self):
                      request = struct.pack('!ii', 3005, 0)
                      self._lock.acquire()
                      answer = self._request(request, 8)
                      if len(answer) != 8:
                          self._lock.release()
                          self.close()
                          raise luxex("error receiving answer: no data")
                      answer = struct.unpack('!ii', answer)
                      fields = ['cmd', 'len']
                      answer = dict(list(zip(fields, answer)))
                      if answer['cmd'] == 3005:
                          attrs = []
                          for i in range(0, answer['len']):
                              attr = self._request_more(1)
                              attrs.append(struct.unpack('!b', attr)[0])
                          self._lock.release()
                          if len(attrs) > 0:
                              self._attrs = attrs
                              return True
                          return False
                      else:
                          self._lock.release()
                          logger.warning("Luxtronic2: failed to retrieve attributes")
                          return False
              
                  def refresh_calculated(self):
                      request = struct.pack('!ii', 3004, 0)
                      self._lock.acquire()
                      answer = self._request(request, 12)
                      if len(answer) != 12:
                          self._lock.release()
                          self.close()
                          raise luxex("error receiving answer: no data")
                      answer = struct.unpack('!iii', answer)
                      fields = ['cmd', 'state', 'len']
                      answer = dict(list(zip(fields, answer)))
                      if answer['cmd'] == 3004:
                          calcs = []
                          for i in range(0, answer['len']):
                              calc = self._request_more(4)
                              calcs.append(struct.unpack('!i', calc)[0])
                          self._lock.release()
                          if len(calcs) > 0:
                              self._calc = calcs
                              return answer['state']
                          return 0
                      else:
                          self._lock.release()
                          logger.warning("Luxtronic2: failed to retrieve calculated")
                          return 0
              
              
              class Luxtronic2(LuxBase):
                  _parameter = {}
                  _attribute = {}
                  _calculated = {}
                  _decoded = {}
                  alive = True
              
                  def __init__(self, smarthome, host, port=8888, cycle=120):
                      LuxBase.__init__(self, host, port)
                      self._sh = smarthome
                      self._cycle = int(cycle)
                      self.connect()
              
                  def run(self):
                      self.alive = True
                      self._sh.scheduler.add('Luxtronic2', self._refresh, cycle=self._cycle)
              
                  def stop(self):
                      self.alive = False
              
                  def _refresh(self):
                      if not self.is_connected:
                          return
                      start = time.time()
                      if len(self._parameter) > 0:
                          self.refresh_parameters()
                          for p in self._parameter:
                              val = self.get_parameter(p)
                              if val:
                                  self._parameter[p](val, 'Luxtronic2')
                      if len(self._attribute) > 0:
                          self.refresh_attributes()
                          for a in self._attribute:
                              val = self.get_attribute(a)
                              if val:
                                  self._attribute[a](val, 'Luxtronic2')
                      if len(self._calculated) > 0 or len(self._decoded) > 0:
                          self.refresh_calculated()
                          for c in self._calculated:
                              val = self.get_calculated(c)
                              if val:
                                  self._calculated[c](val, 'Luxtronic2')
                          for d in self._decoded:
                              val = self.get_calculated(d)
                              if val:
                                  self._decoded[d](self._decode(d, val), 'Luxtronic2')
                      cycletime = time.time() - start
                      logger.debug("cycle takes {0} seconds".format(cycletime))
              
                  def _decode(self, identifier, value):
                      if identifier == 118:
                          if value == 0:
                              return 'Test'
                          if value == 1:
                              return 'Waermepumpe steht'
                          if value == 2:
                              return 'Test2'
                          if value == 3:
                              return 'Test3'
                          return '???'
                      if identifier == 120:
                          if value == 0:
                              return 'Heizbetrieb'
                          if value == 1:
                              return 'Keine Anforderung'
                          if value == 2:
                              return 'Netz- Einschaltverzoegerung'
                          if value == 3:
                              return 'SSP Zeit'
                          if value == 4:
                              return 'Sperrzeit'
                          if value == 5:
                              return 'Brauchwasser'
                          if value == 6:
                              return 'Estrich Programm'
                          if value == 7:
                              return 'Abtauen'
                          if value == 8:
                              return 'Pumpenvorlauf'
                          if value == 9:
                              return 'Thermische Desinfektion'
                          if value == 10:
                              return 'Kuehlbetrieb'
                          if value == 12:
                              return 'Schwimmbad'
                          if value == 13:
                              return 'Heizen Ext.'
                          if value == 14:
                              return 'Brauchwasser Ext.'
                          if value == 16:
                              return 'Durchflussueberwachung'
                          if value == 17:
                              return 'ZWE Betrieb'
                          return '???'
                      if identifier == 10:
                          return float(value) / 10
                      if identifier == 11:
                          return float(value) / 10
                      if identifier == 12:
                          return float(value) / 10
                      if identifier == 15:
                          return float(value) / 10
                      if identifier == 19:
                          return float(value) / 10
                      if identifier == 20:
                          return float(value) / 10
                      if identifier == 151:
                          return float(value) / 10
                      if identifier == 152:
                          return float(value) / 10
                      return value
              
                  def parse_item(self, item):
                      if 'lux2' in item.conf:
                          d = item.conf['lux2']
                          d = int(d)
                          self._decoded[d] = item
                      if 'lux2_a' in item.conf:
                          a = item.conf['lux2_a']
                          a = int(a)
                          self._attribute[a] = item
                      if 'lux2_c' in item.conf:
                          c = item.conf['lux2_c']
                          c = int(c)
                          self._calculated[c] = item
                      if 'lux2_p' in item.conf:
                          p = item.conf['lux2_p']
                          p = int(p)
                          self._parameter[p] = item
                          return self.update_item
              
                  def update_item(self, item, caller=None, source=None, dest=None):
                      if caller != 'Luxtronic2':
                          self.set_param(item.conf['lux2_p'], item())
              
              
              def main():
                  try:
                      lux = LuxBase('192.168.1.11')
                      lux.connect()
                      if not lux.is_connected:
                          return 1
                      start = time.time()
                      lux.refresh_parameters()
                      lux.refresh_attributes()
                      lux.refresh_calculated()
                      cycletime = time.time() - start
                      print("{0} Parameters:".format(lux.get_parameter_count()))
                      for i in range(0, lux.get_parameter_count()):
                          print("  {0} = {1}".format(i + 1, lux.get_parameter(i)))
                      print("{0} Attributes:".format(lux.get_attribute_count()))
                      for i in range(0, lux.get_attribute_count()):
                          print("  {0} = {1}".format(i + 1, lux.get_attribute(i)))
                      print("{0} Calculated:".format(lux.get_calculated_count()))
                      for i in range(0, lux.get_calculated_count()):
                          print("  {0} = {1}".format(i + 1, lux.get_calculated(i)))
                      print("cycle takes {0} seconds".format(cycletime))
              
                  except Exception as e:
                      print("[EXCEPTION] error main: {0}".format(e))
                      return 1
                  finally:
                      if lux:
                          lux.close()
              
              if __name__ == "__main__":
                  sys.exit(main())
              Oder sind hier noch mehr Anpassungen notwendig??

              Edit: Habe den dazugehörigen Fehler-Log:
              Code:
              2015-10-05 01:16:04,406 DEBUG    Luxtronic2   cycle takes 0.19151806831359863 seconds -- __init__.py:_refresh:275
              2015-10-05 01:16:04,721 DEBUG    Scheduler    Luxtronic2 next time: 2015-10-05 01:18:04+02:00 -- scheduler.py:_next_time:289
              2015-10-05 01:17:50,363 DEBUG    galaxys3.ping Triggering galaxys3.ping-eval - by: Scheduler source: None dest: None value: {'dest': None, 'source': None, 'caller': -- scheduler.py:trigger:162
              2015-10-05 01:17:50,874 DEBUG    Scheduler    galaxys3.ping next time: 2015-10-05 01:19:50+02:00 -- scheduler.py:_next_time:289
              2015-10-05 01:17:53,416 DEBUG    galaxys5.ping Triggering galaxys5.ping-eval - by: Scheduler source: None dest: None value: {'dest': None, 'source': None, 'caller': -- scheduler.py:trigger:162
              2015-10-05 01:17:53,928 DEBUG    Scheduler    galaxys5.ping next time: 2015-10-05 01:19:53+02:00 -- scheduler.py:_next_time:289
              2015-10-05 01:18:04,551 DEBUG    Scheduler    Luxtronic2 next time: 2015-10-05 01:20:04+02:00 -- scheduler.py:_next_time:289
              2015-10-05 01:18:06,048 ERROR    Luxtronic2   Method Luxtronic2 exception: error receiving answer: timeout -- scheduler.py:_task:348
              Traceback (most recent call last):
                File "/usr/smarthome/plugins/luxtronic2/__init__.py", line 106, in _request
                  answer = self._sock.recv(length)
              socket.timeout: timed out
              
              During handling of the above exception, another exception occurred:
              
              Traceback (most recent call last):
                File "/usr/smarthome/lib/scheduler.py", line 344, in _task
                  obj()
                File "/usr/smarthome/plugins/luxtronic2/__init__.py", line 253, in _refresh
                  self.refresh_parameters()
                File "/usr/smarthome/plugins/luxtronic2/__init__.py", line 152, in refresh_parameters
                  answer = self._request(request, 8)
                File "/usr/smarthome/plugins/luxtronic2/__init__.py", line 109, in _request
                  raise luxex("error receiving answer: timeout")
              plugins.luxtronic2.luxex: error receiving answer: timeout


              Lg Max
              Zuletzt geändert von Max2612; 05.10.2015, 12:32.

              Kommentar

              Lädt...
              X