Ankündigung

Einklappen
Keine Ankündigung bisher.

Nutzung des Mqtt Modules aus eigenem Plugin

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

    [Codebeispiel] Nutzung des Mqtt Modules aus eigenem Plugin

    Moin zusammen,
    aus einem eigenen Plugin oder einer Logic würde ich gerne das MQTT Plugin/Module nutzen. Dazu habe ich schon einige Resourcen durchsucht, wie https://www.smarthomeng.de/user/plug...tt/README.html oder https://github.com/smarthomeNG/plugi...an/__init__.py

    Jedoch bekomme ich nur eine Fehlermeldung im Log zu sehen
    Code:
    2019-12-28  22:41:06 INFO     Main         Modules: Loaded module 'http' (class 'Http') v1.6.0: Modul zur Implementierung von Backend-Webinterfaces für Plugins
    2019-12-28  22:41:06 INFO     Main         Loading '/usr/local/smarthome/modules/mqtt/module.yaml' to 'OrderedDict'
    2019-12-28  22:41:06 INFO     Main         module 'mqtt': has no item-struct definitions in metadata
    2019-12-28  22:41:06 INFO     Main         Loading module 'mqtt': args = '{'module_name': "'mqtt'"}'
    2019-12-28  22:41:06 ERROR    Main         Module mqtt exception: module 'modules.mqtt' has no attribute 'Mqtt'
    Traceback (most recent call last):
      File "/usr/local/smarthome/lib/module.py", line 101, in __init__
        self._load_module(module, classname, classpath, args)
      File "/usr/local/smarthome/lib/module.py", line 226, in _load_module
        exec("self.loadedmodule = {0}.{1}.__new__({0}.{1})".format(classpath, classname))
      File "<string>", line 1, in <module>
    AttributeError: module 'modules.mqtt' has no attribute 'Mqtt'
    2019-12-28  22:41:06 INFO     Main         Loaded Modules: ['http']
    und
    Code:
    AttributeError: 'NoneType' object has no attribute 'publish_topic'
    Meine plugin.yaml
    Code:
    MQTT:
        class_name: Mqtt
        class_path: plugins.mqtt
        host: 127.0.0.1
        port: 1883
    Meine module.yaml
    Code:
    %YAML 1.1
    ---
    # etc/module.yaml
    http:
        module_name: http
        starturl: backend
    #    threads: 8
    #    showtraceback: False
    #    showpluginlist: True
    #    port: 8383
    #    user: admin
    #    password: ''
    #    hashed_password: 'xxx'
    #    servicesport: 8384
    #    service_user: serviceuser
    #    service_password: ''
    #    service_hashed_password: 'xxx'
    mqtt:
        module_name: mqtt
    #dummy:
    #    module_name: dummy
    Und schliesslich die Zeilen in meinem Plugin
    Code:
    try:
        self.mod_mqtt = Modules.get_instance().get_module('mqtt')
    except:
        self.mod_mqtt = None
    if self.mod_mqtt == None:
        self.logger.error("Plugin '{}': Cannot load MQTT module".format(self.get_shortname()))
        return False
    ...
    self.mod_mqtt.publish_topic(self, topicOut, mqttValue)
    Meine Versionen:
    - SmartHomeNG Version: 1.6.master
    - SmartHomeNG Plugins Version: 1.6.1.master

    Kann mir jemand einen Tipp geben wie ich MQTT aus einem anderen Plugin nutzen kann?
    Zuletzt geändert von Echo; 29.12.2019, 09:55.

    #2
    Die Nutzung von MQTT aus einem anderen Plugin ist in v1.6 zwar grundsätzlich möglich, aber nicht sehr elegant und nicht öffentliche dokumentiert. Dazu kommt, dass sich mit dem Release von v1.7 die Unterstützung von MQTT deutlich ändern wird. Die Planungen dazu habe ich schon länger, wollte aber warten bis die verwendete MQTT Python Client Library des Eclipse Projektes die Version mit Unterstützung des MQTT Protokolls v5.0 fertig hat. Da ein Release Datum jedoch weiterhin nicht bekannt ist, habe ich mich entschlossen die Umbauten an SmartHomeNG mit der alten Version (die MQTT v3.1.1 unterstützt) umzusetzen und das Upgrade auf v5.0 später durchzuführen.

    Du bist bei Deiner Suche bereits auf den ersten Entwicklungsstand des MQTT Moduls gestoßen, den ich gestern Abend eingecheckt habe . Dieser unterstützt bisher nur die Nutzung von MQTT durch Logiken. Allerdings würde ich von einer Nutzung noch absehen, da sich das API in den nächsten Tagen noch ändert. Da für die bessere Einbindung von MQTT auch Änderungen an Libraries des Core vorgenommen wurden, funktioniert das Modul z.Zt. definitiv nur mit dem Develop Branch.

    Zielsetzung für das Module ist, eine MQTT Implementierung in SmartHomeNG zur Verfügung zu stellen, die einfach von Plugins und Logiken genutzt werden kann. Dadurch wird es einfach möglich ein Plugin zu schreiben, welches MQTT nutzt und selbst nur das darüber liegende Protokoll implementiert, welches als MQTT Payload zur Kommunikation mit Devices genutzt wird. Mir schwebt vor, als Beispiel in SmartHomeNG v1.7 ein solches Plugin mit auszuliefern, welches Shelly Devices unterstützt. Dabei werde ich auch das bestehende MQTT Plugin so reimplementieren, dass es das MQTT Modul nutzt und die bisherige Funktionalität eiter zur Verfügung stellt.

    Ich möchte Dich deshalb noch um etwas Geduld bitten. Bei Interesse halte ich Dich über die Fortschritte gern auf dem laufenden.
    Zuletzt geändert von Msinn; 29.12.2019, 10:31.
    Viele Grüße
    Martin

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

    Kommentar


      #3
      Mache es doch einfach über die Items.
      Ich löse es zum Beispiel so:
      Code:
      Garage:
          Taster:
              type: bool
              mqtt_topic_in: Garage_Taster
              autotimer: 2 = false
              visu_acl: rw
              gpio_out: 33
          zu:
              type: bool
              gpio_in: 37
              mqtt_topic_init: Garage_zu
              mqtt_topic_out: Garage_zu
              Visu_acl: rw
      Heizung:
          Aussentemperatur:
              type: num
              vicare_data: Aussentemperatur
              mqtt_topic_init: Aussentemperatur
          Warmwasser_Soll:
              type: num
              vicare_data: SollwertWarmwasser
              mqtt_topic_init: SollwertWarmwasser
      Ich bastel da grade an einem Plugin für die Viessmann-Heizung über die ViCare-Schnittstelle. Ist ein einfacher Raspberry, welcher in der Garage unter der Decke in einer Abzweigdose hängt und im Normalfall über die GPIO das Garagentor fährt; getriggert über MQTT.
      Zum Testen nehme ich den auch für ViCare:
      In die andere Richtung sammelt der die Heizungsdaten ein und sendet die über MQTT und WLAN ins Haus.

      MQTT unmittelbar in ViCare einzubauen, macht in meinen Augen das Ganze intransparent und entspricht auch meiner Meinung nach nicht dem Grundgedanken von SmarthomeNG, Plugins in Plugins zu verschachteln.

      Kommentar


        #4
        Zitat von tsb2001 Beitrag anzeigen
        MQTT unmittelbar in ViCare einzubauen, macht in meinen Augen das Ganze intransparent und entspricht auch meiner Meinung nach nicht dem Grundgedanken von SmarthomeNG, Plugins in Plugins zu verschachteln.
        Deshalb baue ich das MQTT Module. Damit wird das eigentliche MQTT Protokoll Teil des Core und es gibt 2 bis 3 Methoden um das Daten über das Protokoll zu transferieren.

        Zitat von tsb2001 Beitrag anzeigen
        dem Grundgedanken von SmarthomeNG, Plugins in Plugins zu verschachteln.
        Deshalb habe ich die bestehende Möglichkeit das MQTT Plugin so zu nutzen auch nicht öffentlich dokumentiert, sondern nur in privaten Plugins genutzt.
        Viele Grüße
        Martin

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

        Kommentar


          #5
          Zitat von Msinn Beitrag anzeigen
          Du bist bei Deiner Suche bereits auf den ersten Entwicklungsstand des MQTT Moduls gestoßen, den ich gestern Abend eingecheckt habe . Dieser unterstützt bisher nur die Nutzung von MQTT durch Logiken. Allerdings würde ich von einer Nutzung noch absehen, da sich das API in den nächsten Tagen noch ändert. Da für die bessere Einbindung von MQTT auch Änderungen an Libraries des Core vorgenommen wurden, funktioniert das Modul z.Zt. definitiv nur mit dem Develop Branch.
          lol. Ist ja lustig. Zum testen werde ich dann mal den Aufruf aus einer Logik testen.
          Zitat von Msinn Beitrag anzeigen
          Ich möchte Dich deshalb noch um etwas Geduld bitten. Bei Interesse halte ich Dich über die Fortschritte gern auf dem laufenden.
          Sehr gerne.
          Zitat von tsb2001 Beitrag anzeigen
          Mache es doch einfach über die Items.
          Prinzipiell eine super Idee. Jedoch muss ich die Payload noch modifizieren und kann sie nicht einfach über ein Eval errechnen :-(

          Kommentar


            #6
            Zitat von Echo Beitrag anzeigen
            Zum testen werde ich dann mal den Aufruf aus einer Logik testen.
            Warte bitte noch auf ein commit heute. (Dann verrate ich Dir auch wie das aus einer Logik funktioniert )



            Viele Grüße
            Martin

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

            Kommentar


              #7
              Zitat von Msinn Beitrag anzeigen
              Warte bitte noch auf ein commit heute. (Dann verrate ich Dir auch wie das aus einer Logik funktioniert )
              Geht klar. Dann halt XBox :-)

              Kommentar


                #8
                So...

                ich habe eine neue Version des Moduls eingecheckt. Die Konfigurationsparameter in /etc/module.yaml entsprechen denen, die Du schon vom mqtt Plugin kennen solltest.

                Das mqtt Plugin kann parallel weiter genutzt werden.
                Das Modul funktioniert nur auf dem aktuellen develop Branch, da einige Libs angepasst wurden.

                Bisher werden Logiken unterstützt, wobei auch mehrere Logiken das selbe Topic subscriben können.
                Um MQTT zu unterstützen, stehen in Logiken 3 Funktionen zur Verfügung
                • mqtt.publish_topic(logic.name, topic, payload)
                • mqtt.subscribe_topic(logic.name, topic, None, payload_type, logic.name)
                • mqtt.unsubscribe_topic(logic.name, topic)
                Die Logik, die Callbacks handled, wird mit folgenden Trigger Informationen aufgerufen:
                • trigger['source'] - 'mqtt' - Konstante
                • trigger['by'] - <topic> - Dadurch kann bestimmt werden, wie die payload zu behandeln ist, falls eine Logik die Callbacks mehrer topics erhält
                • trigger['value'] - <payload>, wobei der Datentyp der payload dem entspricht, was in mqtt.subscribe_topic() als payload_type angegeben wurde

                Bei der mqtt.subscribe_topic() Funktion
                • kann als Payload ein Ausdruck folgender SmartHomeNG Typen übergeben werden und wird automatisch in ein MQTT kompatibles Format gewandelt:
                  - 'str'
                  - 'num
                  - 'bool'
                  - 'list'
                  - 'dict'
                  - 'scene'
                Bei der mqtt.subscribe_topic() Funktion
                • kann mit payload_type bestimmt werden, welchen Datentyp das Callback zurück liefern soll:
                  - 'str'
                  - 'bool'
                  - 'list'
                  - 'dict'
                • kann der letzte Parameter der Name einer anderen Logik sein, wenn die Callbacks nicht durch die Logik gehandled werden sollen, die die Subscription ausführt.

                Hier ist eine Beispiel Logik, die sowohl Subscriptions ausführt, als auch die Callbacks handled:

                Code:
                #!/usr/bin/env python3
                # logics/mqtt_demo.py
                
                def logic_publish_topic(logger, mqtt, logic, topic, payload):
                    logger.info("Function '{}()' - called by '{}()' in logic '{}'".format(inspect.stack()[0][3], inspect.stack()[1][3], logic.name))
                    if mqtt.publish_topic(logic.name, topic, payload):
                        logger.info("Function '{}()' - test-topic was published".format(inspect.stack()[0][3], inspect.stack()[1][3]))
                    else:
                        logger.warning("Function '{}()' - test-topic was NOT published".format(inspect.stack()[0][3], inspect.stack()[1][3]))
                
                def logic_subscribe_topic(logger, mqtt, logic, topic, payload_type='str'):
                    logger.info("Function '{}()' - called by '{}()' in logic '{}'".format(inspect.stack()[0][3], inspect.stack()[1][3], logic.name))
                    mqtt.subscribe_topic(logic.name, topic, None, payload_type, logic.name)
                
                
                # logic main-code starts here
                logger.info("Triggered: trigger['source'] = {}, trigger[by] = {}, trigger[value] = {}".format(trigger['source'], trigger['by'], trigger['value']) )
                if mqtt is None:
                    # no MQTT support available
                    logger.warning("MQTT module is not loaded or not yet initialized")
                elif trigger['source'] == 'mqtt':
                    # callback received
                    topic = trigger['by']
                    payload = trigger['value']
                    logger.info("MQTT received topic '{}': payload = '{}' - type(payload) = {})".format(topic, payload, type(payload)))
                else:
                    mydict = {'txt': 'Test payload 2', 'num': 5}
                    # logger, mqtt and logic are handed over to functions, because only this way they are accessable in a logic's function
                    logic_publish_topic(logger, mqtt, logic, 'test_mqtt/topic', 'Test payload')
                    logic_publish_topic(logger, mqtt, logic, 'test_mqtt/topic2', mydict)
                    logic_subscribe_topic(logger, mqtt, logic, 'test_mqtt/sub')
                    logic_subscribe_topic(logger, mqtt, logic, 'test_mqtt/sub2', 'dict')
                Den logger müßte man nicht unbedingt an die Funktionen übergeben, aber dann würden im Log die Einträge aus Funktionen nicht als Modul logics.mqtt_demo,angeben, sondern scheduler.

                Ich hoffe, das lässt erstmal keine Fragen offen.
                Zuletzt geändert von Msinn; 29.12.2019, 19:58.
                Viele Grüße
                Martin

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

                Kommentar


                  #9
                  Noch ein Nachtrag zhur Konfiguration des Loggings für Logiken:

                  Um die INFO Einträge der Logik auch geloggt zu bekommen solltest Du in der /etc/logging.yaml entweder

                  Code:
                  loggers:
                  
                      ...
                  
                      logics:
                          handlers: [shng_details_file]
                          level: WARNING
                  
                      logics.demo_mqtt:
                          level: INFO
                  oder folgendes konfiguriert haben:

                  Code:
                  loggers:
                  
                      ...
                  
                      logics.demo_mqtt:
                          handlers: [shng_details_file]
                          level: INFO
                  Im ersten Fall bekommst Du für alle Logiken Warnungen geloggt und nur für demo_mqtt auch Infos in das shng_details_file.
                  Im zweiten Fall bekommst Du für andere Logiken keine Logausgaben und nur für demo_mqtt auch Infos in das shng_details_file.
                  Viele Grüße
                  Martin

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

                  Kommentar


                    #10
                    Echo So, jetzt bin ich ein Stück weiter.

                    Das MQTT Modul hat noch einige Änderungen erfahren und jetzt werden auch Plugins unterstützt!

                    ACHTUNG: Die Parameter Reihenfolge von mqtt.subscribe_topic() hat sich gegenüber der Beschreibung oben im Thread geändert:

                    Code:
                            mqtt.subscribe_topic(logic.name, topic, logic.name, None, payload_type, bool_values)
                    Als Beispiele für Plugins die das MQTT Modul nutzen, gibt es
                    • mqtt2: Eine Reimplementierung des mqtt Plugins, welche jedoch das mqtt Modul nutzt.
                    • shelly: Ansteuerung von Shelly Plugs über MQTT
                    Das shelly Plugin ist recht klein und übersichtlich. Dort kannst Du nachsehen, wir ein Plugin das mqtt Modul und die Erweiterungsklasse zum SmartPlugin nutzt.

                    In der Doku des develop Branches (Work in Progress) unter https://www.smarthomeng.de/dev/user findest Du dazu bereits unter Konfiguration/Module und unter Logiken/Nutzung von MQTT in Logiken die Doku zur neuen Funktionalität. Die Doku zur Nutzung in Plugins (in der Devleoper Doku) ist noch nicht so weit.
                    Viele Grüße
                    Martin

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

                    Kommentar


                      #11
                      Danke schön.
                      ich bekomme aktuell die Abhängigkeiten des develop nicht zum laufen. Nach langer Zeit (halbe Stunde oder so) bricht ein install der requirements ab :-(
                      Habe gerade die Meldungen nicht zur Hand, aber ich versuche SH auf einem OrangePI mit Armbian zum fliegen zu bekommen.

                      Kommentar


                        #12
                        Zitat von Echo Beitrag anzeigen
                        ich bekomme aktuell die Abhängigkeiten des develop nicht zum laufen.
                        Da hat sich zum Master aber kaum was verändert?
                        Viele Grüße
                        Martin

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

                        Kommentar


                          #13
                          Zitat von Msinn Beitrag anzeigen
                          Da hat sich zum Master aber kaum was verändert?
                          SM startet wenn ich die Ordner umkopiere. Scheint also zu passen. Ich mache mal weiter und berichte.

                          Kommentar


                            #14
                            Ich bin jetzt doch wieder bei einer Logik anstatt ein Plugin zu nutzen.
                            Wie bekomme ich mqtt in die Logic hinein? Muss ich es erst laden?
                            Code:
                            #!/usr/bin/env python3
                            from lib.item import Items
                            items = Items.get_instance()
                            def logic_publish_topic(logger, mqtt, logic, topic, payload):
                                logger.info("Function '{}()' - called by '{}()' in logic '{}'".format(inspect.stack()[0][3], inspect.stack()[1][3], logic.name))
                                if mqtt.publish_topic(logic.name, topic, payload):
                                    logger.info("Function '{}()' - test-topic was published".format(inspect.stack()[0][3], inspect.stack()[1][3]))
                                else:
                                    logger.warning("Function '{}()' - test-topic was NOT published".format(inspect.stack()[0][3], inspect.stack()[1][3]))
                            def logic_subscribe_topic(logger, mqtt, logic, topic, payload_type='str'):
                                logger.info("Function '{}()' - called by '{}()' in logic '{}'".format(inspect.stack()[0][3], inspect.stack()[1][3], logic.name))
                                mqtt.subscribe_topic(logic.name, topic, None, payload_type, logic.name)
                            # try:
                            mqtt = sh.get_module('mqtt')
                            # except:
                            #     mqtt = None
                            # logic main-code starts here
                            logger.info("Triggered: trigger['source'] = {}, trigger[by] = {}, trigger[value] = {}".format(trigger['source'], trigger['by'], trigger['value']) )
                            if mqtt is None:
                                # no MQTT support available
                                logger.error("MQTT module is not loaded or not yet initialized")
                            mqtt ist immer None :-(

                            Kommentar


                              #15
                              Zitat von Echo Beitrag anzeigen
                              Wie bekomme ich mqtt in die Logic hinein? Muss ich es erst laden?

                              Nein, das ist schon da. Hast Du das mqtt Modul in /etc/module.yaml konfiguriert?
                              Viele Grüße
                              Martin

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

                              Kommentar

                              Lädt...
                              X