MQTT-Controller LWT topic

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

MQTT-Controller LWT topic

#1 Post by Micha_he » 25 Oct 2020, 17:59

Hi.

In the actual ESPEasy versions, the default 'DEFAULT_MQTT_LWT_TOPIC' is set to 'none'. If I use the default controller settings, 'send LWT to broker' is enabled but nothing is send. If I change the topic to '%sysname&/status', the LWT is send to my Mosquitto V1.4.10.
In older versions the default is set to this default value. Is the change is intended?

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: MQTT-Controller LWT topic

#2 Post by TD-er » 25 Oct 2020, 20:52

Hmm if it were intentional, then I can't remember the reason for it.
So I don't think it is intentional.

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#3 Post by Micha_he » 26 Oct 2020, 09:54

I'd a quick look at the current source, but found no changes, which explains this behavior.
The only possibility would be that 'if (LWTTopic.length() == 0)' (in the Controler.cpp) is not zero ?!?

Your last change (add a LWT to the topic) seems not work with my Mosquitto V1.4.10 server on OpenHABianPi either. It isn't send the LastWill, if I use /%sysname%/status/LWT' and shut down the ESP. Old '/%sysname%/status' is working, if I set it manually in the controller settings. Is the new topic '/%sysname%/status/LWT' according to the mqtt 5 specification? I couldn't find any information about it...

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: MQTT-Controller LWT topic

#4 Post by TD-er » 26 Oct 2020, 10:03

Not sure if the format of the LWT topic structure is part of the MQTT specification at all.
I would be surprised if it is, as you send flags along with the publish command to indicate it is a LWT message.
So I don't think the topic has anything to do with it.

Your other devices must subscribe to some topic and your application then interprets the messages in that specific topic as being LWT messages.
Not sure if a subscribed client gets a flag signaling whether a message is a LWT message.

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#5 Post by Micha_he » 26 Oct 2020, 10:36

Maybe I misunderstood your second statement, but:

If the ESP is send '%sysname%/status' as LWT-topic, the ESP is shut down, the Mosquitto-server sends '/%sysname%/status Connection Lost'. All ok.
If I set the LWT-topic in the controller to '/%sysname%/status/LWT' and shut it down after It's connected, nothing is sent from the Mosquitto-Server.

I'll do a second check to it in the evening.

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: MQTT-Controller LWT topic

#6 Post by TD-er » 26 Oct 2020, 11:25

Just as a remark on your last comment.
Make sure to double check the leading slash in your topics.
%sysname%/status has no overlap with /%sysname%/status/LWT

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#7 Post by Micha_he » 26 Oct 2020, 11:28

No, all are with leading slash. I've missed one in my comment ;)

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#8 Post by Micha_he » 26 Oct 2020, 18:03

TD-er wrote: 26 Oct 2020, 11:25 Just as a remark on your last comment.
Make sure to double check the leading slash in your topics.
Damn, you're right... :oops:

The test-ESP has the default settings after factory reset and there is no leading slash.

Result: LWT is working, default LWT (.../status/LWT) also works !!!

I'll now reconfigure all my ESP's and my OpenHAB-server unified to the topic without a leading slash!

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: MQTT-Controller LWT topic

#9 Post by TD-er » 26 Oct 2020, 19:12

Glad you fixed it.
And to make you feel not so bad about yourself... Just think why that was one of the first things I thought about :)

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#10 Post by Micha_he » 30 Oct 2020, 15:18

One single question again:

Here you see the retained messages from the broker if I subcribe to '#':

Code: Select all

Okt 30 15:11:25 DIM1GZ/status/LWT Connected
Okt 30 15:11:25 DIM2GZ/status/LWT Connected
Okt 30 15:11:25 SW001/status/LWT Connected
Okt 30 15:11:25 Zisterne/status/LWT Connected
Okt 30 15:11:25 FK001/status/LWT Connected
The last two are wrong ? These are in DeepSleep (1. Zisterne 300s via DeepSleep in Config and 2. FK001 unlimited via DeepSleep,0 command in a rule) but both are listed as connected !?
You said, the DeepSleep disconnect it from the MQTT-Broker.

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: MQTT-Controller LWT topic

#11 Post by TD-er » 30 Oct 2020, 15:34

What the deepsleep does before entering deep sleep:

Code: Select all

void prepareShutdown(ESPEasy_Scheduler::IntendedRebootReason_e reason)
{
#ifdef USES_MQTT
  runPeriodicalMQTT(); // Flush outstanding MQTT messages
#endif // USES_MQTT
  process_serialWriteBuffer();
  flushAndDisconnectAllClients();
  saveUserVarToRTC();
  ESPEASY_FS.end();
  delay(100); // give the node time to flush all before reboot or sleep
  node_time.now();
  Scheduler.markIntendedReboot(reason);
  saveToRTC();
}
And the code for flushing and disconnecting:

Code: Select all

