Ankündigung

Einklappen
Keine Ankündigung bisher.

Referenzimplementierung Treppenhausautomat?

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

    Referenzimplementierung Treppenhausautomat?

    Hi!

    Ich stehe gerade ein bisschen auf dem Schlauch, wie ich möglichst effzient einen Treppenhausautomat hinbekomme...

    Eingang: trigger_item was alle 30 sec auf 1 gesetzt wird (also "force_updates = true")
    Ausgang: Item das bei Empfang des trigger_item auf '1' und zwei Minuten nach dem letzten Empfang auf '0' gesetzt wird.

    Logik-Config: watch_item = trigger_item

    Logik:
    Code:
    if (trigger['source'] == watch_item) and watch_item():
       sh.scheduler.add(????? - EINMALIG AUFRUFEN NACH 120 SEC - FALLS SCHON GESETZT NACHTRIGGERN
    else:
       send_item(0)
    Irgendwie werde ich spontan selbst aus der scheduler.py nicht schlau...

    Grüße
    Robert

    #2
    Puuh, geht es schöner:

    Code:
    #!/usr/bin/env python
    
    if ((trigger['source'] in getattr(logic, "watch_item")) and trigger['value']):
        logger.info('LOGIC---{0}---: true and (re)set timer'.format(logic.name))
        sh.return_item(getattr(logic, "send_item"))(1, logic.name)
        sh.scheduler.remove(logic.name + '.' + trigger['source'])
        #sh.scheduler.add(logic.name + '.' + trigger['source'], logic, offset=int(getattr(logic, "delay")))
        #sh.scheduler.add(logic.name + '.' + trigger['source'], logic, cycle=30, offset=int(getattr(logic, "delay")))
        sh.scheduler.add(logic.name + '.' + trigger['source'], logic, cron='init', offset=int(getattr(logic, "delay")))
    #    sh.scheduler.add(logic.name + '.' + trigger['source'], sh.return_item(getattr(logic, "send_item")), cron='init', offset=int(getattr(logic, "delay")), value=False)
    else:
        logger.info('LOGIC---{0}---: false'.format(logic.name))
        sh.return_item(getattr(logic, "send_item"))(0, logic.name)
    Was ich nicht verstehe:
    • warum muss ich cron="init" mitgeben?
    • mit cycle habe ich es nicht hinbekommen?
    • wird mit cron=init" der Timer nur einmal aufgerufen? Ich finde kein Löschen...
    • Könnte ich statt die Logik erneut zu triggern einfach das Item selbst eintragen und Value=False?

    Hat noch kein anderer solche dynamisch getimedten Logiken gemacht?

    Kommentar


      #3
      Ich verzweifle hier auch an add und change des schedulers:

      Folgender Code:
      Code:
      #/logics/zirkulation.py
      #!/usr/bin/env python
      
      ### config ###
      zirk_item = sh.zirk             #item Zirkulationspumpe (bool)
      praesenz_item = sh.ow.praesenz   #item Praesenz (bool)
      ww_item = sh.ebus.status_wp     #item Status Warmwasserbereitung
      ww_values = [62,7,8]            #Werte von Status Warmwasserbereitung bei denen Zirkulation laufen soll als Liste!
      
      base_time = 3                  #Basis-Zeit Minuten
      on_perc = 33                     #PWM in %
      ### end config ###
      
      on = int(base_time * 60 * on_perc / 100)
      off = int(base_time * 60 - on)
      #logger.debug('Zirkulation Age: {0} Status: {1} on: {2} off: {3} in {4}'.format(zirk_item.age(),zirk_item(),on,off,logic.filename))
      
      ### Check Warmwasserbereitung
      for i in ww_values:
          if ww_item() == i:
              if not zirk_item:
                  zirk_item('True')
              logger.info('Zirkulation aufgrund Warmwasserbereitung')
              sys.exit()
      
      ### PWM & Praesenz
      if zirk_item() == True: #and zirk_item.age() > on:
          zirk_item('False')
          logger.info('Zirkulation aus fuer {} Sekunden'.format(off))
          #logger.debug('Zirkulation Soll:0 - Age: {0} Status: {1} on: {2} off: {3}'.format(zirk_item.age(),zirk_item(),on,off))
      [B][COLOR="Navy"]    sh.scheduler.remove(logic.name)
          sh.scheduler.add(logic.name, logic, cycle=121)[/COLOR][/B]
          sys.exit()
      if zirk_item() == False: #and zirk_item.age() > off and praesenz_item() == True:
          zirk_item('True')
          logger.info('Zirkulation an fuer {} Sekunden'.format(on))
          #logger.debug('Zirkulation Soll:1 - Age: {0} Status: {1} on: {2} off: {3}'.format(zirk_item.age(),zirk_item(),on,off))
      [COLOR="navy"][B]    sh.scheduler.remove(logic.name)
          sh.scheduler.add(logic.name, logic, cycle=59)[/B][/COLOR]
          sys.exit()
      logic.conf:
      Code:
      [zirkulation]
          filename = zirkulation.py
          crontab = init
          #cycle = 60
      Ich hab oben im Code aus Verzweiflung bei sh.scheduler.add schon den cycle=xx= manuell eingetragen, dennoch wird alle 6-8 Sekunden neu getriggert:

      Code:
      2013-09-29 13:25:38,907 DEBUG    Main         Logic: zirkulation -- logic.py:__init__:46
      2013-09-29 13:25:42,048 DEBUG    zirkulation  zirk = True via Logic None -- item.py:_update:251
      2013-09-29 13:25:42,051 INFO     zirkulation  Zirkulation an fuer 59 Sekunden -- zirkulation.py:<module>:36
      2013-09-29 13:25:42,055 DEBUG    zirkulation  zirkulation next time: 2013-09-29 13:25:49+02:00 -- scheduler.py:_next_time:245
      2013-09-29 13:25:49,099 DEBUG    zirkulation  zirk = False via Logic None -- item.py:_update:251
      2013-09-29 13:25:49,104 INFO     zirkulation  Zirkulation aus fuer 121 Sekunden -- zirkulation.py:<module>:29
      2013-09-29 13:25:49,108 DEBUG    zirkulation  zirkulation next time: 2013-09-29 13:25:57+02:00 -- scheduler.py:_next_time:245
      2013-09-29 13:25:57,150 DEBUG    zirkulation  zirk = True via Logic None -- item.py:_update:251
      2013-09-29 13:25:57,154 INFO     zirkulation  Zirkulation an fuer 59 Sekunden -- zirkulation.py:<module>:36
      2013-09-29 13:25:57,157 DEBUG    zirkulation  zirkulation next time: 2013-09-29 13:26:07+02:00 -- scheduler.py:_next_time:245
      2013-09-29 13:26:07,007 DEBUG    zirkulation  zirk = False via Logic None -- item.py:_update:251
      2013-09-29 13:26:07,011 INFO     zirkulation  Zirkulation aus fuer 121 Sekunden -- zirkulation.py:<module>:29
      2013-09-29 13:26:07,015 DEBUG    zirkulation  zirkulation next time: 2013-09-29 13:26:15+02:00 -- scheduler.py:_next_time:245
      2013-09-29 13:26:15,055 DEBUG    zirkulation  zirk = True via Logic None -- item.py:_update:251
      2013-09-29 13:26:15,056 INFO     zirkulation  Zirkulation an fuer 59 Sekunden -- zirkulation.py:<module>:36
      2013-09-29 13:26:15,059 DEBUG    zirkulation  zirkulation next time: 2013-09-29 13:26:27+02:00 -- scheduler.py:_next_time:245
      2013-09-29 13:26:27,119 DEBUG    zirkulation  zirk = False via Logic None -- item.py:_update:251
      2013-09-29 13:26:27,120 INFO     zirkulation  Zirkulation aus fuer 121 Sekunden -- zirkulation.py:<module>:29
      2013-09-29 13:26:27,121 DEBUG    zirkulation  zirkulation next time: 2013-09-29 13:26:33+02:00 -- scheduler.py:_next_time:245
      2013-09-29 13:26:33,158 DEBUG    zirkulation  zirk = True via Logic None -- item.py:_update:251
      2013-09-29 13:26:33,161 INFO     zirkulation  Zirkulation an fuer 59 Sekunden -- zirkulation.py:<module>:36
      2013-09-29 13:26:33,165 DEBUG    zirkulation  zirkulation next time: 2013-09-29 13:26:44+02:00 -- scheduler.py:_next_time:245
      EDIT:
      Jetzt hab ich es, nach einem Blick in die lib/scheduler.py wurde es klar ... dennoch nicht gerade intuitiv.
      Man setzt cycle=0 und macht die nächste Ausführung über offset=xx.


      Code:
      ### PWM & Praesenz
      if zirk_item() == True: #and zirk_item.age() > on:
          zirk_item('False')
          logger.info('Zirkulation aus fuer {} Sekunden'.format(off))
          #logger.debug('Zirkulation Soll:0 - Age: {0} Status: {1} on: {2} off: {3}'.format(zirk_item.age(),zirk_item(),on,off))
          sh.scheduler.remove(logic.name)
          [COLOR="navy"][B]sh.scheduler.add(logic.name, logic, cycle=0, offset=off)[/B][/COLOR]
          sys.exit()
      if zirk_item() == False: #and zirk_item.age() > off and praesenz_item() == True:
          zirk_item('True')
          logger.info('Zirkulation an fuer {} Sekunden'.format(on))
          #logger.debug('Zirkulation Soll:1 - Age: {0} Status: {1} on: {2} off: {3}'.format(zirk_item.age(),zirk_item(),on,off))
          sh.scheduler.remove(logic.name)
          [COLOR="Navy"][B]sh.scheduler.add(logic.name, logic, cycle=0, offset=on)[/B][/COLOR]
          sys.exit()

      Dank und Gruß
      Umgezogen? Ja! ... Fertig? Nein!
      Baustelle 2.0 !

      Kommentar


        #4
        Hi,

        der ganze Thread ist irgendwie an mir vorbei gegangen.

        Kennt Ihr? https://knx-user-forum.de/smarthome-...autotimer.html

        Bis bald

        Marcus

        Kommentar


          #5
          Ein zwischenzeitlicher trigger auf eine logic macht den scheduler kaputt - stimmts?
          Timer sollte dann heil bleiben? Irgendwie dreht sich das im Kreis - ich sitz schon den ganzen Tag an immer wieder neuen Ansätzen und letztlich fehlt immer ein neues Detail dass es rund wird.
          Umgezogen? Ja! ... Fertig? Nein!
          Baustelle 2.0 !

          Kommentar


            #6
            Hi Mirko,

            erzähl doch mal was Du eigentlich machen möchtest. Also in ein paar Sätzen.

            Aus dem Code werde ich nicht so ganz schlau.

            Bis bald

            Marcus

            Kommentar


              #7
              Eigentlich ganz einfach:

              -Zirkulation soll in X Miuten für Y Minuten an sein.
              -läuft bei der Wärmepume die WW-Bereitung soll die Zirkulation so lange laufen
              -bei Abwesenheit soll auch die Zirkulation aus sein

              Die Details:
              -sauberes Verhalten der Logic, egal zu welchem Zeitpunkt sh.py gestartet wird
              -Triggern durch Paraesenz, WP und zusätzlich mal Präsenzmelder

              Ich hab's schon am laufen gehabt in dem ich die Logik jede Minute aufrufe, das funktioniert auch ... Ich wollte es noch eleganter .
              Umgezogen? Ja! ... Fertig? Nein!
              Baustelle 2.0 !

              Kommentar


                #8
                Da hätte ich bei Erstellung des Threads 1,5 Monate in die Zukunft gucken müssen. ;-)

                Hatte zwischenzeitlich schon wahrgenommen, dass es da ne schöne Lösung gibt.

                Grüße
                Robert

                Kommentar


                  #9
                  Hi Mirko,

                  ich würde es in etwa so realisieren: (Code ist nicht getestet)

                  Code:
                  # logics/zirkulation.py
                  
                  ### config ###
                  ww_values = [62,7,8]            #Werte von Status Warmwasserbereitung bei denen Zirkulation laufen soll als Liste!
                  base_time = 3                  #Basis-Zeit Minuten
                  on_perc = 33                     #PWM in %
                  on = int(base_time * 60 * on_perc / 100)
                  ### end config ###
                  
                  if not sh.ow.praesenz():  # niemand da
                      sh.zirk(False)
                  elif sh.ebus.status_wp() in ww_values:  # Wärempumpe läuft
                      sh.zirk(True)
                  else:
                      if not sh.zirk() and sh.zirk.age() > on:  # Zirkpumpe aus und das schon länger als 'on' Sekunden
                          sh.zirk(True)
                          sh.zirk.timer(10, False)
                  Die Logik kannst Du entweder nur mit crontab = init, cycle = 60 aufrufen. Oder noch folgende Item-Trigger hinzufügen: ow.praesenz, ebus.status_wp, bewegungsmelder, ....

                  Bis bald

                  Marcus

                  Kommentar


                    #10
                    Fast so hab ich es gemacht ... Dein Ansatz funktioniert bestens! Danke.

                    P.S.: Wo ist jetzt die Sammlung für universelle logics?



                    Code:
                    #/logics/zirkulation.py
                    #!/usr/bin/env python
                    #trigger logic by ww_item, zirk_item oder anything else
                    
                    ### config ###
                    zirk_item = sh.zirk             #item Zirkulationspumpe (bool)
                    praesenz_item = sh.ow.praesenz  #item Praesenz (bool)
                    ww_item = sh.ebus.status_wp     #item Status Warmwasserbereitung
                    ww_values = [62,7,8]            #Werte von Status Warmwasserbereitung bei denen Zirkulation laufen soll als Liste!
                    
                    base_time = 60                 #Basis-Zeit Minuten
                    on_perc = 10                      #PWM in %
                    ### end config ###
                    
                    on = int(base_time * 60 * on_perc / 100)
                    off = int(base_time * 60 - on)
                    
                    if not praesenz_item():  # niemand da
                        zirk_item(False)
                    
                    elif ww_item() in ww_values:  # Waermepumpe laeuft
                        zirk_item(True)
                    
                    else:
                        if not zirk_item() and zirk_item.age() >= off:  # Zirkpumpe aus und das schon laenger als 'off' Sekunden
                            zirk_item(True)
                            zirk_item.timer(on, False)
                    Umgezogen? Ja! ... Fertig? Nein!
                    Baustelle 2.0 !

                    Kommentar


                      #11
                      Zitat von JuMi2006 Beitrag anzeigen
                      P.S.: Wo ist jetzt die Sammlung für universelle logics?
                      Wiki.

                      Bis bald

                      Marcus

                      Kommentar


                        #12
                        Genau, kannste einfach die bisherige damit ersetzen. Kommentare sind schon ok.
                        Derzeit zwischen Kistenauspacken und Garten anlegen.
                        Baublog im Profil.

                        Kommentar

                        Lädt...
                        X