MQTT LWT werkt niet zoals verwacht

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • szjoin
  • Registratie: Februari 2011
  • Laatst online: 27-05 16:44
Ik heb een esp-12 draaien met PubSubClient.h library.
Mijn MQTT broker is de welbekende mosquitto (in een docker)

Dit is de connect string op de esp-12:
C:
1
2
3
4
5
6
7
8
9
10
client.connect(
  config_data.device_id,
  config_data.mqtt_user,
  config_data.mqtt_pass,
  config_data.mqtt_lwt_topic,
  config_data.mqtt_lwt_qos,
  config_data.mqtt_lwt_retain, 
  config_data.mqtt_lwt_message, 
  config_data.mqtt_clean
)


Probleem: Als ik de power van de esp-12 haal, wordt er pas een Last Will gepubliceerd nadat ik de power er weer op heb gezet.

Ik verwacht echter dat er een Last Will wordt gepubliceerd door de broker zodra de Keepalive is gepasseerd zonder dat er een mqtt bericht is verzonden.

Begrijp ik nu iets verkeerd of doe ik iets fout?

[ Voor 5% gewijzigd door RobIII op 05-02-2024 16:14 . Reden: Code leesbaar gemaakt ]

Beste antwoord (via szjoin op 07-02-2024 16:57)


  • Merethil
  • Registratie: December 2008
  • Laatst online: 23:26
szjoin schreef op woensdag 7 februari 2024 @ 09:24:
[...]


Dat is inderdaad bij deze bevestigd.

De publisher is een esp. De subscriber is de debug tool op mijn telefoon en in Homeassistant.
Wanneer ik
code:
1
mosquitto_sub -u "guest" -P "guest" -h 192.168.1.20 -t "mijnesp"
doe, en de spanning er opeens afhaal, stop de topic-flow gewoon. Geen LWT.

Voor de liefhebber: Dit is de volledig uitgeklede code waarmee ik e.e.a. kan reproduceren:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

WiFiClient espClient;
PubSubClient client(espClient);

const char* ssid = ""; // ssid here
const char* pass = ""; // wifi password here

void setup() {
  WiFi.mode(WIFI_STA);
  delay(500);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }
  }

  if (!client.connected()) {
    client.setServer("192.168.1.20", 1883);
    client.setKeepAlive(10000);  // 10s
    
    // last will topic: "mijnesp/status", last will message: "offline"
    client.connect("mijnesp", "guest", "guest", "mijnesp/status", 0, 0, "offline", 0);
  }

  client.publish("mijnesp", "Hello World", 0);

  client.loop();
  delay(1000);
}
De beschrijving op de website van de library zegt dat keepAlive seconden verwacht als parameter:
keepAlive uint16_t - the keep alive interval, in seconds
https://pubsubclient.knolleary.net/api

Jij zet hem in je code op 10000 seconden.

Alle reacties


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Laatst online: 22-05 08:46

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

szjoin schreef op maandag 5 februari 2024 @ 16:06:
Begrijp ik nu iets verkeerd of doe ik iets fout?
Nou, in ieder geval: Die vragen die er staan wanneer je een nieuw topic opent staan er niet voor niets:
Mijn vraag
...

Relevante software en hardware die ik gebruik
...

Wat ik al gevonden of geprobeerd heb
...
Waarom haal je die weg?

Ik zou graag zien dat je je topicstart even aanvult met die informatie. En neem meteen even onze Quickstart door als je toch bezig bent ;)

Verder zou het handig zijn als we wisten wat er in al de config_data values zit; we zijn niet helderziend namelijk ;) Heb je iets als dit al eens doorgenomen?