void flushAndDisconnectAllClients() {
  if (anyControllerEnabled()) {
#ifdef USES_MQTT
    bool mqttControllerEnabled = validControllerIndex(firstEnabledMQTT_ControllerIndex());
#endif //USES_MQTT
    unsigned long timer = millis() + 1000;
    while (!timeOutReached(timer)) {
      // call to all controllers (delay queue) to flush all data.
      CPluginCall(CPlugin::Function::CPLUGIN_FLUSH, 0);
#ifdef USES_MQTT      
      if (mqttControllerEnabled && MQTTclient.connected()) {
        MQTTclient.loop();
      }
#endif //USES_MQTT
    }
#ifdef USES_MQTT
    if (mqttControllerEnabled && MQTTclient.connected()) {
      MQTTclient.disconnect();
      updateMQTTclient_connected();
    }
#endif //USES_MQTT
    saveToRTC();
    delay(100); // Flush anything in the network buffers.
  }
  process_serialWriteBuffer();
}
As you can see, there is a delay of some arbitrary duration to allow the ESP to flush its data from all the buffers.
I can imagine not all data may be flushed as data is handled by the IP stack, but at least I do initiate the disconnect from the broker.

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#12 Post by Micha_he » 03 Nov 2020, 13:41

Yes, the disconnection is arrived at the msoquitto-broker. I can saw it in the log.

But the disconnection doesn't clean the retained LWT. This may be intentional or due to MQTT, especially with mosquitto or the pubsubclient. I could not clarify it. There are some discussions in other forums, such the pubsubclient-forum.

I'll test, if it is enough to publish the topic '%sysname%/status/LWT' with the payload 'Connection Lost', before DeepSleep. Then my OpenHAB-server can recognize, that the client is no longer reachable.

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#13 Post by Micha_he » 04 Nov 2020, 10:32

New insights: A 'publish,%sysname%/status/LWT,"Connection Lost"' before sleep, publish the message to the broker, but didn't clean the retained LWT topic. If I check it later with mosquitto_sub, then the retained LWT-topic still exists and contains "Connected", although the client is no longer accessable. :cry:

I would have expected that the disconnect (before the sleep) would also delete the LWT-topic, but it doesn't. And I've found no other way to do this via ESPEasy.
Last edited by Micha_he on 04 Nov 2020, 15:22, edited 1 time in total.

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: MQTT-Controller LWT topic

#14 Post by TD-er » 04 Nov 2020, 11:36

Perhaps it has something to do with the flag marking it a LWT message is missing.
I will also have a look at the current LWT code in the controllers to see if something obvious is missing there.

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#15 Post by Micha_he » 04 Nov 2020, 19:23

From http://docs.oasis-open.org/mqtt/mqtt/v3 ... c442180843

Code: Select all

3.1.2.5 Will Flag

Position: bit 2 of the Connect Flags.

... the Will Message has been deleted by the Server on receipt of a DISCONNECT Packet [MQTT-3.1.2-8]...
So it should work in principle :)

Edit: One question to the 'Will Retain'-option in the controller settings: Is this option only for the connect (LWT message) or for each message sent to this controller ? Am I right: For each ?

Micha_he
Normal user
Posts: 369
Joined: 07 Feb 2018, 19:14
Location: Helmstedt, Germany

Re: MQTT-Controller LWT topic

#16 Post by Micha_he » 06 Nov 2020, 08:30

In the fact, that the correct MQTT-LWT-handling not help at my OpenHAB problem (at a proper disconnect, no message and no LWT is send, so I can't control the OpenHAB-active-item), I've found a solution:

OpenHAB MQTT 2.x multichannel-binding

One active-item is bind at two MQTT-channels (should work with MQTT 1.x binding). In this configuration, firstly the LWT can control the item and additionally a second MQTT-topic (like CON=Connect) can control the same item. This second topic is used, in my rules with 'System#Sleep'.

Here are some examples:

Broker-bridge-thing:

Code: Select all

Bridge mqtt:broker:MQTT2 [
	host="localhost",
	port=1883,
	secure=false
	]
Switch-thing (only the channels for active/inactive-state changes, here the name SW012 is used):

Code: Select all

Thing mqtt:topic:MQTT2:SW012 "MQTT Thing SW012" (mqtt:broker:MQTT2)
{
	Channels:
		Type switch : LWT [ 
			stateTopic="SW012/status/LWT",
			on="Connected",
			off="Connection Lost"
			]
		Type switch : CON [ 
			stateTopic="SW012/status/CON",
			on="Connected",
			off="Disconnected"
			]
}
and the item (with the two binded read-only state channels):

Code: Select all

Switch SW012active "Switch active" { channel="mqtt:topic:MQTT2:SW012:LWT",channel="mqtt:topic:MQTT2:SW012:CON",autoupdate="false" }
Nevertheless it would be great, if we could clear the unusual condition with the (incorrectly) stored LWT-topic after a disconnect.

Post Reply

Who is online

Users browsing this forum: No registered users and 18 guests