Basis example MQTT in local network

Alles rund um TX(T) und RoboPro, mit ft-Hard- und Software
Computing using original ft hard- and software
Forumsregeln
Bitte beachte die Forumsregeln!
Antworten
vleeuwen
Beiträge: 1583
Registriert: 31 Okt 2010, 22:23
Wohnort: Enschede (NL)
Kontaktdaten:

Basis example MQTT in local network

Beitrag von vleeuwen » 05 Mai 2024, 14:00

Example of a connection with a Mosquitto MQTT-broker (version 2.0.18) in a (local) network.
https://mosquitto.org/
https://cedalo.com/mqtt-academy/

Mosquitto MQTT broker address in this example = 192.168.10.136:1883 (under the condition that the subnetworks, if in use, are well routed)
Not over websocket here!

Note: don't forget to enable the access for external clients in the mosquitto.conf !
See the documentation in this file.
The MQTT-broken could be started as Windows service but starting from a cmd-box give more information in case of problems.

The fischertechnik blocky has not (yet) implemented: message_callback_add

Python mosquitto MQTT client lib: https://pypi.org/project/paho-mqtt/
Note: Version 2 does not support Python 3.5 and 3.6.
If you are programming in directly in Python on the TXT4.0 (for example: remote with Visual Studio code)
On the TXT4.0 (Python 3.5 ?) you will need to use the latest version 1 (1.6.1)
https://pypi.org/project/paho-mqtt/1.6.1/

For testing I am using Node-Red on a Windows 10 system:
[info] Node-RED version: v3.1.9
[info] Node.js version: v21.5.0
[info] Windows_NT 10.0.19045 x64 LE
Blockly test mqtt workflow
Blockly test mqtt workflow
BasisMqttConn.JPG (104.64 KiB) 317 mal betrachtet
Simple Node Red test message flow
Node-Red test mqtt
Node-Red test mqtt
NodeRed_test.JPG (169.5 KiB) 317 mal betrachtet
software enigineer/teacher/advisor
Google translate
http://tescaweb.nl/Carel/?p=713

vleeuwen
Beiträge: 1583
Registriert: 31 Okt 2010, 22:23
Wohnort: Enschede (NL)
Kontaktdaten:

Re: Basis example MQTT in local network

Beitrag von vleeuwen » 05 Mai 2024, 14:32

If you like to use the MQTT broker on the TXT itself, replace the IP-address with 127.0.0.1 or localhost
software enigineer/teacher/advisor
Google translate
http://tescaweb.nl/Carel/?p=713

Benutzeravatar
fishfriend
Beiträge: 1846
Registriert: 26 Nov 2010, 11:45

Re: Basis example MQTT in local network

Beitrag von fishfriend » 05 Mai 2024, 19:17

Hallo...
:-) Funny. We work at the same stuff. We, Axel and me, has a easyer example-programm.
I had the problem, that it dosent work on my TXT 4.0 with Node-Red.
The solution was, not to use 1883 but 2883 on 127.0.0.1 (127.0.0.1:2883). Axels TXT 4.0 works with 1883.
The other problem was, that the Robo Pro Coding Program (on my TXT 4.0) needs a little wait-time after the create (10ms) and after the first sendig of a topic (1ms).
Without, some times no comunicaion will start.
The Problem was also with test.Mosqutto.org:1883 . With the time, no problems with send or read.
I was on the way, to use a own Mosquittoserver in my network.

There is a (german) Node-Red Tutorial at YT. As far as i see, we can use it with the TXT 4.0.
The Dashborad is now easy to use.

But, it ist posibil to use two/three... different IP-Adresses? May be 127.0.0.1 and test.Mosquitto.org, in Node-Red?
So, the Robo Pro Coding send to Mosquitto and the Broker from the Node-Red may be to a other TXT 4.0?
Every time i want cange the IP, the hole IPs from the other Flows were changed.
With best regards
Holger
ft Riesenräder PDF: ftcommunity.de/knowhow/bauanleitungen
TX-Light: Arduino und ftduino mit RoboPro

vleeuwen
Beiträge: 1583
Registriert: 31 Okt 2010, 22:23
Wohnort: Enschede (NL)
Kontaktdaten:

Re: Basis example MQTT in local network

Beitrag von vleeuwen » 05 Mai 2024, 23:49

Mosquitto broker is the same as what you call Mosquitto server.
Mosquitto broker is the name they are using everywhere.

I tested it with a mosquitto broker (last version) on my laptop and also with the mqtt broker on the TXT4.0

To define and change the broker is easy in NodeRed
NodeRedBrokers.JPG
NodeRedBrokers.JPG (33.62 KiB) 250 mal betrachtet
It is also possible to change the IP- address in such a defined broker
1 select the broker, 2 edit this broker
NodeRedBrokersEdit.JPG
NodeRedBrokersEdit.JPG (34.17 KiB) 250 mal betrachtet
Look for the mosquitto.conf file,
The solution was, not to use 1883 but 2883 on 127.0.0.1 (127.0.0.1:2883)
127.0.0.1 is the same as localhost!
WIth the TXT40 and a remote command (Putty) you can try to stop the running mqtt broker and start it manually with the log activated.
Time stamps + logging to a file activated in the conf file.
However a external MQTT broker will be faster because the TXT(40) needs also time to it main activities.


