Ankündigung

Einklappen
Keine Ankündigung bisher.

- √ - Hilfe bei (erster) Logik

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

    - √ - Hilfe bei (erster) Logik

    Hallo,

    Ich (als Python Noob) versuche mich gerade an meiner ersten aufwendigeren Logik,
    Leider komm ich nach zig versuchen immer auf eine Fehlermeldung.

    Ich würde gerne meine Squeezebox im Bad mit dem Lichtschalter verknüpfen,
    Es soll von 6-7 uhr Morgens beim einschalten des Lichts der Radiosender Antenne Bayern abgespielt werden.
    Tagsüber zw. 7 und 21 Uhr soll der Radio aber mit dem Sender Rockantenne starten.
    Nach 21 Uhr soll er keinen Sender mehr einschalten.
    Und beim ausschalten des Lichts soll der Radio auch ausschalten.

    Bisher hätte ich folgende Logik erstellt (radio2.py):
    Code:
    #!/usr/bin/env python
         
    now = sh.now()
    
    # Switch go off
    if sh.radio.switch() == False:
        sh.Squeezebox_1.Power('False')
    
    # look for a value to set
    #if hasattr(logic, 'set_value'):
    #    val = logic.cond_value
    if hasattr(logic, 'start_time'):
        start_time = logic.start_time
    if hasattr(logic, 'end_time'):
        end_time = logic.end_time
    if hasattr(logic, 'nacht_time'):
        nacht_time = logic.nacht_time
    
    # Time
    
    unix = now.strftime('%s')
    sth,stm = start_time.split(':')
    enh,enm = end_time.split(':')
    nih,nim = nacht_time.split(':')
    sb = int(sth)
    print "sth {0}".format(sth)
    sm = int(stm)
    print "stm {0}".format(stm)
    eh = int(enh)
    print "enh {0}".format(enh)
    em = int(enm)
    print "enm {0}".format(enm)
    nh = int(nih)
    print "nih {0}".format(nih)
    nm = int(nim)
    print "nim {0}".format(nim)
        
    print now
    
    start = datetime.datetime(now.year, now.month, now.day, sb, sm, 0, 0)
    unix_start = int(start.strftime('%s'))
    print start
    
    end = datetime.datetime(now.year, now.month, now.day, eh, em, 0, 0)
    unix_end = int(end.strftime('%s'))
    print end
    
    nacht = datetime.datetime(now.year, now.month, now.day, nh, nm, 0, 0)
    unix_nacht = int(nacht.strftime('%s'))
    print nacht
    
    print unix
    print unix_start
    print unix_end
    print unix_nacht
    
    ###Startzeit vor Endzeit z.B. 14-18 Uhr
    if sb <= eh: ###Startzeit vor Endzeit z.B. 14-18 Uhr
        print "Startzeit vor Endzeit"
        if int(unix) < int(unix_nacht):
        print "Tag"
        if int(unix) > int(unix_start) and int(unix) < int(unix_end):
          sh.Squeezebox_1.AntenneBayern('True')
          print "AntenneBayern"
        if int(unix) < int(unix_nacht) and int(unix) > int(unix_end):
              sh.Squeezebox_1.Rockantenne('True')
              print "RockAntenne"
    Hier die logic.conf
    Code:
    [sender]
         filename = 'radio2.py'
         watch_item = radio.switch
         start_time = '6:00'
         end_time = '7:00'
         nacht_time = '21:00'
    die Squeezebox-Items.conf
    Code:
    [radio]
        [[switch]]
              type = bool
              visu = yes
    
    [Squeezebox_1]
      squeezebox_playerid = xx:xx:xx:xx:xx:xx
    
      [[Power]]
        type = bool
        visu = yes
        squeezebox_send = <playerid> power {}
        squeezebox_recv = <playerid> prefset server power
        squeezebox_init = <playerid> power    
                    
      [[AntenneBayern]]
              type = bool
              enforce_updates = true
              visu = yes
              squeezebox_send = <playerid> playlist play http://opml.radiotime.com/Tune.ashx?id=xxx&partnerId=xxx
      [[Rockantenne]]
              type = bool
              enforce_updates = true
              visu = yes
              squeezebox_send = <playerid> playlist play http://opml.radiotime.com/Tune.ashx?id=xxx&partnerId=xxx
    Im Logfile bekomm ich beim starten folgenden Fehler:
    Code:
    2013-10-21 21:02:18,636 SmartHome.py WARNING  Exception: unindent does not match any outer indentation level (radio2.py, line 61) -- logic.py:generate_bytecode:111
    line 61 wäre diese Zeile: if int(unix) < int(unix_nacht):

    Bis zu der Startzeit vor Endzeit hat es schon funktioniert,
    nur mit dem Zeitvergleich komm ich nicht weiter.

    Kann mir bitte jemand helfen ?

    Gruß, Mike

    #2
    Tja, das
    print "Tag"
    ist nicht eingerückt. Das mag Python nicht.

    Aber: Wäre es nicht besser, erstmal mit EINEM Zeitfenster und EINEM Sender anzufangen?

    Ansonsten interessantes Feature. Wenn sich herausstellen sollte, dass das Plugin dafür irgend eine Unzulänglichkeit aufweist versuche ich das schnell zu fixen.

    Grüße
    Robert

    Kommentar


      #3
      Warum nicht mit einem eval und eval Trigger ? Da braucht es kein Plugin.
      Ich lasse mir Speicher und Aussentemperatur auf 2 Lichtschaltern anzeigen:

      Code:
      [Squeezebox]
        [[Display_Speicher]]
          type = str
          knx_dpt = 4.002
          [B]knx_listen = 1/2/100[/B]
          enforce_updates = true
          squeezebox_send = <playerid> show line1:Speichertemperatur line2:{} centered:1 duration:10
          eval = str(int(sh.ow.WP_WW_SP()))+' C Grad'
        [[Display_Aussen]]
          type = str
          knx_dpt = 4.002
          [B]knx_listen = 1/2/35[/B]
          enforce_updates = true
          squeezebox_send = <playerid> show line1:Aussentemperatur line2:{} centered:1 duration:10
          eval = str(int(sh.ow.AT_Nord()))+' C Grad'
      Die eingetragenen GAs sind die der entsprechenden Leuchten. Das eval ließe sich ja leicht mit sh.now() auf die entsprechenden Stunden eingrenzen.
      Umgezogen? Ja! ... Fertig? Nein!
      Baustelle 2.0 !

      Kommentar


        #4
        Hm, also ich mag eval ja auch, aber Zeitraum bestimmen, evtl. Einschalten, Playliste laden,Lautstärke justieren und vor allem wieder intelligent ausschalten - Komm, da kann man sich eine eigene Datei gönnen. ;-)

        Kommentar


          #5
          Du machst doch selbst das Nachdimmen über eval oder hab ich das falsch in Erinnerung?

          Sollte das laden der Playliste nicht automatisch die Squeezebox einschalten? Play macht das jedenfalls.

          Grüße
          Umgezogen? Ja! ... Fertig? Nein!
          Baustelle 2.0 !

          Kommentar


            #6
            Nene, das ist eine eigene Logik. Nur die Selektion der betroffenen Leuchten und deren Helligkeit sind als Attribut direkt beim Item. So hab ich eine Logik für ca. 20 Leuchten. Kommt man natürlich nicht auf so "eindrucksvolle" Zahlen wie "über 600“, dafür aber gut wartbar.

            Mit Play hast du natürlich Recht, mit dem Laden von Playlisten war ich jetzt nicht sicher. Wenn es perfekt sein soll, müssen aber wohl auch noch Lautstärke etc. gesetzt werden. Irgendwann platzt dann das eval.

            Kommentar


              #7
              Ja da hast Du recht. Die benannte Aufstellung hat mich mehr als fasziniert . Ich hab da auch einfach ein Plugin geschrieben das mehrere RRDs auf einmal schreiben kann. Langweilig.
              Umgezogen? Ja! ... Fertig? Nein!
              Baustelle 2.0 !

              Kommentar


                #8
                Danke für eure Antworten,

                Hab die Logik jetzt mit den Tabs neu eingerückt und schon geht es.
                Dachte mir schon dass es nur eine kleinigkeit ist, denn es ging ja schon mal.
                Jetzt ist mir auch klar, wie python die if-Anweisungen unterscheidet.
                Hab mich nämlich schon gewundert, dass hier kein "end if" nötig ist.

                Das mit der eval funktion klingt interessant, hab damit auch schon mal gespielt, aber bin auf keinen grünen Zweig gekommen, seitdem mach ich alles mit Logiken, allerdings hab ich 4 Logiken, die ich etwas umständlich finde, wenn man das mit eval machen könnte wär das natürlich toll.
                Es handelt sich um 4 Funksteckdosen, die ich über ein Gateway ansteuere,
                das Gateway empfängt html befehle, und sendet dann Funksignale an die Steckdose.

                Gibt es hierfür evtl. eine eval Lösung ?

                bisher ist es so gelöst:
                item.conf
                Code:
                [funk]     
                [[steckd1]]
                           type = bool
                           [URL="http://redaktion.knx-user-forum.de/lexikon/visu/"]visu[/URL] = yes
                logic.conf
                Code:
                [funk]
                     filename = funk.[URL="http://redaktion.knx-user-forum.de/lexikon/py/"]py[/URL]
                     watch_item = funk.steckd1
                pages.html
                Code:
                {{ basic.flip('EG.Mike.Funk', 'funk.steckd1', 'Ein', 'Aus') }}
                logik.py
                Code:
                #!/usr/bin/env [URL="http://redaktion.knx-user-forum.de/lexikon/python/"]python[/URL] 
                if [URL="http://redaktion.knx-user-forum.de/lexikon/sh/"]sh[/URL].funk.steckd1() == True:     
                [URL="http://redaktion.knx-user-forum.de/lexikon/sh/"] sh[/URL].tools.fetch_url('http://192.168.0.244/command?XC_FNC=SendSC&type=IT&data=A1E')     
                
                if [URL="http://redaktion.knx-user-forum.de/lexikon/sh/"]sh[/URL].funk.steckd1() == False:     
                [URL="http://redaktion.knx-user-forum.de/lexikon/sh/"] sh[/URL].tools.fetch_url('http://192.168.0.244/command?XC_FNC=SendSC&type=IT&data=A16')
                Kann man mit eval zwischen True und False unterscheiden ?

                Kommentar


                  #9
                  item.conf
                  [funk]
                  [[steckd1]]
                  type = bool
                  visu = yes
                  eval_trigger = <dein-bool-switch>
                  eval = sh.tools.fetch_url('http://192.168.0.244/command?XC_FNC=SendSC&type=IT&data=' + hex(2582 + (value * 8)))
                  Alternativ könnte man auch per Bitmaske das 2^3 Bit setzen - ist aber nur eine optische Sache.

                  eval = sh.tools.fetch_url('http://192.168.0.244/command?XC_FNC=SendSC&type=IT&data=' + hex(2582 | (8 if value else 0)))
                  oder wenn es wirklich nur diese zwei Werte sind und ein Bool:

                  eval = sh.tools.fetch_url('http://192.168.0.244/command?XC_FNC=SendSC&type=IT&data=' + ('1AE' if value else '1A6')))
                  oder den ganzen String oder gar das fetch_url in den "if else". Wird nur arg unübersichtlich.

                  Schreib mal ob es funktioniert...

                  Grüße
                  Robert

                  Kommentar


                    #10
                    Hey Danke für den Code, hab alle 3 Varianten getestet,

                    Variante 1 und 2 werden zwar erfolgreich ausgeführt, aber die Steckdose schaltet nicht. Ich kann auch den Code nicht ganz nachvollziehen.

                    Was bedeutet der wert "hex(2582" und "(8 if value else 0)))"
                    Wie ergibt das 1AE und 1A6 ?

                    ansonsten hab ich es mit der 3ten Variante am besten nachvollziehen können.
                    Diese Variante schaltet die Steckdose auch auf anhieb, lediglich eine Klammer zuviel war bei deinem Beispiel.

                    Es ändert sich übrigens pro Steckdose immer der Wert wie folgt
                    A0 = Steckd. 1
                    A1 = Steckd. 2
                    A2 = Steckd. 3 ...
                    E = Ein, 6 = Aus

                    Ich bekomm zwar bei allen 3 Varianten einen Error, weil der html Befehl einen Bestätigungsstring zurücksendet, aber das wird schon nicht stören, oder ?

                    Code:
                    2013-10-22 19:55:18,092 funk.steckd2-eval ERROR    Item 'funk.steckd2': value ({XC_SUC}) does not match type (bool). Via Visu 192.168.0.169:65297 => None -- item.py:_update:211

                    Kommentar


                      #11
                      Hallo Mike,

                      ein eval ist dazu da einem Item einen Wert zuzuweisen und nicht um einfach Code auszuführen.
                      Wenn das eval None oder einen fehlerhaften Wert zurück liefert, wie in diesem Fall. Dann wird das Item nicht mit dem neuen Werte versehen. => Plugins und Visu bekommen von der Änderung nichts mit.

                      Eine Logik ist hier angebrachter.

                      Bis bald

                      Marcus

                      Kommentar


                        #12
                        Bei dem Rückgabewert kann ich grad nicht erkennen, ob das ein String "{bla}" ist oder ein Dict mit "bla".

                        eval = value if (sh.tools.fetch_url('http://192.168.0.244/command?XC_FNC=SendSC&type=IT&data=' + ('1AE' if value else '1A6')) == '{XC_SUC}') else self()
                        Schreib mal ob es funktioniert...

                        Grüße
                        Robert

                        Kommentar


                          #13
                          @Robert,

                          Hab den Code gerade getestet, und er funktioniert einwandfrei und ohne Fehlermeldungen. Vielen Dank dafür.
                          Das ist ab jetzt meine neue Vorlage.
                          Hab noch andere div. Logiken, die nur aus ein-zwei zeilen bestehen, die werde ich mal versuchen mit der eval Funktion zu ersetzen.
                          Falls ich Probleme oder Fragen habe melde ich mich hier wieder :-).

                          Tolle Arbeit, Danke !

                          Code:
                          2013-10-23 18:51:53,190 SmartHome.py DEBUG    192.168.0.169:50640 sent '{"cmd":"item","id":"funk.steckd4","val":1}' -- __init__.py:json_parse:295
                          2013-10-23 18:51:53,195 SmartHome.py DEBUG    Triggering funk.steckd4-eval - by: Visu source: 192.168.0.169:50640 dest: None value: {'dest': None, 'source': '192.168.0.169: -- scheduler.py:trigger:122
                          2013-10-23 18:51:53,547 funk.steckd4-eval DEBUG    funk.steckd4 = True via Visu 192.168.0.169:50640 -- item.py:_update:219
                          
                          2013-10-23 18:51:59,179 SmartHome.py DEBUG    192.168.0.169:50640 sent '{"cmd":"item","id":"funk.steckd4","val":0}' -- __init__.py:json_parse:295
                          2013-10-23 18:51:59,184 SmartHome.py DEBUG    Triggering funk.steckd4-eval - by: Visu source: 192.168.0.169:50640 dest: None value: {'dest': None, 'source': '192.168.0.169: -- scheduler.py:trigger:122
                          2013-10-23 18:51:59,562 funk.steckd4-eval DEBUG    funk.steckd4 = False via Visu 192.168.0.169:50640 -- item.py:_update:219

                          Kommentar


                            #14
                            Hi!

                            Freut mich.

                            Je nach Anzahl der Steckdosen würde ich allerdings über ein entsprechendes Plugin (nicht Logik) nachdenken.

                            plugin.conf wäre dann u.A. die IP-Adresse des Gateways.

                            In der items.conf wäre dann bei dem jeweiligen Item nur noch "mein_plugin_schalter_addr = 1A" notwendig.

                            Auf Dauer ist das übersichtlicher und wartungsfreundlicher (z.B. bei der Änderung der IP-Adresse des Gateways, bei der benötigten URL oder einer Änderung von z.B. "fetch_url"). Das alles änderst du dann ja nur zentral einmal im Plugin (oder seiner .conf).

                            Nur Mut!

                            Grüße
                            Robert

                            Kommentar


                              #15
                              Ja danke für den hinweis, Hab mir schon einige Plugins angesehen, und den aufbau analysiert. Werd mich da bestimmt auch mal daran versuchen (Mich begeistert das ganze hier im Moment sowieso sehr, allerdings fange ich immer mal wieder eine Idee an, scheitere dann meist doch wieder, dann bleibt es liegen, ich versuch mich an der nächsten Idee, die funktioniert nur mal halbwegs, und so weiter, wodurch im moment der WAF schon etwas leidet. Deshalb bin ich im moment immer glücklich wenn ein bereich funktioniert.

                              Die Funksteckdosen sind eigentlich nur eine spielerei, bzw. hab bevor ich in meinem Haus den KNX Bus eingebaut hab viel mit den Funksteckdosen geschalten. Jetzt hab ich im moment nur noch 4 dieser Funksteckdosen im einsatz, aber das Gateway steuert auch meine kompletten IR Geräte im Wohnzimmer, diese lassen sich ähnlich ansteuern, evtl. versuch ich mich doch mal an einem Plugin.

                              Das Gateway nennt sich übrigens Mediola AIO Gateway,
                              ... falls es jemanden interessiert.

                              Kommentar

                              Lädt...
                              X