Ankündigung

Einklappen
Keine Ankündigung bisher.

UZSU schaltet nicht immer

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

    UZSU schaltet nicht immer

    Hallo,

    ich benutze die UZSU schon lange, habe aber nach wie vor folgendes Problem:

    Wenn ich zur selben Zeit mehrere Elemente schalten lasse z.B. mehrere Rolläden oder Lampen, kommt es relativ häufig vor, dass eine Rollade nicht verfährt oder ein Licht nicht schaltet. Als Workaround lasse ich z.B. die Rolläden nacheinander (z.B. jede Minute, 1. 6:00, 2. 6:01, 3. 6:02) fahren. Schön ist das allerdings nicht aber es funktioniert.

    Hat jemand von Euch auch diesen Effekt? Liegt das an meiner Installation? Kennt Jemand eine Lösung? Ich habe hier auch schon mal gelesen, das die UZSU in dieser Hinsicht ein grundsätzliches Problem mit der smarthome.py Architektur hat. Auch habe ich gelesen das eine neue Zeitschaltung entwickelt wird.

    Wer kann mir hier weiter helfen?

    #2
    Moin,

    es gibt da noch zwei Ansatzpunkte:

    Hast Du ggf. eibd-Parameter "--no-tunnel-client-queuing" gesetzt?

    Prüf mal auch zusätzlich, welchen ephem Version (aktuell ist Stand 1.10.2015 die 3.7.6.0) bei Dir installiert ist. Kann man rausfinden in dem man eine Shell auf dem Rechner öffnet:
    Code:
    smarthome@visu:~$ python3
    Python 3.4.3 (default, Jul 28 2015, 18:20:59)
    [GCC 4.8.4] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import ephem
    >>> ephem.__version__
    '3.7.6.0'
    >>>
    Gruß,
    Bernd

    Kommentar


      #3
      Ah ok, werde ich heute Abend mal prüfen...

      Kommentar


        #4
        Interessiert mich auch, habe das gleiche Problem.

        Kommentar


          #5
          Hast Du ggf. eibd-Parameter "--no-tunnel-client-queuing" gesetzt?
          So, hatte den Parameter nicht gesetzt. Wenn ich richtig verstanden habe setze ich diesen oder?

          Und ephem habe ich folgende Version:

          Code:
          admin@smarthome:/etc/default$ python3
          Python 3.2.3 (default, Mar  1 2013, 11:53:50)
          [GCC 4.6.3] on linux2
          Type "help", "copyright", "credits" or "license" for more information.
          >>> import ephem
          >>> ephem.__version__
          '3.7.5.1'
          Zuletzt geändert von Sprocky; 05.10.2015, 18:24.

          Kommentar


            #6
            Noch eine Möglichkeit, warum die UZSU nicht richtig schaltet, könnte ein nicht eindeutiges name-Attribut sein. Hat mir viel "Freude" bei der Fehlersuche gebracht:

            Code:
            [testdevices]
                name = Test Smarthome.py
                [[funktion1]]
                    name = Funktion 1 ausfuehren
                    type = bool
                    visu_acl = rw
                    knx_dpt = 1
                    knx_send = 8/1/1
                    enforce_updates = yes
                    [[[uzsu]]]
                        name = Zeitschaltuhr
                        type = dict
                        enforce_updates = yes
                        uzsu_item = testdevices.funktion1
                        cache = True
                        visu_acl = rw
                [[funktion2]]
                    name = Funktion 2 ausfuehren
                    type = bool
                    visu_acl = rw
                    knx_dpt = 1
                    knx_send = 8/1/2
                    enforce_updates = yes
                    [[[uzsu]]]
                        name = Zeitschaltuhr
                        type = dict
                        enforce_updates = yes
                        uzsu_item = testdevices.funktion2
                        cache = True
                        visu_acl = rw
            In diesem Beispiel schaltet nur die zweite UZSU. Verteilen die UZSUs sich auf verschiedene conf-Dateien, läuft nur die Uhr (mit ident. name-Attribut), dessen conf-Datei als letztes geparst wurde. Mein Learning: Am besten auf das name-Attribut mit Pseudo-Beschreibung verzichten...

            Besten Gruß
            Michael

            Kommentar


              #7
              Hallo,

              Zitat von Sprocky Beitrag anzeigen
              ch habe hier auch schon mal gelesen, das die UZSU in dieser Hinsicht ein grundsätzliches Problem mit der smarthome.py Architektur hat. Auch habe ich gelesen das eine neue Zeitschaltung entwickelt wird.
              Das stimmt beides.

              Leider kann ich Dir momentan nicht weiterhelfen, da ich nicht das Plugin fixen möchte (wegen der neuen Zeitschaltuhr).

              Bis bald

              Marcus

              Kommentar


                #8
                Moin,

                ich habe mal einen Ansatz gemacht, das Plugin zu fixen. Es hat bei mir diese Woche bisher keine Aussetzer gegeben und bei einem anderen User ist das auch gerade im Beta-Test....

                Gruß,
                Bernd

                Kommentar


                  #9
                  welche neue Zeitschaltuhr wird es denn geben?
                  und vor allem wann?

                  Ich bin gerade dabei mich in uzsu einzulesen. läuft bis jetzt aber noch nicht....

                  Kommentar


                    #10
                    So, ich habe dazu bei github mal einen Pull-Request gemacht, aber ich weiß nicht, wie Marcus das in Zukunft handhabt mit dem Einpflegen. Wer will, kann folgende Datei mal als plugins/uzsu/__init__.py plazieren im uzsu Plugin:

                    Code:
                    #!/usr/bin/env python3
                    # vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
                    #########################################################################
                    # Copyright 2011-2013 Niko Will
                    #########################################################################
                    #  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/>.
                    ##########################################################################
                    
                    
                    # Item Data Format
                    #
                    # Each UZSU item is of type list. Each list entry has to be a dict with specific key and value pairs. Here are the possible keys and what their for:
                    #
                    #     dtstart: a datetime object. Exact datetime as start value for the rrule algorithm. Important e.g. for FREQ=MINUTELY rrules (optional).
                    #
                    #     value: the value which will be set to the item.
                    #
                    #     active: True if the entry is activated, False if not. A deactivated entry is stored to the database but doesn't trigger the setting of the value. It can be enabled later with the update method.
                    #
                    #     time: time as string to use sunrise/sunset arithmetics like in the crontab eg. 17:00<sunset, sunrise>8:00, 17:00<sunset. You also can set the time with 17:00.
                    #
                    #     rrule: You can use the recurrence rules documented in the iCalendar RFC for recurrence use of a switching entry.
                    #
                    # Example
                    #
                    # Activates the light every other day at 16:30 and deactivates it at 17:30 for five times:
                    #
                    # sh.eg.wohnen.kugellampe.uzsu({'active':True, 'list':[
                    # {'value':1, 'active':True, 'rrule':'FREQ=DAILY;INTERVAL=2;COUNT=5', 'time': '16:30'},
                    # {'value':0, 'active':True, 'rrule':'FREQ=DAILY;INTERVAL=2;COUNT=5', 'time': '17:30'}
                    # ]})
                    
                    
                    
                    import logging
                    from datetime import datetime, timedelta
                    
                    from dateutil.rrule import rrulestr
                    from dateutil import parser
                    
                    import lib.orb
                    
                    class UZSU():
                    
                        _items = {}         # item buffer for all uzsu enabled items
                    
                        def __init__(self, smarthome, path=None):
                            self.logger = logging.getLogger('UZSU')
                            self.logger.info('Init UZSU')
                            self._sh = smarthome
                    
                        def parse_item(self, item):
                            if 'uzsu_item' in item.conf:
                                self._items[item] = item()
                                return self.update_item
                    
                        def run(self):
                            """This is called once at the beginning after all items are already parsed from smarthome.py
                            All active uzsu items are registered to the scheduler
                            """
                            self.alive = True
                            for item in self._items:
                                if 'active' in self._items[item]:
                                    if self._items[item]['active']:
                                        self._schedule(item)
                    
                        def stop(self):
                            self.alive = False
                    
                        def update_item(self, item, caller=None, source=None, dest=None):
                            """
                            This is called by smarthome engine when the item changes, e.g. by Visu or by the command line interface
                            The relevant item is put into the internal item list and registered to the scheduler
                            """
                            self._items[item] = item()
                            self._schedule(item)
                    
                        def _schedule(self, item):
                            """
                            This function schedules an item: First the item is removed from the scheduler. If the item is active
                            then the list is searched for the nearest next execution time
                            """
                            self._sh.scheduler.remove('uzsu_{}'.format(item))
                            _next = None
                            _value = None
                            if 'active' in self._items[item]:
                                if self._items[item]['active']:
                                    for entry in self._items[item]['list']:
                                        next, value = self._next_time(entry)
                                        if _next is None:
                                            _next = next
                                            _value = value
                                        elif next and next < _next:
                                            _next = next
                                            _value = value
                            if _next and not _value is None:
                                self._sh.scheduler.add('uzsu_{}'.format(item), self._set, value={'item': item, 'value': _value}, next=_next)
                    
                        def _set(self, **kwargs):
                            item = kwargs['item']
                            value = kwargs['value']
                            self._sh.return_item(item.conf['uzsu_item'])(value, caller='UZSU')
                            self._schedule(item)
                    
                        def _next_time(self, entry):
                            """
                            Here we examine an entry of the list of points in time and return the next execution time and the next value
                            """
                            try:
                                if not isinstance(entry, dict):
                                    return None, None
                                if not 'value' in entry:
                                    return None, None
                                if not 'active' in entry:
                                    return None, None
                                if not 'time' in entry:
                                    return None, None
                                now = datetime.now()
                                value = entry['value']
                                active = entry['active']
                                today = datetime.today()
                                yesterday = today - timedelta(days=1)
                                time = entry['time']
                                if not active:
                                    return None, None
                                if 'date' in entry:
                                    date = entry['date']
                                if 'rrule' in entry:
                                    if 'dtstart' in entry:
                                        rrule = rrulestr(entry['rrule'], dtstart=entry['dtstart'])
                                    else:
                                        try:
                                            rrule = rrulestr(entry['rrule'], dtstart=datetime.combine(yesterday, parser.parse(time.strip()).time()))
                                        except Exception as e:
                                            self.logger.debug("Tolerated Exception '{}' while examining '{}' with function rrulestr()".format(e,time))
                                            if 'sun' in time:
                                                self.logger.debug("Looking for next sun-related time with rulestr()")
                                                rrule = rrulestr(entry['rrule'], dtstart=datetime.combine(yesterday, self._sun(datetime.combine(yesterday.date(), datetime.min.time()).replace(tzinfo=self._sh.tzinfo()), time).time()))
                                            else:
                                                self.logger.debug("Looking for next time with rulestr()")
                                                rrule = rrulestr(entry['rrule'], dtstart=datetime.combine(yesterday, datetime.min.time()))
                                    dt = now
                                    while self.alive:
                                        dt = rrule.after(dt)
                                        if dt is None:
                                            return None, None
                                        if 'sun' in time:
                                            next = self._sun(datetime.combine(dt.date(), datetime.min.time()).replace(tzinfo=self._sh.tzinfo()), time)
                                            self.logger.debug("Result parsing time (rrule){}: {}".format(time, next))                 
                                        else:
                                            next = datetime.combine(dt.date(), parser.parse(time.strip()).time()).replace(tzinfo=self._sh.tzinfo())
                                        if next and next.date() == dt.date() and next > datetime.now(self._sh.tzinfo()):
                                            return next, value
                                if 'sun' in time:
                                    next = self.sun(datetime.combine(today, datetime.min.time()).replace(tzinfo=self._sh.tzinfo()), time)
                                    self.logger.debug("Result parsing time (sun) {}: {}".format(time, next))              
                                else:
                                    next = datetime.combine(today, parser.parse(time.strip()).time()).replace(tzinfo=self._sh.tzinfo())
                                if next and next.date() == today and next > datetime.now(self._sh.tzinfo()):
                                    return next, value
                            except Exception as e:
                                self.logger.error("Error '{}' parsing time: {}".format(time, e))
                            return None, None
                    
                        def _sun(self, dt, tstr):
                            #dt contains a datetime object, whereas tstr should contain a string like '6:00<sunrise<8:00'
                            #syntax is [H:M<](sunrise|sunset)[+|-][offset][<H:M]
                    
                            # checking preconditions from configuration:
                            if not self._sh.sun:  # no sun object created
                                self.logger.error('No latitude/longitude specified. You could not use sunrise/sunset as UZSU entry.')
                                return
                    
                            # create an own sun object:
                            try:
                                #longitude = self._sh.sun.long
                                #latitude = self._sh.sun.lat
                                #elevation = self._sh.sun.elevation
                                longitude = self._sh.sun._obs.long
                                latitude = self._sh.sun._obs.lat
                                elevation = self._sh.sun._obs.elev
                                uzsu_sun = lib.orb.Orb('sun', longitude, latitude, elevation)
                                self.logger.debug("Created a new sun object with latitude={}, longitude={}, elevation={}".format(latitude, longitude, elevation))
                            except Exception as e:
                                self.logger.error("Error '{}' creating a new sun object. You could not use sunrise/sunset as UZSU entry.".format(e))
                                return
                    
                            # now start into parsing details
                            self.logger.debug('Examine time string: {0}'.format(tstr))
                                
                            # find min/max times
                            tabs = tstr.split('<')
                            if len(tabs) == 1:
                                smin = None
                                cron = tabs[0].strip()
                                smax = None
                            elif len(tabs) == 2:
                                if tabs[0].startswith('sun'):
                                    smin = None
                                    cron = tabs[0].strip()
                                    smax = tabs[1].strip()
                                else:
                                    smin = tabs[0].strip()
                                    cron = tabs[1].strip()
                                    smax = None
                            elif len(tabs) == 3:
                                smin = tabs[0].strip()
                                cron = tabs[1].strip()
                                smax = tabs[2].strip()
                            else:
                                self.logger.error('Wrong syntax: {0}. Should be [H:M<](sunrise|sunset)[+|-][offset][<H:M]'.format(tstr))
                                return
                    
                            # calculate the time offset
                            doff = 0  # degree offset
                            moff = 0  # minute offset
                            tmp, op, offs = cron.rpartition('+')
                            if op:
                                if offs.endswith('m'):
                                    moff = int(offs.strip('m'))
                                else:
                                    doff = float(offs)
                            else:
                                tmp, op, offs = cron.rpartition('-')
                                if op:
                                    if offs.endswith('m'):
                                        moff = -int(offs.strip('m'))
                                    else:
                                        doff = -float(offs)
                    
                            # see if sunset or sunrise are included
                            dmin = None
                            dmax = None
                            if cron.startswith('sunrise'):
                                next_time = uzsu_sun.rise(doff, moff, dt=dt)
                                self.logger.debug("Sunrise is included and calculated as {}".format(next_time))
                            elif cron.startswith('sunset'):
                                next_time = uzsu_sun.set(doff, moff, dt=dt)
                                self.logger.debug("Sunset is included and calculated as {}".format(next_time))
                            else:
                                self.logger.error('Wrong syntax: {0}. Should be [H:M<](sunrise|sunset)[+|-][offset][<H:M]'.format(tstr))
                                return
                    
                            if smin is not None:
                                h, sep, m = smin.partition(':')
                                try:
                                    dmin = next_time.replace(hour=int(h), minute=int(m), second=0, tzinfo=self._sh.tzinfo())
                                except Exception:
                                    self.logger.error('Wrong syntax: {0}. Should be [H:M<](sunrise|sunset)[+|-][offset][<H:M]'.format(tstr))
                                    return
                                if dmin > next_time:
                                    next_time = dmin
                            if smax is not None:
                                h, sep, m = smax.partition(':')
                                try:
                                    dmax = next_time.replace(hour=int(h), minute=int(m), second=0, tzinfo=self._sh.tzinfo())
                                except Exception:
                                    self.logger.error('Wrong syntax: {0}. Should be [H:M<](sunrise|sunset)[+|-][offset][<H:M]'.format(tstr))
                                    return
                                if dmax < next_time:
                                    next_time = dmax
                            
                            if dmin is not None and dmax is not None:
                                if dmin > dmax:
                                    self.logger.error('Wrong times: the earliest time should be smaller than the latest time in {}'.format(tstr))
                                    return
                                
                            return next_time
                    Der Fix richtet sich eigentlich an Probleme mit sunrise und sunset. Es wird ein eigenes sun Objekt dafür erstellt so das ephem auch dafür dann eigene Objekte nutzt. Die Probleme mit dem Scheduler (soweit es diesen betrifft) löst der Fix nicht unbedingt.

                    Gruß,
                    Bernd

                    Kommentar


                      #11
                      Hallo Bernd,

                      habe mal nachvollzogen und erscheint mir eine fast vollwertige Lösung zum Problem jenseits von Problemen in ephem (falls vorhanden).

                      Danke dafür.

                      Michel

                      Kommentar


                        #12
                        Hallo Bernd,

                        danke für den tollen Fix, der bis heute bei mir sehr gut gelaufen ist. Heute ist das Plugin aber über die Umstellung auf Sommerzeit gestolpert. Die mit sunset definierten items sind alle eine Stunde zu früh geschaltet worden. Die mit Festzeiten definierten items liefen richtig.

                        Ich vermute, dass dies nur am Tag der Umstellung so ist und würde das gerne überprüfen. Gibt es eine Möglichkeit, dem Scheduler bei laufendem System zu entlocken, welche Zeiten er für den nächsten Tag berechnet hat? Über das CLI habe ich keine Möglichkeit gefunden. Da wird bei den uzsu-items die ganze Argumentliste angezeigt, aber nicht das Ergebnis für next_time. Klar könnte ich Smarthome im Debug-Modus neu starten, aber das könnte schon das Ergebnis beeinflussen, weil die Zeiten dann ganz neu berechnet werden.

                        Danke und Gruß
                        Wolfram

                        Kommentar


                          #13
                          Hi Wolfram,

                          aus meiner jetzigen Sicht: Nein.

                          Ich hatte mal angefangen so eine Funktionalität in das CLI zu integrieren, so das nicht nur die nächsten Laufzeiten der Logiken gezeigt wurden, sondern alternativ alle Schaltzeiten vom Scheduler. Kommt vielleicht nach der ersten Release vom smarthomeNG.

                          Gruß,
                          Bernd

                          Kommentar


                            #14
                            Hallo Bernd,

                            nochmals danke für die Einführung der eigenen Objekte. Bei hats bislang fehlerfrei funktioniert. Daher würde ich auf diesem Stand aufbauen und einige Funktionen erweitern wollen, die ich auf der FHEM Seite mitbekomme, da ich das UZSU POPUP Widget für die smartvisu maintaine.
                            Nur für den Fall, dass wir uns nicht auf den Füssen stehen. Ich würde dann in nächster Zeit das Plugin anfangen anzupassen.

                            Michel

                            Kommentar


                              #15
                              Hi Michel,

                              danke für Dein UZSU Plugin!!! Für die Zukunft könnte man eine Daylight Saving Time Erkennung mit einbauen. Ich lasse Dir gerne den Vortritt bei allen Dingen, es ist Dein Plugin, Dein Baby :-)
                              Wenn ich kann helfe ich gerne mit.

                              Gruß,
                              Bernd

                              Kommentar

                              Lädt...
                              X