Go Down

Topic: MQTT - retrieve topic value and set variable (Read 145 times) previous topic - next topic

denisj

Hi there all,
I have a door on my chicken coop that is open and close at morning and night via MQTT
from broker to the NodeMCU client.

If the door is Up or Down is saved in a variable.
And this variable is sett Up when the NodeMCU is power on. (default)

Everything it's work fine but sometime, I don't know why, the NodeMCU is reset...
...and obviously, if the reset is done when the door is Down,
my Up/Down variable it's in a wrong state cause when power on,
the default of variable is set to Open.

What I want to try is to retrieve the MQTT ratain topic when NodeMCU is power on,
and then set that variable Up/Down to the value of the retained message.

Can anybody help me please to do this ?
I use the PubSubClient.h lib.

Thanks a lot
Denis

pylon

If you set the retain flag you will get the last state send just after you subscribe to the topic.

denisj

Thanks a lot... and sorry for not reply... the mail alert was not default on this topic.

So you tell me that with the command:
client.subscribe(switchCMD);

...I already can receive the retained message of topic ?

I so on the MQTT page that it can use an optional table array of 'topic, qos' pairs
...but I don't know how to use it and I found a lot of sample with only client.subscribe(topic);

Can you help me please to put the value of retained in the switchCMD variable ?

Thanks a lot.
Denis

wildbill

The publisher has to specify the retain flag, not the subscriber.

denisj

The publisher has to specify the retain flag, not the subscriber.
I have the publisher that is the subscriber... at last this is what I think...

Well, I have the chicken coop door that is open/close
by a stepper motor linked at a NodeMCU.

When it receive (like a subscriber) the topic (via WiFi), it control the internal variable.

So if receive "open the door", and the internal variable is "the door is close",
it will open the door and will publish "the door is open", like retained topic.
If the internal variable is already "open" will do nothing.


The problem is... that if the door is close(during the night),
and the NodeMCU will reset, this internal variable is "open" by default.
In the morning the broker send "open the door" and the NodeMCU have already
the internal variable to open status... so will do nothing.


Now... what I try to do is, when NodeMCU is power on,
set the internal variable to the retained message status of broker.

Thanks a lot again
Denis

wildbill

What is publishing the required door status? That's where the retain is needed and then when your subscriber starts up again, it will get the current status sent as soon as it subscribes.

denisj

What is publishing the required door status?
Yes...

That's where the retain is needed and then when your subscriber starts up again, it will get the current status sent as soon as it subscribes.
Yes... it publish a retained message and then it change the internal variable status.
But I don't know how do... when NodeMCU subscribe to broker
to move the retained message into the internal variable.

I have this command in my source:
client.subscribe(topic);
...and if I understand is possible to give another optional parameter in order to receive
the topic at subscribe time.

The problem is that I can'd find samples in order to copy it.

Thanks a lot again
Denis



wildbill

Nope. You're missing the point. You have something that sends a message to the broker saying door open or door closed. What is that thing?

Your nodeMCU is subscribing to the topic that contains the open or close messages. There is nothing the subscriber can do to require that it receives the last message sent. Only the publisher can set that up for you.

If the publisher has done its job, the nodeMCU just needs to subscribe as it does today and the last message will be automagically sent to it.

denisj

Nope. You're missing the point. You have something that sends a message to the broker saying door open or door closed. What is that thing?
Yes... here is the piece of code that run when the door is open or close:
Code: [Select]
client.publish(switchStatus, "1",true); // publish on MQTT the dor UP / client.publish(topic, payload, retained)


Your nodeMCU is subscribing to the topic that contains the open or close messages. There is nothing the subscriber can do to require that it receives the last message sent. Only the publisher can set that up for you.

If the publisher has done its job, the nodeMCU just needs to subscribe as it does today and the last message will be automagically sent to it.
But what I need is that the publisher, in this case the subscriber, always the NodeMCU,
receive the retained message when is power on.

So when the NodeMCU is power on I need:
1. to subscribe to the broker
2. receive the actual status of the door (retained message from broker)
3. set the internal variable at the retained status of the message received.

Thanks a lot again
Denis

wildbill

You have missed out the retain flag from your publish call. The docs you linked to earlier say this:
Code: [Select]

mqtt:publish(topic, payload, qos, retain[, function(client)])

It looks like you left the qos parameter out.

As a matter of interest, why do you have the same device acting as a publisher and subscriber to the same topic?

denisj

I don't know exactly how it's work te missing parameter
but if I take a look to the messages using MQTT.fx software I see all messages with QoS = 0
and the pollaio/switchStatus/ topic have a retained status.

Let's take a scenario...
The actual door satus is "UP" and the NodeMCU is reseting for various reason.
The default of internal variable "doorSwitch" when power on is set to "down"
Here is a log of what is happen when I power on the NodeMCU.
Code: [Select]
connected with DaVinci17Mesh, channel 6
dhcp client start...
ip:192.168.1.152,mask:255.255.255.0,gw:192.168.1.1
.
WiFi connected
IP address: 192.168.1.152
Attempting MQTT connection...
 MQTT Connected
MQTT Callback Topic: pollaio/switchCMD/ <<< here is the first callback routine at the connection
MQTT Callback Payload = 1 (go UP) <<< here arrive the retained message cause the last msg was "1"
MQTT ACTUAL doorSwitch = DOWN <<< the default variable at power on is DOWN
MQTT > door go UP
motorUP INIT...
motorUP FINISH...
motorUP FINISH ACTUAL doorSwitch = UP
WebServer ON...
Sabato, 9:26:58 L O O P  > doorSwitch = UP



The logic is:
- if arrive cmd UP and the internal doorSwitch variable is DOWN, the motor will go UP
- if arrive cmd UP and the internal doorSwitch variable is already UP, the motor will do nothing
- and viceversa for cmd DOWN

I use the internal variable because I have also a push button on the chicken coop
that toggle the open/close door when I'm near the chicken coop.


But... now I have another idea...
I'll insert a new internal variable, for example PowerON
The default of PowerON variable at power on will be "0"
At the callback routine will do:
-if PowerON == "0" > set the doorSwitch == retain msg that arrive, and set the PowerON to "1"
-if PowerON == "1" > do the logic and go and do the motor routine

Is not so nice, but I think will work :-)

In order to thanks here is a pic of chicken coop that I made :-)




Thanks a lot for your help
Denis

denisj

Ok... PowerON variable implemented
All it's work when I reset the NodeMCU

:-)

Thanks all again
Denis

Go Up