Request, mqtt publish then read by the subscribe node

Dear Community,

I have a HW config which consists of a Raspberry 3 (running the node-red and the mosquitto broker), and on the same network, I have an ESP8266, communicating via mqtt. To the ESP, there is a DHT11 temperature sensor attached. Now I faced a problem here. Until now, the ESP node measured the temp & humidity periodically (every 30 sec, let's say), published the value to the mosquitto, and the node-red mqtt subscribe node had put it into a local variable inside node-red. When a request by the user came via telegram, to get the temperature, simply these local variables had been sent back to the telegram.

Since the DH11 is quite slow sensor, during the measurement, it blocks the ESP to response to other (also user initiated) commands, like turning the lamp on or off.

So I tried to achieve that node-red gets the request via telegram that the user wants to have the temp&humidity values. This works. Then, node-red publishes via mqtt that we need a fresh value of them. This works too. Then, ESP is subscribed, so it is triggered to measure, this works, too. The ESP publishes the new values after its measurement, that's also OK. Then, back to the node-red flow, I could get the value via the mqtt subscribe node. The problem appears here: after the measurement is triggered, how to wait for the result before I run the mqtt subscribe node? The mqtt subscribe node and publish node have only input / output connector respectively, so they cannot be connected neither after each other, nor with a script node between them. If I could place a script node between them, maybe with some handshaking logic this could be done.

So is there a solution or best practice to publish an mqtt request, run some code to create the response then show the response for the user?

Thank you!

Zsolt

You don't need to keep subscribing to the topic. Once you have started node red then any time a new value is published the MQTT In node will pick that up and send the value.
So any time the ESP provides a value, however that request is generated, the MQTT In node will pickup the value automatically.

Someone asked a similar question in the forum a few days ago.
Here's my response about using a Rules Set in ESP Easy running using a Wemos D1 Mini.

As Colin said... you don't need to keep subscribing.

@zsolttrenyik
It sounds a bit unnecessary complicated handling in respect to the ESP. I would assume you would wish the ESP to automatically read & publish the data to mqtt, let's say once every 10 second. In this way you would always have "the latest" values available in a variable in Node-RED. So when the user sends his telegram, you just pick those values and put them into your response

I have a similar setup but I'm using the ESP32. Have a look at ESP Home, dead simple to configure and use

Specifically, check the below for DHT sensors. In the configuration you can define the required update interval that defaults to 60 seconds

Thanks for the comment everyone. However, this is exactly what I did so far - refreshed the value periodically. This is problematic, because the measurement is slow, and in worst case, if the user wants to switch the lamp on (by triggering a DI switching a relay) he will see the response of his action about two seconds later. This is not fine. If the request was temperature measurement, and the user knows, that the action takes some time, this is not a problem, but an implicit delay is not OK. This is why I want to trigger the temperature measurement explicitely, and don't run it periodically. If the user requests the data, should get the data, otherwise performing a measurement is unneccessary.

Thank you once again!
Zsolt

I have just realised that this is the crux of the problem. The issue you are having is that reading the sensor is locking up the ESP for two seconds. Are you sure there is not a way of programming the device to minimise that? I have not used those sensors so cannot comment. Perhaps someone else can.

Dear Colin,

yes, that's it. I will replace the temp sensor to a better one, it just takes some time. Then, I will measure periodically, like now, but with a better sensor, the system should be more responsive to the user.

But the question may be still valid: how to force two steps in a sequence in node-red if input / output connectors are missing. Is there a way to go? Could I maybe modify the mqtt nodes just to add e.g. an output where it is missing now? In Labview, in my professional work, I often use this technique, that I synchronize the data flow just by connecting e.g. an error output to e.g. a loop, to ensure that the setting of a GUI control will be performed first, then the loop starts. Actually, I would just need to have an output for the first mqtt node (like a bool, or any single datatype) to be able to connect a function node there, waiting for a valid value. I'm not sure, but it could work probably.

So maybe my question is more generic than just reading the temp value on demand.

Thank you all!

Zsolt

Why not buy a second esp8266 to control the relay? They are cheep enough and it should resolve your delay issue.

Also, what are you measuring that can't use the value that was received sometime in the last 30 seconds? I can't imaine what it might be if you are using a DHT11 to measure it.

I didn't quire get it. Something like you described would be a typical pattern for asynchronous messaging (like MQTT). The ESP could subscribe to a separate topic e.g. esp/temperature/request. When it receives a message on the topic, it will publish the temperature to esp/temperature and the requester (Node-RED) knows it will receive it when it's done.

The requesting and receiving can be separate Node-RED flows without any linkage besides the indirect one through MQTT (decoupled).

Is the issue that you would need to be able to reply the temperature reading to a specific person to Telegram who requested the reading?

I side through with @zenofmud's thinking. Either a faster sensor or an ESP for each purpose. You can cram a many of even slow sensors to a single device if it's not expected to respond to immediate user input for a completely unrelated request.

Can I ask what firmware you are running in the ESP8266 and what version of ESP8266 it is??

Quite a lot of people on this forum use the development board... Wemos D1 Mini devices (ESP8266-EX 12-F based microcontroller) flashed with ESP Easy, Tasmota or ESPHome.

Are you using both the temperature and humidity readings?
If you are only using temperature, then it might be better to use a DS18B20 as they are more accurate.

Note:
DHT11 (that's the blue-cased version)
Temp range is 0-50 deg C +/- 2 deg C
Humidity range is 20 - 80% +/- 5%

If I get some spare time over the next day or so I'll rig-up a test bench with a Wemos D1 fitted with a DHT11 and a relay or maybe some LEDs (as I don't remember having any "speed" issues in the past).

Unverified, but maybe switching to an ESP32 would work better since it is more powerful (non-blocking while reading) but I don't know, I do not have a DHT11 to test with

Sorry, I don't understand what you mean by i/o connectors being missing.
Basically if you want to do two steps in sequence you just trigger one after the other, What is preventing you from doing that?

But a new sensor is a cheaper, simpler and more likely to fix the issue.

1 Like

Thanks a lot everyone who took the time for answering.

What I did so far: ordered new (faster) sensors, as suggested here, and upgraded my flow to provide a better user experience (user should always know what happens). This means that once the user sends the request via telegram to get the temperature, he receives a message immediately that measuring starts. At the same time, (1) via mqtt, measuring is triggered in the ESP, and (2) a flow variable is set to indicate that the current temperature value is invalid. Then, the flow waits about 3 seconds (with JS setTimeout function - however, it doesn't work the same as it would "normally", so I can handle only fixed waiting time, can't exit if the updated value via mqtt arrives).

Once the time is over, the new measured value is sent back to the user via telegram. The same logic has been developed for getting the relay's status to know always if the user request (set a relay on or off) is really done.

So, to my original question: via flow variables I could manage process flow control, but what works in JSfiddle, doesn't work in node-red, so it had been simplified to a fixed timeout, depending on the query/device.

Thanks once again!

The JS code that would wait either until a valid temperature value arrives or timeout. In JSFiddle, it works, in node-red's function node doesn't. Could you give me any hint why? Thanks!

var timeoutMsec = 3000;
var myDelay = 100;
var i = 0;
var imax = timeoutMsec / myDelay;

console.log(imax);


  while (i < imax) 
  {
  
  	//console.log(i);
    
    (function(i,imax) 
    {
      setTimeout(function() 
      {
        if (isready(i,imax))
        {
          console.log(i);
        }
        
      }, i*100)
    })(
    i++
    )
  }


function isready(i,imax)
{
  if (i >= 20) 
	// here, the real condition would be if a valid value appeared in the flow.actualTemperatureValue variable
  {
    return false;
  }
  else
  {
  return true;
  }
}

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.