[ Voor 7% gewijzigd door RobIII op 05-02-2024 16:16 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
Hoe groot heb je je MQTT keep alive staan? Laat de power er af langer dan die tijd anders weet de broker niet dat je client weg is.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • szjoin
  • Registratie: Februari 2011
  • Laatst online: 27-05 16:44
@RobIII - bij deze:

Mijn vraag
Hoe kan ik de LWT laten versturen terwijl mijn device offline is?

Relevante software en hardware die ik gebruik
* PubSubClient.h versie 2.8 (versie van nick.oleary@gmail.com)
* docker image: eclipse-mosquitto:latest

Wat ik al gevonden of geprobeerd heb
1. Keepalive op 10 seconden (@farlane - daar is jouw antwoord)
2. Device offline brengen (stekker er uit)
3. meer dan 10 seconden naar de mqtt bus staren - geen LWT

edit:
Het standaard topic is 'mijnesp'
Het LWT topic is 'mijnesp/status'
Ik luister op 'mijnesp/#' maar ook op 'mijnesp/status'


Additioneel:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct settings {
  char wifi_ssid[32];
  char wifi_pass[32];
  char mqtt_serv[32];
  char mqtt_user[32];
  char mqtt_pass[32];
  char device_id[32];
  int mqtt_port;
  int wifi_retry_interval;
  int mqtt_retry_interval;
  int mqtt_keep_alive;
  int mqtt_qos;
  bool mqtt_retain;
  bool mqtt_clean;
  char mqtt_lwt_topic[32];
  char mqtt_lwt_message[32];
  int mqtt_lwt_qos;
  bool mqtt_lwt_retain;
} config_data;


En debug data van de serial console:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
09:50:52.272 -> Current config:
09:50:52.272 -> device_id: >mijnesp<
09:50:52.305 -> wifi_ssid: <verwijderd>
09:50:52.338 -> wifi_pass:  <verwijderd>
09:50:52.372 -> mqtt_serv:  <verwijderd>
09:50:52.406 -> mqtt_user:  <verwijderd>
09:50:52.406 -> mqtt_pass:  <verwijderd>
09:50:52.438 -> mqtt_port: >1883<
09:50:52.472 -> wifi_retry_interval: >1<
09:50:52.472 -> mqtt_retry_interval: >5<
09:50:52.505 -> mqtt_keep_alive: >10<
09:50:52.540 -> mqtt_qos: >0<
09:50:52.540 -> mqtt_retain: >0<
09:50:52.571 -> mqtt_clean: >0<
09:50:52.605 -> mqtt_lwt_topic: >mijnesp/status<
09:50:52.638 -> mqtt_lwt_message: >Offline<
09:50:52.638 -> mqtt_lwt_qos: >0<
09:50:52.671 -> mqtt_lwt_retain: >0<

[ Voor 3% gewijzigd door szjoin op 06-02-2024 10:18 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
Weet je zeker dat de client op een ordentelijk "ongecontroleerde" manier sterft? Als de client netjes de MQTT disconnect doet komt er geen LWT nl. Ik zou ook even iets langer wachten dan de keepalive, zou kunnen dat de lwt pas na 1.5* de keepalive komt ofzo, de spec zou dit moeten kunnen ophelderen.

Een voorbeeld met mosquittto_pub/sub:

Publisher (met CTRL+C afgebroken dus)
code:
1
2
3
 ~ mosquitto_pub -h 192.168.1.2 -t "test-lwt" -m "blaat" --will-payload "lwt" --will-topic "test-lwt" --repeat 10 --repeat-delay 2
^C
 ~


Subscriber:
code:
1
2
3
4
5
6
7
mosquitto_sub -h 192.168.1.2 -t "test-lwt"                                                                                                                             
blaat
blaat
blaat
blaat
blaat
lwt

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • szjoin
  • Registratie: Februari 2011
  • Laatst online: 27-05 16:44
De cliënt draait op een esp. Ik trek gewoon de (usb) stekker er uit. Lijkt me vrij ongecontroleerd. De esp weet niet wat er gebeurt en is gewoon 'weg'.

De keepalive staat nu op 10000ms en ik wacht tot bijna een minuut.

Ik zal de commandline ook eens proberen om de broker van verdenking uit te sluiten...

[ Voor 16% gewijzigd door szjoin op 06-02-2024 20:26 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
Die test die ik heb gedaan is met een mosquitto broker, die werkt wel, het vast en zeker een probleem met (een van de) de clients.

Test je zowel de publisher als subscriber op een ESP32? In dat geval zou je eens mosquitto_sub als de subscriber kunnen gebruiken om te kijken of het registreren van de LWT door de publisher wel goed gaat.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • szjoin
  • Registratie: Februari 2011
  • Laatst online: 27-05 16:44
farlane schreef op dinsdag 6 februari 2024 @ 23:23:
Die test die ik heb gedaan is met een mosquitto broker, die werkt wel, het vast en zeker een probleem met (een van de) de clients.

Test je zowel de publisher als subscriber op een ESP32? In dat geval zou je eens mosquitto_sub als de subscriber kunnen gebruiken om te kijken of het registreren van de LWT door de publisher wel goed gaat.
Dat is inderdaad bij deze bevestigd.

De publisher is een esp. De subscriber is de debug tool op mijn telefoon en in Homeassistant.
Wanneer ik
code:
1
mosquitto_sub -u "guest" -P "guest" -h 192.168.1.20 -t "mijnesp"
doe, en de spanning er opeens afhaal, stop de topic-flow gewoon. Geen LWT.

Voor de liefhebber: Dit is de volledig uitgeklede code waarmee ik e.e.a. kan reproduceren:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

WiFiClient espClient;
PubSubClient client(espClient);

const char* ssid = ""; // ssid here
const char* pass = ""; // wifi password here

void setup() {
  WiFi.mode(WIFI_STA);
  delay(500);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }
  }

  if (!client.connected()) {
    client.setServer("192.168.1.20", 1883);
    client.setKeepAlive(10000);  // 10s
    
    // last will topic: "mijnesp/status", last will message: "offline"
    client.connect("mijnesp", "guest", "guest", "mijnesp/status", 0, 0, "offline", 0);
  }

  client.publish("mijnesp", "Hello World", 0);

  client.loop();
  delay(1000);
}

Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 23:26
szjoin schreef op woensdag 7 februari 2024 @ 09:24:
[...]


Dat is inderdaad bij deze bevestigd.

De publisher is een esp. De subscriber is de debug tool op mijn telefoon en in Homeassistant.
Wanneer ik
code:
1
mosquitto_sub -u "guest" -P "guest" -h 192.168.1.20 -t "mijnesp"
doe, en de spanning er opeens afhaal, stop de topic-flow gewoon. Geen LWT.

Voor de liefhebber: Dit is de volledig uitgeklede code waarmee ik e.e.a. kan reproduceren:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

WiFiClient espClient;
PubSubClient client(espClient);

const char* ssid = ""; // ssid here
const char* pass = ""; // wifi password here

void setup() {
  WiFi.mode(WIFI_STA);
  delay(500);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }
  }

  if (!client.connected()) {
    client.setServer("192.168.1.20", 1883);
    client.setKeepAlive(10000);  // 10s
    
    // last will topic: "mijnesp/status", last will message: "offline"
    client.connect("mijnesp", "guest", "guest", "mijnesp/status", 0, 0, "offline", 0);
  }

  client.publish("mijnesp", "Hello World", 0);

  client.loop();
  delay(1000);
}
De beschrijving op de website van de library zegt dat keepAlive seconden verwacht als parameter:
keepAlive uint16_t - the keep alive interval, in seconds
https://pubsubclient.knolleary.net/api

