stefandreyer / CODESYS-MQTT

MQTT client library for CODESYS, supporting all QoS
MIT License
112 stars 26 forks source link

MQTT birth and will messages #12

Closed MichielVanwelsenaere closed 5 years ago

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

correct me if I'm wrong but it seems that the will topic is currently a hardcoded concatination of 'clientId' + '/MQTTWill/' + 'clientId' + 'Topic', any chance you could change this so we can full configure the topic ourselves? (this breaks the convention for all my other devices..)

Also, if you could support MQTT birth messages that would be great, very handy to know if the PLC is available in combination with MQTT will messages :)

stefandreyer commented 5 years ago

Hi Michiel,

yes, it is hard coded ..... Sure it is possible to change this ....

I'll do this.

Birth messages? What is this? Didn't found that in OASIS standart for version 3 and 5?

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi stefan,

You're right, it's not described in the OASIS standard, didn't know that! I'm assuming that is because a birth message is a normal Mqtt message send from the client side. Where as for LWT you need to set a bit somewhere I thought to indicate that it's a Testament message.

Ok, so a birth message is a message that is send out on a specific topic with a specific payload each time the client is able to reconnect to the broker after experiencing connection issues..

In combination wiht LWT it's very handy to know the state of your device..

This has specifical use when using home assistant for home automation.

Best regards, Michiel

stefandreyer commented 5 years ago

Hi Michiel,

Sounds like a normal publish with trigger on rising Edge of connect status....

I see no need to implement this in the client.

You see this so too?

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

If this can be implemented by checking for a certain high flank that's fine for me, where can I find this 'connect status' to work with?

Best regards, Michiel

stefandreyer commented 5 years ago

Hi Michiel

take a look to your MQTT_INFO:

TYPE MQTT_INFO :
STRUCT
    MQTT_CONNECTED : BOOL;
    MQTT_ERROR : STRING(OSCAT_BASIC.STRING_LENGTH);
END_STRUCT
END_TYPE

BR Stefan

stefandreyer commented 5 years ago

Hi Michiel,

you may use this now:

BuildWillTopicAndMessage: BOOL := TRUE;
WillTopicBase:STRING(255) := 'MQTTWill';
ClientWillTopic:STRING(255) := 'DEAD';
ClientWillMessage:STRING(30) := 'DIED';

set BuildWillTopicAndMessage to false and Topic and message is used as is.

Resists in MQTT_IN_OUT

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

stupid question most likely but the below gives an compile error:

MQTTClient.MQTT_IN_OUT.BuildWillTopicAndMessage := TRUE;
MQTTClient.MQTT_IN_OUT.WillTopicBase := '';
MQTTClient.MQTT_IN_OUT.ClientWillTopic := MQTTLwtTopic;
MQTTClient.MQTT_IN_OUT.ClientWillMessage := MQTTLwtPayload;

Error: _C0037: 'MQTT_INOUT' is no input of ClientWrapper

yet this seems deadsimple syntax.. any idea how to set the LWT correct?

stefandreyer commented 5 years ago

Hi Michiel,

Looks like you are using the ClientWrapper. There MQTT_IN_OUT is a output. The Wrapper is not made for changing Will Topic. So, don't use my the wrapper and build your own.

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

thanks, so I build my own using the code above and the values below:

MQTTLwtTopic            :STRING:='Devices/Wago-PFC200/LWT';
MQTTLwtPayload          :STRING:='offline';

yet that results in a topic: WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT any way I can fully control it?

I'm also noticing that the LWT message suddenly is being triggered every X seconds, which was not the cause with previous version of the library. Mqtt is working fine however as my publishes keep arriving. Any changes in your lib that could have triggered this or should I look further in my code? Note that the Mosquitto broker keeps logging a disconnect and reconnect as well.

Best regards, Michiel

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

doing a quick test with the previous version of your library shows the same issue/behaviour with LWT. Steps to reproduce;

  1. Download you application to the controller
  2. Start the application
  3. Stop the application
  4. Wait untill LWT message is published by broker
  5. Start application again
  6. Every 13 seconds or so a new LWT message is published by the broker

Still checking this further to see if pub/sub works fine during this issue.

stefandreyer commented 5 years ago

Hi Michiel,

