Ankündigung

Einklappen
Keine Ankündigung bisher.

Fehler in Userfunctions

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

    Fehler in Userfunctions

    Irgendwie funktionieren, die Userfunctions bei mir nicht.

    Hier der Beispielcode:

    Code:
    #!/usr/bin/env python
    # knx_blink.py
    
    import logging
    _logger = logging.getLogger(__name__)
    
    _VERSION     = '0.0.1'
    _DESCRIPTION = 'Lässt Item blinken'
    
    def knx_blink(knx_address, knx_dpt = 1, count = 7, pulse = 3, pause = 3, value_on = 1, value_off = 0, value_final = 0, startdelay = 0):
        time.sleep(startdelay / 10.0)
        while count > 0:
            count = count - 1
            logger.warning("Blinken: GA {0} => {1}".format(knx_address, int(value_on)))
            sh.knx.groupwrite(knx_address, value_on, knx_dpt)
            time.sleep(pulse / 10.0)
            logger.warning("Blinken: GA {0} => {1}".format(knx_address, int(value_off)))
            sh.knx.groupwrite(knx_address, value_off, knx_dpt)
            time.sleep(pause / 10.0)
            if value_off != value_final:
                sh.knx.groupwrite(knx_address, value_final, knx_dpt)
                logger.warning("Blinken final: GA {0} => {1}".format(knx_address, int(value_final)))
        return True
    So sieht es im Item aus:

    Code:
    sperren:
        type: bool
        knx_dpt: 1
        visu_acl: rw
        cache: yes
        knx_send: 0/4/7
        knx_reply: 0/4/7
        quittieren:
            type: bool
            eval_trigger: ..self
            eval: uf.knx_blink('0/2/7') if sh...self() else None
    DIesen Fehler bekomme ich:

    Item EG.Essen.Licht.Decke.sperren.quittieren: problem evaluating 'uf.knx_blink('0/2/7') if sh.EG.Essen.Licht.Decke.sperren() else None': 'module' object is not callable

    Für mein Verständnis findet der die Funktion nicht. Die UserFunktion ist aber über das Admin-Interface zu finden.

    #2
    Du musst die im eval die userfunctions und die darin definierte Funktion aufrufen, also
    eval: uf.knx_blink.knx_blink('0/2/7')

    Probier mal

    Kommentar


      #3
      Zitat von Sisamiwe Beitrag anzeigen
      Du musst die im eval die userfunctions und die darin definierte Funktion aufrufen, also
      eval: uf.knx_blink.knx_blink('0/2/7')
      Steht so nicht in der Doku und geht auch so nicht: "problem evaluating 'uf.knx_blink.knx_blink('0/2/7')"

      Kommentar


        #4
        Doch steht so in der Doku!!!

        Der Hinweis von Sisamiwe ist richtig: Du musst uf.<Dteiname>.<funktion> aufrufen.

        wird denn im Log angezeigt, dass die Userfunctions erfolgreich geladen wurden?

        Im Zweifelsfall wurde Die Python gar nicht geladen, weil sie einen (oder mehrere) Fehler enthält.
        Mir fällt z.B. auf, dass Du time.sleep() nutzt ohne das time Package importiert zu haben.

        PS: Eine Tüte Freundlichkeit könnte nicht schaden.
        Viele Grüße
        Martin

        There is no cloud. It's only someone else's computer.

        Kommentar


          #5
          Mir fällt noch auf, dass Du logging als _logger importiert, aber dann logger (also ohne führenden Unterstrich) nutzt.
          Vielleicht kommt deshalb im log nichts an.

          Kommentar


            #6
            Zitat von Msinn Beitrag anzeigen
            Doch steht so in der Doku!!!

            Der Hinweis von Sisamiwe ist richtig: Du musst uf.<Dteiname>.<funktion> aufrufen.
            Offensichtlich bin ich blind.

            Code:
            test_item:
                type: num
                eval_trigger: env.location.sun_position.elevation.degrees
                eval: uf.lamellen_oeffnung_ost( sh.env.location.sun_position.elevation.degrees() )
            /usr/local/smarthome/functions/beschattung.py:

            Code:
            _VERSION     = '0.1.0'
            _DESCRIPTION = 'Hilfsfunktionen zur Beschattungssteuerung per Stateengine'
            
            def lamellen_oeffnung_ost(elevation):
                """
                Bestimmung der Stellung der Ost Lamellen im Wohnbereich
            
                :param elevation: Sonnen Position (Höhe in Grad)
                :return: Schließung der Lamellen in Prozent
                """
            
                return 87 if elevation <= 6.6 else 84 if elevation <= 11.5 else 81 if elevation <= 14.8 else 78 if elevation <= 19.4 else 74 if elevation <= 16.1 else 70 if elevation <= 28 else 65 if elevation <= 30.9 else 60 if elevation <= 33.9 else 54
            Für mein empfinden steht das in der Doku nicht so.

            Zitat von Msinn Beitrag anzeigen
            wird denn im Log angezeigt, dass die Userfunctions erfolgreich geladen wurden?

            Im Zweifelsfall wurde Die Python gar nicht geladen, weil sie einen (oder mehrere) Fehler enthält.
            Mir fällt z.B. auf, dass Du time.sleep() nutzt ohne das time Package importiert zu haben.
            Ja die Usefunctions werden ohne Fehler geladen. Danke für den Hinweis mit time.sleep() . .. habe ich zugefügt.

            Zitat von Sisamiwe Beitrag anzeigen
            Mir fällt noch auf, dass Du logging als _logger importiert, aber dann logger (also ohne führenden Unterstrich) nutzt.
            Vielleicht kommt deshalb im log nichts an.
            Auch hier danke für den Hinweis. Ist repariert und ein logger war auch noch nicht definiert.

            Das habe ich jetzt alles repariert. Aber immer noch ein Fehler:

            WARNING lib.item.item Item EG.Essen.Licht.Decke.sperren.quittieren: problem evaluating 'uf.knx_blink.knx_blink('0/2/7') if sh.EG.Essen.Licht.Decke.sperren() else None': name 'sh' is not defined

            Warum nun sh nicht definiert ist, weiß ich auch nicht.

            Kommentar


              #7
              Gugst Du hier: https://www.smarthomeng.de/user/refe...20userfunction

              unter Aufruf einer Userfunction

              So, das ist mir zu blöd. Ich bin hier raus
              Viele Grüße
              Martin

              There is no cloud. It's only someone else's computer.

              Kommentar


                #8
                Zitat von Msinn Beitrag anzeigen
                unter Aufruf einer Userfunction
                Verstehe. Dann wäre es schön, wenn jemand die Doku fixen könnte, damit das nicht für Verwirrung sorgt. Denn im Beispiel unter Übergabe als Parameter ist dann ein Fehler. Das müsste dann ersetzt werden:

                alt: uf.lamellen_oeffnung_ost
                neu: uf.beschattung.lamellen_oeffnung_ost

                Wenn man das nie genutzt hat, weiß man ja auch nicht, was richtig ist und was falsch.

                Kommentar


                  #9
                  Ja, das ist in der Doku falsch.
                  Mach doch einen PR.
                  Zuletzt geändert von henfri; 26.02.2022, 10:26.

                  Kommentar


                    #10
                    Cannon

                    so gehts:
                    Code:
                    #!/usr/bin/env python
                    # knx_tools.py
                    
                    from lib.item import Items
                    import logging
                    import time
                    
                    _logger = logging.getLogger(__name__)
                    
                    _VERSION     = '0.0.1'
                    _DESCRIPTION = 'Tools für KNX'
                    
                    def blink(sh, knx_address, knx_dpt=1, count=7, pulse=3, pause=3, value_on=1, value_off=0, value_final=0, startdelay=0):
                        time.sleep(startdelay / 10.0)
                        while count > 0:
                            count = count - 1
                            _logger.warning(f"Blinken: GA {knx_address} => {int(value_on)}")
                            sh.knx.groupwrite(knx_address, value_on, knx_dpt)
                            time.sleep(pulse / 10)
                            _logger.warning(f"Blinken: GA {knx_address} => {int(value_off)}")
                            sh.knx.groupwrite(knx_address, value_off, knx_dpt)
                            time.sleep(pause / 10)
                            if value_off != value_final:
                                sh.knx.groupwrite(knx_address, value_final, knx_dpt)
                                _logger.warning(f"Blinken final: GA {knx_address} => {int(value_final)}")
                        return True
                    mit dem Aufruf:
                    Code:
                    uf.knx_tools.blink(sh, '1/1/92')
                    Probier mal.

                    Kommentar


                      #11
                      Zitat von Sisamiwe Cannon Beitrag anzeigen
                      so gehts:
                      Ja geht. Danke!! Allerdings hast du so viel geändert, dass ich das Problem nicht ganz einkreisen kann. Ich vermute, dass das Hauptproblem ist, dass "sh" nicht in den Userfunctions existiert, korrekt?

                      Da ich vorher mit on_update gearbeitet habe (und ich davon ein großer Fan bin), musste ich nun noch enforce_updates auf yes setzen, damit das eval auch getriggert wird, wenn sich der Wert nicht ändert. Ganz optimal ist allerdings nicht, dass die Funktion bei einem Neustart aufgerufen wird. Denn dann wird an so ziemlich allen Tastsensoren diese Funktion ausgeführt. Irgendeine Idee, wie ich das unterbinden kann?

                      Kommentar


                        #12
                        Zitat von Cannon Beitrag anzeigen
                        Ich vermute, dass das Hauptproblem ist, dass "sh" nicht in den Userfunctions existiert, korrekt?
                        Ja, du musst das mit übergeben. Steht aber auch so in der Doku.

                        Desweitern solltest Du das object des KNX Plugin abfragen. Wenn zufällig ein Item mit knx... beginnt, klappt das mit dem Zugriff auf die Funktion des knx Plugins nicht.
                        Ich habe mal etwas weiterentwickelt, u.a. ein Version, bei der man ein Zielitem angeben kann.

                        Code:
                        #!/usr/bin/env python
                        # knx_tools.py
                        
                        from lib.item import Items
                        import logging
                        import time
                        
                        _logger = logging.getLogger(__name__)
                        
                        _VERSION     = '0.0.2'
                        _DESCRIPTION = 'Tools für KNX'
                        
                        def blink_ga(sh, knx_address, knx_dpt=1, count=5, pulse=3, pause=3, value_on=1, value_off=0, value_final=None, startdelay=0):
                            knx = sh.plugins.return_plugin('knx')
                            value = value_on
                            time.sleep(startdelay / 10)
                            for i in range(count*2):
                                _logger.info(f"blink_ga: GA {knx_address} => {int(value)}")
                                knx.groupwrite(knx_address, int(value), knx_dpt)
                                delay = pulse / 10 if value else pause / 10
                                time.sleep(delay)
                                value = value_off
                            if value_final:
                                knx.groupwrite(knx_address, value_final, knx_dpt)
                                _logger.info(f"blink_ga final: GA {knx_address} => {int(value_final)}")
                            return True
                            
                        def blink_item(item, count=5, pulse=3, pause=3, value_final=None, startdelay=0):
                            _logger.info(f"blink_item: blink_item={item} with value={item()}")
                            value = not(item())
                            time.sleep(startdelay / 10)
                            for i in range(count*2):
                                _logger.info(f"blink_item: Item {item.id()} => {int(value)}")
                                item(value)
                                delay = pulse / 10 if value else pause / 10
                                time.sleep(delay)
                                value = not(value)
                            if value_final:
                                _logger.info(f"blink_item: Item {item.id()} => {int(value_final)}")
                                item(value_final)
                            return True

                        Kommentar


                          #13
                          Zitat von Sisamiwe Beitrag anzeigen
                          Ich habe mal etwas weiterentwickelt, u.a. ein Version, bei der man ein Zielitem angeben kann.
                          Das wäre mein zweiter Schritt gewesen. Dann hieße das aber nicht mehr KNX-Tools, weil man damit auch ohne KNX auskommt.

                          Ich habe das Ganze noch mal angepasst:

                          blink.py:

                          Code:
                          #!/usr/bin/env python
                          # blink.py
                          
                          from lib.item import Items
                          import logging
                          import time
                          
                          _logger = logging.getLogger(__name__)
                          
                          _VERSION     = '0.0.3'
                          _DESCRIPTION = 'Blinkfunktionen'
                          
                          # blinkt direkt auf eine KNX-Gruppenadresse
                          #
                          # sh: sh-Objekt
                          # knx_adress: KNX-Gruppenadresse
                          # knx_dpt: KNX DPT Typ (optional)
                          # count: Anzahl der Blinkvorgänge (optional)
                          # pulse: Dauer des Einschaltwertes (optional)
                          # pause: Dauer des Ausschaltwertes (optional)
                          # value_on: Wert des Einschaltwertes (optional)
                          # value_off: Wert des Ausschaltwertes (optional)
                          # value_final: Wert, der nach den Blinkvorgängen gesetzt wird (optional)
                          # startdelay: Starverzögerung des Blinkvorganges (optional)
                          def knx(sh, knx_address, knx_dpt=1, count=7, pulse=3, pause=3, value_on=1, value_off=0, value_final=0, startdelay=0):
                              _logger.debug(f"Blinkfunktion startet auf Gruppenadresse: {knx_address}")
                              knx = sh.plugins.return_plugin('knx')
                              time.sleep(startdelay / 10)
                              for i in range(count):
                                  knx.groupwrite(knx_address, value_on, knx_dpt)
                                  time.sleep(pulse / 10)
                                  knx.groupwrite(knx_address, value_off, knx_dpt)
                                  time.sleep(pause / 10)
                              if value_off != value_final: knx.groupwrite(knx_address, value_final, knx_dpt)
                              return True
                          
                          # blinkt direkt auf ein Item
                          #
                          # item: Item, welches blinken soll
                          # count: Anzahl der Blinkvorgänge (optional)
                          # pulse: Dauer des Einschaltwertes (optional)
                          # pause: Dauer des Ausschaltwertes (optional)
                          # value_on: Wert des Einschaltwertes (optional)
                          # value_off: Wert des Ausschaltwertes (optional)
                          # value_final: Wert, der nach den Blinkvorgängen gesetzt wird (optional)
                          # startdelay: Starverzögerung des Blinkvorganges (optional)
                          def item(item, count=7, pulse=3, pause=3, value_on=1, value_off=0, value_final=0, startdelay=0):
                              _logger.debug(f"Blinkfunktion startet auf Item: {item}")
                              knx = sh.plugins.return_plugin('knx')
                              time.sleep(startdelay / 10)
                              for i in range(count):
                                  item(value_on)
                                  time.sleep(pulse / 10)
                                  item(value_off)
                                  time.sleep(pause / 10)
                              if value_off != value_final: item(value_final)
                              return True
                          Aufruf mittels:

                          Code:
                              testitem:
                                  type: bool
                                  enforce_updates: yes
                                  blinkme:
                                      type: bool
                                      eval: uf.blink.knx(sh, '0/2/7')
                                      eval_trigger: ..self
                          Wenn man Testitem beschreibt, wird auf die GA 0/2/7 geblinkt. Die . Funktion, die direkt auf ein Item blinkt, habe ich noch nicht getestet. Kann aber gern jemand machen. :-)

                          value_on und value_off kann man bewusst ändern, denn wenn man beispielsweise Dimmwerte blinken lassen will, geht das damit auch. value_final wird nur geschrieben, wenn sich der Wert von value_off unterscheidet, sonst wäre das meiner Meinung nach nicht nötig.

                          Danke für die Hilfe hier im Forum.
                          Zuletzt geändert von Cannon; 26.02.2022, 13:35.

                          Kommentar

                          Lädt...
                          X