Jij zet hem in je code op 10000 seconden.

Acties:
  • 0 Henk 'm!

  • szjoin
  • Registratie: Februari 2011
  • Laatst online: 27-05 16:44
Merethil schreef op woensdag 7 februari 2024 @ 09:28:
[...]


De beschrijving op de website van de library zegt dat keepAlive seconden verwacht als parameter:

[...]

https://pubsubclient.knolleary.net/api

Jij zet hem in je code op 10000 seconden.
Daar heb ik idd overheen gelezen. Ik heb de code nu gewijzigd (eerst 10, daarna 1) maar er komt nog steeds geen LWT(?).

Ik doe dus nog steeds iets niet goed.

Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 23:26
szjoin schreef op woensdag 7 februari 2024 @ 09:40:
[...]


Daar heb ik idd overheen gelezen. Ik heb de code nu gewijzigd (eerst 10, daarna 1) maar er komt nog steeds geen LWT(?).

Ik doe dus nog steeds iets niet goed.
Kan je de retain-flag aanzetten? Het zou zomaar kunnen zijn dat je bericht al gelezen/verwijderd wordt voor je hem ziet?

Acties:
  • 0 Henk 'm!

  • szjoin
  • Registratie: Februari 2011
  • Laatst online: 27-05 16:44
Na een goede lunch opnieuw geprobeerd en het werkt gewoon. :?

Ik heb de Keepalive gewijzigd van 10000 seconden naar 10. (dank @Merethil )
Dat leek aanvankelijk niet te werken. Echter als ik de usb stekker eruit trek dan komt de LWT iets na 10 seconden keurig in beeld... :*)

Ik heb intussen nog wel wat code geoptimaliseerd maar niets in het domein van mqtt.

Dank allen voor het aktief meedenken! Ik kan eindelijk weer verder! _/-\o_

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
Mooi zo :) Let er wel op dat er nog steeds situaties zijn waarbij je niet een melding krijgt terwijl de publisher toch offline is:
- De publisher doet een fraaie disconnect
- De publisher connect nooit
- De broker restart
- De client connect nadat de publisher stierf

IMHO als je op een client wilt weten of een publisher nog leeft is het robuuster om zelf een watchdog op een periodieke bericht van de publisher te zetten.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 28-05 16:11
szjoin schreef op woensdag 7 februari 2024 @ 09:24:
[...]


Dat is inderdaad bij deze bevestigd.

De publisher is een esp. De subscriber is de debug tool op mijn telefoon en in Homeassistant.
Wanneer ik
code:
1
mosquitto_sub -u "guest" -P "guest" -h 192.168.1.20 -t "mijnesp"
doe, en de spanning er opeens afhaal, stop de topic-flow gewoon. Geen LWT.

Voor de liefhebber: Dit is de volledig uitgeklede code waarmee ik e.e.a. kan reproduceren:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

WiFiClient espClient;
PubSubClient client(espClient);

const char* ssid = ""; // ssid here
const char* pass = ""; // wifi password here

void setup() {
  WiFi.mode(WIFI_STA);
  delay(500);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
    }
  }

  if (!client.connected()) {
    client.setServer("192.168.1.20", 1883);
    client.setKeepAlive(10000);  // 10s
    
    // last will topic: "mijnesp/status", last will message: "offline"
    client.connect("mijnesp", "guest", "guest", "mijnesp/status", 0, 0, "offline", 0);
  }

  client.publish("mijnesp", "Hello World", 0);

  client.loop();
  delay(1000);
}
Je subscribed hier niet op het mijnesp/status LWT topic BTW....

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • szjoin
  • Registratie: Februari 2011
  • Laatst online: 27-05 16:44
Je hebt gelijk. Typo. Ik gebruikte eigenlijk 'mijnesp/#' als subscription topic.
Pagina: 1