mqtt is a rather slow asynchronous protocol, not suitable for (semi) real-time closed control loops!

Also I am using the NodeRed one my Laptop, also the latest version.
software enigineer/teacher/advisor
Google translate
http://tescaweb.nl/Carel/?p=713

Benutzeravatar
fishfriend
Beiträge: 1846
Registriert: 26 Nov 2010, 11:45

Re: Basis example MQTT in local network

Beitrag von fishfriend » 08 Mai 2024, 15:40

Hallo...
OK, danke schon mal dafür.

Ich hab da noch etwas.
Ich bin mir nicht sicher und ich vermute mal das es so nicht ist.
Wenn man auf einen TXT 4.0 mit zwei Rechnerm zugreift, muss man dann, wenn man einen Portzugrif z.B. auf 1883 gemacht hat, den "irgendwie" wieder schließen?
Vom Gefühl her, würde ich sagen, das nicht das -Gerät- "gespeichert" wird, was den Zugriff macht.
Es geht mir nur darum, Fehlerquellen auszuschließen, warum es mal klappt und mal nicht.
Mit freundlichen Grüßen
Holger
ft Riesenräder PDF: ftcommunity.de/knowhow/bauanleitungen
TX-Light: Arduino und ftduino mit RoboPro

vleeuwen
Beiträge: 1583
Registriert: 31 Okt 2010, 22:23
Wohnort: Enschede (NL)
Kontaktdaten:

Re: Basis example MQTT in local network

Beitrag von vleeuwen » 08 Mai 2024, 16:57

Your question is not completely clear to me.
In the first place:
Please read the MQTT client (Python) documentation carefully: https://eclipse.dev/paho/files/paho.mqt ... lient.html

One or more MQTT clients can establish a connection to an MQTT broker.
This can be done from different IP addresses or from the same IP address, or a combination of both.
So it is not the device/computer that connects, but every application of which an MQTT client is part, connects to the MQTT broker.

Note: All IP addresses must be correctly routed in the (local) subnetwork.

Each of these connected MQTT clients can "subscribe" and/or "publish" to the MQTT broker.

Of course, every MQTT client must correctly execute "message_callback_remove", "unsubscribe" and "disconnect" at the end.
Otherwise, "keep alive" and "will" will cause an error message.

Note: So also work out a good exception operation (try: except: finally:) in the program code.

Note: Remember that the on_message callback amounts to event driven programming and therefore communication between threads.

Here is the basics of an MQTT client with all call-backs.
There are two ways to link the call-backs to the client, via an assignment or via @decorations
========================================================================
Deine Frage ist mir nicht ganz klar.
An erster Stelle:
Bitte lesen Sie die Dokumentation zum MQTT-Client (Python) sorgfältig durch: https://eclipse.dev/paho/files/paho.mqt ... lient.html

Ein oder mehrere MQTT-Clients können eine Verbindung zu einem MQTT-Broker aufbauen.

Dies kann von verschiedenen IP-Adressen oder von derselben IP-Adresse oder einer Kombination aus beidem erfolgen.
Es ist also nicht das Gerät/der Computer, der die Verbindung herstellt, sondern jede Anwendung, zu der ein MQTT-Client gehört, verbindet sich mit dem MQTT-Broker.

Hinweis: Alle IP-Adressen müssen im (lokalen) Subnetz korrekt geroutet sein.

Jeder dieser verbundenen MQTT-Clients kann den MQTT-Broker "subscribe" und/oder "publish".

Natürlich muss jeder MQTT-Client am Ende „message_callback_remove“, „unsubscribe“ und „disconnect“ korrekt ausführen.
Andernfalls führen „keep alive“ und „will“ zu einer Fehlermeldung.

Hinweis: Erarbeiten Sie also auch eine gute Ausnahmeoperation (try: except: finally:) im Programmcode.

Hinweis: Denken Sie daran, dass der on_message-Rückruf einer ereignisgesteuerten Programmierung und damit der Kommunikation zwischen Threads gleichkommt.

Hier sind die Grundlagen eines MQTT-Clients mit allen Rückrufen.
Es gibt zwei Möglichkeiten, die Rückrufe mit dem Kunden zu verknüpfen: über eine Zuweisung oder über @decorations


Code: Alles auswählen

