Ankündigung

Einklappen
Keine Ankündigung bisher.

MQTT API Server und MQTT Clients - LBS19001051 - LBS19001054

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

    MQTT API Server und MQTT Clients - LBS19001051 - LBS19001054

    Die folgenden LBS realisieren eine EDOMI MQTT API. Damit ist es möglich alle EDOMI KOs (iKOs und KNX-GAs) anderen Systemen via MQTT zur Verfügung zu stellen (publish) als auch alle EDOMI KOs zur Steuerung durch andere Systeme via MQTT freizugeben.

    Insgesamt sind es 4 LBS
    1. MQTT Publish Server (LBS19001051): Veröffentlicht EDOMI KOs auf einem MQTT Broker
    2. MQTT Subscribe Server (LBS19001052): Erlaubt Remote Control von EDOMI KOs aus anderen Applikationen via MQTT Broker
    3. MQTT Publish Client (LBS19001053): Veröffentlicht individuelle MQTT Messages (Topics/Payloads/QoS/Retain) auf einem MQTT Broker
    4. MQTT Subscribe Client (LBS19001054): Abboniert individuelle Topics von einem MQTT Broker
    Detaillierte Beschreibung in den Hilfstexten der LBS.

    Viel Spaß damit ...
    Zuletzt geändert von jonofe; 16.05.2017, 21:22.

    #2
    Hi!

    Im Install-Skript fehlt wohl eine Abhängigkeit:

    Code:
    [root@edomi lib_mysqludf_sys]# ./install.sh
    Compiling the MySQL UDF
    gcc -DMYSQL_DYNAMIC_PLUGIN -fPIC -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o /usr/lib64/mysql/plugin/lib_mysqludf_sys.so
    lib_mysqludf_sys.c:40:23: Fehler: my_global.h: Datei oder Verzeichnis nicht gefunden
    lib_mysqludf_sys.c:41:20: Fehler: my_sys.h: Datei oder Verzeichnis nicht gefunden
    lib_mysqludf_sys.c:43:19: Fehler: mysql.h: Datei oder Verzeichnis nicht gefunden
    lib_mysqludf_sys.c:44:21: Fehler: m_ctype.h: Datei oder Verzeichnis nicht gefunden
    lib_mysqludf_sys.c:45:22: Fehler: m_string.h: Datei oder Verzeichnis nicht gefunden
    make: *** [install] Fehler 1
    ERROR: You need libmysqlclient development software installed
    to be able to compile this UDF, on Debian/Ubuntu just run:
    apt-get install libmysqlclient15-dev
    [root@edomi lib_mysqludf_sys]#
    Code:
    yum install mysql-devel
    Code:
    [root@edomi lib_mysqludf_sys]# ./install.sh
    Compiling the MySQL UDF
    gcc -DMYSQL_DYNAMIC_PLUGIN -fPIC -Wall -I/usr/include/mysql -I. -shared lib_mysqludf_sys.c -o /usr/lib64/mysql/plugin/lib_mysqludf_sys.so
    MySQL UDF compiled successfully
    
    Please provide your MySQL root password
    MySQL UDF installed successfully
    [root@edomi lib_mysqludf_sys]#
    Zuletzt geändert von Nanosonde; 16.05.2017, 10:58.

    Kommentar


      #3
      Na toll.. Wollte ich eigentlich heute abend in den produktiv Einsatz mit
      Jean-Luc Picard: "Things are only impossible until they are not."

      Kommentar


        #4
        [QUOTE=Nanosonde;n1094722]Hi!

        Im Install-Skript fehlt wohl eine Abhängigkeit:

        Code:
        yum install mysql-devel
        Danke für das Feedback, werde ich anpassen. Hatte es zwar auf einem Vanilla EDOMI VM Server getestet, aber scheinbar hatte ich da schon mal PHP5.6 drauf installiert und daher war mysql-devel wohl schon drauf.


        Kommentar


          #5
          Zitat von trollmar Beitrag anzeigen
          Na toll.. Wollte ich eigentlich heute abend in den produktiv Einsatz mit
          Die beiden LBS funktionieren ja, die kannst du schon nehmen. Wird nicht viel Aufwand sein die später zu updaten.

          Kommentar


            #6
            Coole Idee ...!

            Kommentar


              #7
              Alle vier LBS sind jetzt hochgeladen ... Los geht's

              Kommentar


                #8
                Hi André,

                mal eine eher generelle Frage zu PHP mit Message Queues bzgl. Timeout.

                Ich habe in Deinen ganzen Bausteinen mit Message Queues gesehen, dass Du eigentlich immer msg_receive(MSG_IPC_NOWAIT) verwendest und dann später für eine kurze Zeit mit usleep() schläfst. Bei meinen ersten LBS Bausteinen habe ich nach einer Lösung gesucht, um das stumpfe Schlafen mit usleep() zu vermeiden, da es eine unnötigte Latenz reinbringt.
                Eine Lösung, die wie select() bei den Sockets funktioniert, kann man mit einem Signal (z.B. SIGUSR1) nachahmen.

                Code:
                // Signal SIGUSR1 is used to notify the EXEC part about new data from the code part which is run
                // in the context of the logic engine.
                // This is used, because msg_receive() does NOT offer a timeout like e.g. select() while waiting for an event.
                // We could use the flag MSG_IPC_NOWAIT for msg_receive(), but then we would have to sleep
                // some milliseconds to give back some CPU time. As the process is inactive now, we cannot
                // react to new events. -> BAD!
                // So we use the signal SIGUSR1 to simulate the wakeup while it is waiting for it with a timeout
                // using pcntl_sigtimedwait().
                
                ###[LBS]###
                function LB_LBSID($id) {
                    $exec_pid = logic_getVar($id, 3);
                
                    msg_send();
                    posix_kill($exec_pid, SIGUSR1);
                }
                ###[/LBS]###
                
                
                
                
                ###[EXEC]###
                function sig_handler($signo)
                {
                    switch ($signo) {
                         case SIGUSR1:
                             break;
                         default:
                     }
                }
                // A handler for SIGUSR1 __MUST__ be installed, because the default is to kill the process instead
                // when using posix_kill() to send the signal SIGUSR1.
                pcntl_signal(SIGUSR1, "sig_handler");
                
                // Remember our process id
                logic_setVar($id, 3,     posix_getpid());
                
                while (getSysInfo(1) >= 1) {
                                    $info = array();
                                    $signo = pcntl_sigtimedwait(array(SIGUSR1), $info, 1);
                
                                    // Check if it was a signal or the timeout
                                    if ($signo > 0) {
                                        // It was a signal, check if there is something in the queue without blocking
                                        if (msg_receive(MSG_IPC_NOWAIT) {          
                                        // ....
                                        }
                                        // Mhmm, nothing was in the queue. Just log this fact.
                                        else
                                        {
                                            logging($id, 'Notification received but no data in msg queue. Strange!');
                                        }
                                   }
                }
                ###[/EXEC]###
                Wenn man insbesondere Tastendrücke verarbeiten muss, kann man mit dieser Lösung eine unnötige Totzeit von zum Beispiel 50ms vermeiden.

                Statt einer Sekunde Timeout wie oben dargestellt, können auch Nanosekunden angegeben werden:
                http://php.net/manual/en/function.pc...gtimedwait.php

                Zuletzt geändert von Nanosonde; 17.05.2017, 09:29.

                Kommentar


                  #9
                  Jetzt fehlt eigentlich nur noch das Testament, damit andere MQTT Teilnehmer automatisch eine Nachricht bekommen, wenn zum Beispiel Edomi heruntergefahren wird und die Verbindung abreißt.

                  Hatte mir das jetzt nicht im Detail angeschaut, aber unterstützt der Mosquittp-PHP Wrapper auch das Festlegen des KeepAlive-Intervalls mit dem dann die PING Requests gesendet werden? Im Zusammenspiel mit dem Testament sehr hilfreich.




                  Kommentar


                    #10
                    Zitat von Nanosonde Beitrag anzeigen
                    Hi André,

                    mal eine eher generelle Frage zu PHP mit Message Queues bzgl. Timeout.

                    Ich habe in Deinen ganzen Bausteinen mit Message Queues gesehen, dass Du eigentlich immer msg_receive(MSG_IPC_NOWAIT) verwendest und dann später für eine kurze Zeit mit usleep() schläfst. Bei meinen ersten LBS Bausteinen habe ich nach einer Lösung gesucht, um das stumpfe Schlafen mit usleep() zu vermeiden, da es eine unnötigte Latenz reinbringt.
                    Nein, ist nicht immer so, nur, dann wenn außerhalb der messages noch andere Dinge in der Endlosschleife passieren muss.
                    Wenn wirklich nur über die MessageQueue getriggert wird, dann kann man auch die Message Queue im Blocking Mode verwenden.
                    Ich glaube hier ist es das $client->loop(), welches sicherstellt, dass ankommende Nachrichten auch verarbeitet werden. Ansonsten funktioniert der onMessage() callback nicht. Zumindest war das meine Intepretation. Der wirkliche Aufwand für den Prozessor ist bislang vernachlässigbar. Einige meiner LBS verwenden genau die blockierende MessageQueue.

                    Kommentar


                      #11
                      Zitat von Nanosonde Beitrag anzeigen
                      Jetzt fehlt eigentlich nur noch das Testament, damit andere MQTT Teilnehmer automatisch eine Nachricht bekommen, wenn zum Beispiel Edomi heruntergefahren wird und die Verbindung abreißt.

                      Hatte mir das jetzt nicht im Detail angeschaut, aber unterstützt der Mosquittp-PHP Wrapper auch das Festlegen des KeepAlive-Intervalls mit dem dann die PING Requests gesendet werden? Im Zusammenspiel mit dem Testament sehr hilfreich.



                      Das schau ich mir mal an. Du hast vielleicht gesehen, dass ich die Struktur der Topics ein wenig geändert habe.

                      ist nun:

                      edomi/set/[knx|internal]/[id|name]
                      edomi/status/[knx|internal]/[id|name]
                      edomi/get/[knx|internal]/[id|name]

                      set für das setzen von KOs in EDOMI
                      status für das senden des Status von EDOMI an den Broker
                      get als aktiven Request des aktuellen Status, d.h. hier wird eine neue Status Message gepublished.

                      Kommentar


                        #12
                        Zitat von Nanosonde Beitrag anzeigen
                        Jetzt fehlt eigentlich nur noch das Testament, damit andere MQTT Teilnehmer automatisch eine Nachricht bekommen, wenn zum Beispiel Edomi heruntergefahren wird und die Verbindung abreißt.

                        Hatte mir das jetzt nicht im Detail angeschaut, aber unterstützt der Mosquittp-PHP Wrapper auch das Festlegen des KeepAlive-Intervalls mit dem dann die PING Requests gesendet werden? Im Zusammenspiel mit dem Testament sehr hilfreich.
                        Mosquitto-PHP unterstützt das. Allerdings wird LW&T nur gesendet, wenn die Verbindung abreisst, d.h. kein korrektes Disconnect gemacht wird.
                        Ich habe es jetzt wie folgt gelöst: Der EDOMI Subscribe Server LBS verwaltet das Topic 'edomi/status'. Bei Connect wird dies auf online gesetzt mit qos 2 und retain=true. Zusätzlich wird Last Will & Testament gesetzt: topic='edomi/status', payload='error', qos=2, retain=true. Genauso wird bei Beenden des LBS (z.B. bei Senden einer 0 auf E1) das Topic 'edomi/status' auf offline gesetzt und zwar auch mit qos=2 und retain=true.

                        Somit bekommt jeder Client der zum Broker connected und dies subscribed sofort eine Info, ob EDOMI im Status online, offline oder error ist.

                        Grundsätzlich habe ich überlegt evtl. noch mal ein Redesign zu machen und nur einen LBS zu haben, der die Verbindung zum Broker hält. Alle anderen sind dann per Message Queue an diese Broker-LBS angebunden. Hätte den Vorteil, dass es nur eine Verbindung zum Broker gibt, die immer aktiv ist. Dann ist auch der o.g. Status sinnvoller. Denn derzeit zeigt er ja nur an, ob der Subscriber Server läuft. Der Publish Server hingegen baut immer für jedes Publish eine Verbindung auf und wieder ab. Mal sehen ...

                        Grundsätzlich sollte es aber jetzt erstmal funktionieren. Wollte aber noch den LW&T testen. Derzeit wird der LW&T noch nicht mal von Broker ausgelöst, wenn ich einfach den Subscribe Server LBS per kill abschieße. Keine Ahnung woran das genau liegt. Versuche es jetzt noch mal mit einer iptables Regel.


                        Kommentar


                          #13
                          Update des Subscribe Servers ist jetzt hochgeladen, damit sollter der Status 'edomi/status' mit den Payloads 'online|offline|error' nun funktionieren.

                          Kommentar


                            #14
                            Hi.
                            Ich hänge noch an den Grundvoraussetzungen.

                            ​​@jonofe
                            Du setzt doch auch node-red ein?
                            Bekomme node-red unter Ubuntu 16.04 lts einfach nicht dazu bei reboot zu starten via SystemD. Klappt das bei dir?
                            ​​​​​​
                            LG

                            ​​
                            Jean-Luc Picard: "Things are only impossible until they are not."

                            Kommentar


                              #15
                              Zitat von trollmar Beitrag anzeigen

                              ​​@jonofe
                              Du setzt doch auch node-red ein?
                              Bekomme node-red unter Ubuntu 16.04 lts einfach nicht dazu bei reboot zu starten via SystemD. Klappt das bei dir?

                              ​​
                              Ehrlich gesagt, habe ich das noch nicht getestet, da ich es bislang nur testweise eingesetzt habe.
                              Kann ich mir aber gleich mal anschauen.

                              Kommentar

                              Lädt...
                              X