Analog values through Rules - MQTT

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
elakdmico
New user
Posts: 2
Joined: 01 Jun 2022, 15:32

Analog values through Rules - MQTT

#1 Post by elakdmico » 01 Jun 2022, 15:36

Hi!
I need to send values of an analog potentiometer by MQTT. I can't find a way to create a rule to send the values only when they change.
If the potentiometer doesn't move, I don't want any message to be sent. When it moves I want it to send them to the MQTT broker so that they can be treated in NodeRed.

Right now, every second it sends the value it currently has, which results in a lot of unnecessary message sending.

Does anyone know how to implement this through Rules?

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

Re: Analog values through Rules - MQTT

#2 Post by TD-er » 01 Jun 2022, 16:46

You can store the current value in a variable and compare it.
If it differs enough, you can call the publish command to publish the value.

Something like this (untested)
- Store the last value in variable #1
- Use variable #2 for temporary calculations
- Assume a task named "analogtask" which has a value named "value"
- Using threshold of 0.1

Code: Select all

On System#Boot do    //When the ESP boots, do
  looptimerset_ms,1,1000      //Set loop timer #1 to create an event every 1000 msec
endon

on Rules#Timer=1 do
  let,2,{abs:[var#1]-[analogtask#value]}  // Compute absolute difference

  if [var#2]>0.1
    let,1,[analogtask#value] // Store the new value in variable #1
    publish,MyMqttTopic,[var#1]  // You need to place your own topic here  
  endif
endon

elakdmico
New user
Posts: 2
Joined: 01 Jun 2022, 15:32

Re: Analog values through Rules - MQTT

#3 Post by elakdmico » 01 Jun 2022, 18:20

WOW Incredible, you are a genius. I also managed to understand how the Timers work in the Rules!

this is my tweaked code
On System#Boot do //When the ESP boots, do
looptimerset_ms,1,1000 //Set loop timer #1 to create an event every 1000 msec
endon

on Rules#Timer=1 do
let,2,abs([var#1]-[Potencia#Analog]) // Compute absolute difference

if [var#2]>10
let,1,[Potencia#Analog] // Store the new value in variable #1
publish,reg_velador/potencia,[var#1] // You need to place your own topic here
endif
endon

Thank you so Much! From Argentina!

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

Re: Analog values through Rules - MQTT

#4 Post by TD-er » 01 Jun 2022, 21:56

You're welcome and nice to see it was working (and also that you found the preferred abs() notation in the docs :) )

User avatar
dasarne
New user
Posts: 4
Joined: 14 Oct 2022, 13:11

Re: Analog values through Rules - MQTT

#5 Post by dasarne » 14 Oct 2022, 15:19

Hi there,
first of all: Thanx showing me the Rules-Engine. This really enhances ESP Easy for me. The algorithm discussed here is exactly what I need. My signal looks like this:
WhatsApp Image 2022-10-12 at 14.48.56.jpeg
WhatsApp Image 2022-10-12 at 14.48.56.jpeg (26.35 KiB) Viewed 3380 times
Unfortunately, my signal is a bit faster, so the peaks shown are not found with a frequency one sample/second for sure.
Do I see that correctly, that your example depends on the Analog input task "analogtask" and there the value "value" is set? Can I read the analog value directly in a rule timer event?
Is there another possibility to read out the analog measured value a bit faster than a second :?:

Yours
Arne

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

Re: Analog values through Rules - MQTT

#6 Post by TD-er » 14 Oct 2022, 17:49

How fast do you need to sample?

If it is "too fast" then rules parsing may be a bit too much...
But we could of course add something to the ADC plugin (which is very likely something I already was thinking of adding...) to measure spikes and send events.

Can you explain your use case a bit more?
Maybe the pulsecounter or "monitor" can also be used here?

User avatar
dasarne
New user
Posts: 4
Joined: 14 Oct 2022, 13:11

Re: Analog values through Rules - MQTT

#7 Post by dasarne » 15 Oct 2022, 19:31

Hi TD-er,
thank you for the reply. My goal is to read my gas meter (older generation) to measure my gas consumption.
I noticed that the last digit in the six has a small mirror:
20220930_102353.jpg
20220930_102353.jpg (247.53 KiB) Viewed 3337 times
Now I am trying to find the passing of this mirror with a photoelectric sensor.
20221015_183645.jpg
20221015_183645.jpg (695.2 KiB) Viewed 3337 times
The signal is a bit noisy, also the passing numbers produce a weak signal. The mirror in the six produces a peak of about 30 analog units. Unfortunately, the signal is (more or less) short because the mirror is flat and therefore reflects only at a certain angle. The signal width depends on the gasflow.
I have now finally put everything together at the meter and made a first measurement without my own software but with EE. Currently I have in EE an analog input - internal
Screenshot_20221015_190808.png
Screenshot_20221015_190808.png (20.3 KiB) Viewed 3337 times
It just samples at 1/second.
The MQTT-Server sees this signal
Screenshot_20221015_185619.png
Screenshot_20221015_185619.png (8.33 KiB) Viewed 3337 times
Additionally, I set these rule

Code: Select all

On System#Boot Do    //When the ESP boots, do
  looptimerset_ms,1,1000      //Set loop timer #1 to create an event every 1000 msec
Endon

On Rules#Timer=1 Do
  looptimerset_ms,1,1000
  Let,2, ([var#1]-[Gas#Analog])  // Compute absolute difference
  If [var#2]>10
    Publish,/SensorData/Gas/signal,1  // You need to place your own topic here  
  Endif
  Let,1,[Gas#Analog]
Endon
But this sends too many signals in mqtt...

My sensor needs peak detection.
Maybe it works like this: You would have to measure higher frequency and then find an extremum via the first derivative. First the first derivative must be greater than zero then equal to zero and then less than zero. Or the other way around. The first derivative does not have to be normalized for this. It is sufficient to simply form the differences of the measured values.
Do you have a better idea? How could you find the peak at the mirror? Should I read the data from the sensor with a small self-written program, so that you can test the algorithm?

I'm curious to see what happens next.

Lots of regards
Arne

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

Re: Analog values through Rules - MQTT

#8 Post by TD-er » 15 Oct 2022, 20:07

Yep, extending the ADC plugin to create events when the value changes > N would be my guess to fix this.
However, in the very recent commits, you now also have some kind of statistics.
This can be used with the ADC plugin too.
The ADC plugin will perform a lot more reads per second (when using oversampling).
Now with these statistics, some info is made accessible, like average, min, max.

See: https://espeasy.readthedocs.io/en/lates ... statistics

So with your task called "Gas" and the value "Analog", you can also access these stats values via
[gas#analog.max]
[gas#analog.min]
[gas#analog.avg]

To reset the min/max, you can call the gas.resetpeaks command.

Thus from the rules, you could do something like this:

Code: Select all

on gas do
  let,1,[gas#analog.avg]-[gas#analog.min] // Compute offset
  if [var#1]>40
    // Count the nr of pulses
    let,2,[int#2]+1  
    logEntry,"Gas: [int#2] counts, signal: [var#1]"
  endif
  gas.resetpeaks  
endon
This still may need some extra checks as the dial may be stuck for a while if you're not consuming gas while the mirror is in front of the sensor, or perhaps the dial rotates so slowly you'll measure a few seconds the reflective signal.
So you'll need to look also for at least 1 second of not seeing the reflection.
I'll leave that as an exercise for the reader :)

User avatar
dasarne
New user
Posts: 4
Joined: 14 Oct 2022, 13:11

Re: Analog values through Rules - MQTT

#9 Post by dasarne » 16 Oct 2022, 19:38

Great, that worked well. I updated the rules a little bit again.

Here is my file:

Code: Select all

On System#Boot Do    //When the ESP boots, do
  looptimerset_ms,1,1000      //Set loop timer #1 to create an event every 1000 msec
Endon

On Rules#Timer=1 Do
 //Find a peak 
 //A peak pushes min and max apart
 let,1,[Gas#Analog.max]-[gas#Analog.min] 
 if [var#1]>20   
    //One peak can trigger several signals. To prevent this, there is a gatekeeper here.
    If [int#2]=0
     //Report that we have found a peak.
     Publish,/SensorData/Gas/signal,1
     //Close the gatekeeper and wait 10 seconds to open it again. 
     Let,2,1
     TimerSet,1,10
    Endif
  Endif 
  //Reset the statistics of the analog input
  gas.resetpeaks  
Endon

//Timer to open the gatekeeper again
On Rules#Timer=1 do
   Let,2,0
 endon

User avatar
Ath
Normal user
Posts: 3416
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Analog values through Rules - MQTT

#10 Post by Ath » 16 Oct 2022, 20:02

dasarne wrote: 16 Oct 2022, 19:38 Great, that worked well. I updated the rules a little bit again.
You re-used timer 1, but that's not going to work as intended, better use timer 2 for that (or any other timer, there are max. 256 available)

Code: Select all

On System#Boot Do    //When the ESP boots, do
  looptimerset_ms,1,1000      //Set loop timer #1 to create an event every 1000 msec
Endon

On Rules#Timer=1 Do
 //Find a peak 
 //A peak pushes min and max apart
 let,1,[Gas#Analog.max]-[gas#Analog.min] 
 if [var#1]>20   
    //One peak can trigger several signals. To prevent this, there is a gatekeeper here.
    If [int#2]=0
     //Report that we have found a peak.
     Publish,/SensorData/Gas/signal,1
     //Close the gatekeeper and wait 10 seconds to open it again. 
     Let,2,1
     TimerSet,2,10
    Endif
  Endif 
  //Reset the statistics of the analog input
  gas.resetpeaks  
Endon

//Timer to open the gatekeeper again
On Rules#Timer=2 do
   Let,2,0
 endon
/Ton (PayPal.me)

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

Re: Analog values through Rules - MQTT

#11 Post by TD-er » 16 Oct 2022, 21:46

Why set a new timer?
This will for sure fail if the dial is "stuck" at a position for a while since you stopped using gas until the heater turns on again.
Also you should at least clear the peaks when "opening" the gate again.

Better keep a flag that you've still not seen another value inbetween.
This can be done by either checking the max. peak value, or set a variable.

puzzle
New user
Posts: 1
Joined: 17 Oct 2022, 21:35

Re: Analog values through Rules - MQTT

#12 Post by puzzle » 17 Oct 2022, 21:41

Hi,
I wonder if something like an interrupt is an alternative in the mirror case. Think about using a light sensor, connected to a transistor and then 3.3 volts (and a resistor) to a GPIO pin which is set to be an input.
I‘m more likely puzzling code than being an expert. But there are so many ideas …

RPi with Python 3.7 and MQTT, BSH, multiple ESP8266 with mega-20220809_57b0c0c

User avatar
dasarne
New user
Posts: 4
Joined: 14 Oct 2022, 13:11

Re: Analog values through Rules - MQTT

#13 Post by dasarne » 17 Oct 2022, 21:53

Hi together,
I ran into this exact problem. For reasons unknown to me, the timer is not always called reliably. After that, everything was broken because var#2 won't be reset. :roll:
Here is my problem:
Screenshot_20221017_214248.png
Screenshot_20221017_214248.png (13.33 KiB) Viewed 3250 times
The peak is so wide that generates multiple hits where min and max are more than 20 digits apart. The further timer should prevent this.
Here is my solution: :D

Code: Select all

On System#Boot Do    //When the ESP boots, do
  looptimerset_ms,1,1000      //Set loop timer #1 to create an event every 1000 msec
  Let,2,0
  Let,3,0
Endon

On Rules#Timer=1 Do
  looptimerset_ms,1,1000
 Let,1,[Gas#Analog.max]-[gas#Analog.min] // Compute offset
 LogEntry,'[var#1] [var#2]'
 If [var#1]>20  And [var#2]=0
   Publish,/SensorData/Gas/signal,1
   Let,2,1
  Endif
  If [var#2]=1
    Let,3,[var#3]+1
    If [var#3]=10
      Let,2,0
      Let,3,0
    Endif
  Endif
  gas.resetpeaks  

Endon

I take another counter and make the gatekeeper open again only after 10 more values. This works robustly.

Many greetings
Arne

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

Re: Analog values through Rules - MQTT

#14 Post by TD-er » 17 Oct 2022, 22:18

dasarne wrote: 17 Oct 2022, 21:53 Hi together,
I ran into this exact problem. For reasons unknown to me, the timer is not always called reliably. After that, everything was broken because var#2 won't be reset. :roll:
[...]
Can you check the timing stats page?
By default collecting the timing stats is disabled, but you can enable it on the tools->Advanced page. (if it is included in the build, builds with LIMIT_BUILD_SIZE do not have it included)
N.B. each time you load the timing stats page, the stats will be reset.

I think you may have some blocking code in your setup which may take quite long to execute.
During execution of other stuff, the ADC will not be sampled.

Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 23 guests