class MyMQTTClass(mqtt.Client):

    def on_subscribe(self, client: mqtt.Client, userdata, mid, reason_code_list, properties):
        logger.debug(msg="MQTT_02_test: on_subscribe")  # + " userdata:" + str(userdata))
        if reason_code_list[0].is_failure:
            logger.debug(f"MQTT_02_test: on_subscribe: Broker rejected you subscription: {reason_code_list[0]}  {mid}  {str(properties)}")
        else:
            logger.debug(f"MQTT_02_test: on_subscribe: Broker granted the following QoS: {reason_code_list[0].value}  {mid}  {str(properties)}")

    def on_unsubscribe(self, client, userdata, mid, reason_code_list, properties):
        logger.debug(msg="MQTT_02_test: on_unsubscribe" + " userdata:" + str(userdata))
        # Be careful, the reason_code_list is only present in MQTTv5.
        # In MQTTv3 it will always be empty
        if len(reason_code_list) == 0 or not reason_code_list[0].is_failure:
            logger.debug("MQTT_02_test: unsubscribe succeeded (if SUBACK is received in MQTTv3 it success)")
        else:
            logger.debug(f"MQTT_02_test: Broker replied with failure: {reason_code_list[0]}")
        client.disconnect()

    def on_message(self, client, userdata, message):
        logger.debug(msg="MQTT_02_test: On message" + " message:" + str(message.payload) + " on topic '" + str(message.topic) + " userdata:" + str(userdata))


    def on_connect(self, client, userdata, flags, reason_code, properties):
        logger.debug(msg="MQTT_02_test:  On connect" + " userdata:" + str(userdata))
        if reason_code.is_failure:
            print(f"Failed to connect: {reason_code}. loop_forever() will retry connection")
            logger.error(
                msg=f"MQTT_02_test: Failed to connect: {reason_code}. loop_forever() will retry connection")
        else:
            logger.debug(msg="MQTT_02_test: On connect Ok")
            # we should always subscribe from on_connect callback to be sure
            # our subscribed is persisted across reconnections.
            # client.subscribe("$SYS/#")

    def on_connect_fail(self, client, userdata, disconnect_flags, reason_code, properties):
        logger.debug(msg="MQTT_02_test:  on_connect_fail" + " flag:" +
                     str(disconnect_flags) + " userdata:" + str(userdata))
        if reason_code.is_failure:
            print(f"Failed to connect: {reason_code}. loop_forever() will retry connection")
            logger.error(
                msg=f"MQTT_02_test: on_connect_fail: {reason_code}. loop_forever() will retry connection")
        else:
            logger.debug(msg="MQTT_02_test: on_connect_fail Ok")

    def on_pre_connect(self, client, userdata):
        logger.debug(msg="MQTT_02_test:  on_pre_connect" + " userdata:" + str(userdata))

    def on_disconnect(self, client, userdata, disconnect_flags, reason_code, properties):
        logger.debug(msg="MQTT_02_test: on_disconnect" + " userdata:" + str(userdata))

    def on_publish(self, client, userdata, mid, reason_code, properties):
        logger.debug(msg="MQTT_02_test: on_publish mid=" + str(mid) + " userdata:" + str(userdata))

    def on_socket_close(self, client, userdata, socket):
        logger.debug(msg="MQTT_02_test: on_socket_close," + " userdata:" + str(userdata))  # + str(socket.socket['fd'])

    def on_socket_register_write(self, client, userdata, socket):
        # logger.debug(msg="MQTT_02_test: on_socket_register_write," + " userdata:" + str(userdata))
        return

    def on_socket_unregister_write(self, client, userdata, socket):
        # logger.debug(msg="MQTT_02_test: on_socket_unregister_write," + " userdata:" + str(userdata))
        return

    #  There exist a second way in Python to connect to a callback, with decorations.
    # def on_log(self, client, userdata, level, buf):
    #     self.logger.debug(msg="MQTT_02_test: on_log" + " userdata:" + str(userdata))

    # def on_socket_open(self, userdata, socket, dummy):
    #     self.logger.debug(msg="MQTT_02_test: on_socket_open= " + str(socket) + " userdata:" + str(userdata))


'''
        https://eclipse.dev/paho/files/paho.mqtt.python/html/client.html#paho.mqtt.client.Client.on_log
        `on_connect`, 
        def on_connect_fail(client, userdata),
'''


def run(client_id: str ='me', ip_addr: str = "localhost" ):
    broker = ip_addr
    port = 1883
    userDATA = {"info": 10}   # for example
    client: MyMQTTClass = MyMQTTClass(client_id=client_id, userdata=userDATA, callback_api_version= CallbackAPIVersion.VERSION2)
    # client.enable_logger(logger=logger)
    client.will_set(topic='/test/will', payload='I,am dying', qos=0, retain=False, properties=None)
    client.username_pw_set("MyApp", None)
    client.disable_logger()
    client.connect_async(host=broker, port=port, keepalive=30)
    # two examples of the use of  decorators 
   
    @client.log_callback()
    def on_log(client, userdata, level, buf):
        logger.debug(msg="MQTT_02_test: on_log" + " l:[" + str(level) + "] b: " + str(buf))  # + "  userdata:" + str(userdata))

    @client.socket_open_callback()
    def on_socket_open(client, userdata, socket):
        logger.debug(msg="MQTT_02_test: on_socket_open,  userdata:" + str(userdata))

    return client
software enigineer/teacher/advisor
Google translate
http://tescaweb.nl/Carel/?p=713

Antworten