there are some triggers who reconnect the client. I Need to make a history of Auto disconnect reasons. Until this, take a look to the DoDisconnect bit in HANDLE_MQTT it Shows you why it could happen.

There is is a CountConnectAtamp counter to, it increases at every connect try. In My example it stays at 1.

BR Stefan

stefandreyer commented 5 years ago

Hi Michiel,

done the history, please try it. You find it in the handler in the ErrorHistory array.

Hope you'll find more Information there.

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

I just gave this a try, and the array switches between 'CONNECTION_REFUSED' and 'CONNECTION_ESTABLISHED':

ERROR_C => 4244635648
ERROR_T => 2

Putting the PLC in 'stop' mode is ofcourse not a natural failure, however plugging out the network cable for a few seconds seems to trigger the same behavior.

PS: any update on how to fully configure the LWT topic + payload?

Best regards, Michiel

stefandreyer commented 5 years ago

Hi Michiel,

ERROR_C is FD000000 and this Comes from OSCAT IP_CONTROL FB and means: Connection closed by remote.

Due some reason your broker is closing your connection. Try to Change the log Level of your mosquitto to debug. You can use Wireshark to find corrupted mqtt packets too.

I had so problems too annoying....

BR Stefan

stefandreyer commented 5 years ago

Hi Michiel,

got some news?

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

I'm hoping to find the time to properly check this further this weekend..

Best regards, Michiel

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

these are the mosquitto broker logs on a debug level:

1554624178: Received PINGREQ from WAGO-PFC200
1554624178: Sending PINGRESP to WAGO-PFC200
1554624180: Received PINGREQ from WAGO-PFC200
1554624180: Sending PINGRESP to WAGO-PFC200
1554624192: Sending PUBLISH to mqttspy (d0, q0, r0, m0, 'WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT', ... (7 bytes))
1554624197: Will message specified (7 bytes) (r1, q2).
1554624197:     WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT
1554624197: Sending CONNACK to WAGO-PFC200 (0, 0)
1554624197: Received SUBSCRIBE from WAGO-PFC200
1554624197:     WAGO-PFC200/In/DigitalOutputs/+ (QoS 2)
1554624197: Sending SUBACK to WAGO-PFC200
1554624205: Received PINGREQ from mqttspy
1554624205: Sending PINGRESP to mqttspy
1554624210: Sending PUBLISH to mqttspy (d0, q0, r0, m0, 'WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT', ... (7 bytes))
1554624210: Will message specified (7 bytes) (r1, q2).
1554624210:     WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT
1554624210: Sending CONNACK to WAGO-PFC200 (0, 0)
1554624210: Received SUBSCRIBE from WAGO-PFC200
1554624210:     WAGO-PFC200/In/DigitalOutputs/+ (QoS 2)
1554624210: Sending SUBACK to WAGO-PFC200
1554624223: Sending PUBLISH to mqttspy (d0, q0, r0, m0, 'WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT', ... (7 bytes))
1554624223: Will message specified (7 bytes) (r1, q2).
1554624223:     WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT
1554624223: Sending CONNACK to WAGO-PFC200 (0, 0)
1554624223: Received SUBSCRIBE from WAGO-PFC200
1554624223:     WAGO-PFC200/In/DigitalOutputs/+ (QoS 2)
1554624223: Sending SUBACK to WAGO-PFC200
1554624236: Sending PUBLISH to mqttspy (d0, q0, r0, m0, 'WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT', ... (7 bytes))
1554624236: Will message specified (7 bytes) (r1, q2).
1554624236:     WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT
1554624236: Sending CONNACK to WAGO-PFC200 (0, 0)
1554624236: Received SUBSCRIBE from WAGO-PFC200
1554624236:     WAGO-PFC200/In/DigitalOutputs/+ (QoS 2)
1554624236: Sending SUBACK to WAGO-PFC200

The above is where I put the PLC in stop mode and suddenly get a situation where the last will message is being published every 13 seconds.

On regular startup the log looks like below:

1554624059: Will message specified (7 bytes) (r1, q2).
1554624059:     WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT
1554624059: Sending CONNACK to WAGO-PFC200 (0, 0)
1554624059: Received PINGREQ from WAGO-PFC200
1554624059: Sending PINGRESP to WAGO-PFC200
1554624059: Received SUBSCRIBE from WAGO-PFC200
1554624059:     WAGO-PFC200/In/DigitalOutputs/+ (QoS 2)
1554624059: Sending SUBACK to WAGO-PFC200
1554624061: Received PINGREQ from WAGO-PFC200
1554624061: Sending PINGRESP to WAGO-PFC200

does this provide you sufficient information of should I use WireShark to capture logs as well?

Best regards, Michiel

stefandreyer commented 5 years ago

Hi Michiel, I don't see the reason for the first disconnect @ 1554624192 there the lwt is published to mqttspy.

After that ther is the connect and connack packet. This is fine.

But I don't see any ping from the wago bevor the next LWT.

Why do you stop your plc and how long?

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

note that before 1554624192 there are no pingreq send anymore from the wago plc, perhaps that triggered the lwt? I put the PLC in stop mode using the CodeSys debugger, for about 20 seconds I guess.

I can trigger the same behaviour normallly by unplugging the network cable, I'll do this and check the logs as well.

Best regards, Michiel

stefandreyer commented 5 years ago

ok, i see,

there is a ping but time is to long.

Please tak e a look to the bit PingRequestet, is this false? if not, no ping packet will be build.

I can't trigger it here…

BR Stefan

stefandreyer commented 5 years ago

Hi,

is your boker up to date?

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

I took the latest mosquitto broker to perform these tests, PingRequestet is set to TRUE when the problem occurs. Is that the problem?

Best regards, Michiel

stefandreyer commented 5 years ago

Hi Michiel,

please test the new version, now I reset PingRequestet on Connection init, this sholud solve the symptom. I Think your program is overwriting some Memory somewhere so the ping crashes.

You may send it to me?

BR Stefan

stefandreyer commented 5 years ago

Hi _Michiel,

i think i got i it. I never teste disconnect without publishing anything.

So it was: 1.line broken

  1. next time for ping
  2. set PingRequestet and build the packet
  3. try to send it through the interface
  4. interface checks that it was disconected
  5. reset Client and neogate new connection, but doesn't reset PingRequestet.
  6. never again a ping was builded so the broker closed the Connection by timout.
  7. back to 2

So the Problem should be solved and you have no Problems with memory…

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan!

Good to hear that, should be able to verify in the comming days.

Best regards, Michiel

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

just tested this and works, no more connection issues after unplugging the cable temporarily, great! :-)

So, two more things:

  1. For LWT I have the following setup:
    
    MQTTLwtTopic            :STRING:='Devices/Wago-PFC200/LWT';
    MQTTLwtPayload          :STRING:='offline';

( Set the LWT topic / payload ) MQTT_IN_OUT.BuildWillTopicAndMessage := TRUE; MQTT_IN_OUT.WillTopicBase := ''; MQTT_IN_OUT.ClientWillTopic := MQTTLwtTopic; MQTT_IN_OUT.ClientWillMessage := MQTTLwtPayload;


which results in the following topic:

> WAGO-PFC200//WAGO-PFC200/Devices/Wago-PFC200/LWT

seems that it's not fully configurable yet, do you think this is possible or is this impossible due to legacy reasons? (just checking, I'll adjust accordingly)

2. I'm using an `R_TRIG` Fb on `MQTTInfo.MQTT_CONNECTED` yet it seems that the `R_TRIG` output doesn't become high after a reconnect (like unplugging and plugging in the cable), are you sure that MQTT_CONNECTED becomes low again after there is a connection issue? It's hard to check for me as I obviously can't check it through the debugger when unplugging the cable.. :-)

Thanks for your work!
Best regards,
Michiel
stefandreyer commented 5 years ago

Hi Michichel,

you need to set

MQTT_IN_OUT.BuildWillTopicAndMessage := TRUE;

to false, then the LWT Topic is taken as is it and not be build.

I initialize with true for my purpus, if it needs someone diffrennt he can set it to false.

I tested the connection bit now, works fine, maby you shutdown your broker to disconect the MQTT client and not the CODESYS for debug.

BR Stefan

MichielVanwelsenaere commented 5 years ago

Hi Stefan,

I was able to get both to work, thanks!

closing this issue.

Best regards, Michiel