Analog values through Rules - MQTT
Moderators: grovkillen, Stuntteam, TD-er
Analog values through Rules - MQTT
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?
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?
Re: Analog values through Rules - MQTT
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
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
Re: Analog values through Rules - MQTT
WOW Incredible, you are a genius. I also managed to understand how the Timers work in the Rules!
this is my tweaked code
Thank you so Much! From Argentina!
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!
Re: Analog values through Rules - MQTT
You're welcome and nice to see it was working (and also that you found the preferred abs() notation in the docs )
Re: Analog values through Rules - MQTT
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: 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
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: 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
Re: Analog values through Rules - MQTT
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?
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?
Re: Analog values through Rules - MQTT
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: Now I am trying to find the passing of this mirror with a photoelectric sensor. 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 It just samples at 1/second.
The MQTT-Server sees this signal Additionally, I set these rule
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
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: Now I am trying to find the passing of this mirror with a photoelectric sensor. 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 It just samples at 1/second.
The MQTT-Server sees this signal 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
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
Re: Analog values through Rules - MQTT
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:
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
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
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
Re: Analog values through Rules - MQTT
Great, that worked well. I updated the rules a little bit again.
Here is my file:
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
Re: Analog values through Rules - MQTT
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)
Re: Analog values through Rules - MQTT
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.
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.
Re: Analog values through Rules - MQTT
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 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
RPi with Python 3.7 and MQTT, BSH, multiple ESP8266 with mega-20220809_57b0c0c
Re: Analog values through Rules - MQTT
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.
Here is my problem: 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:
I take another counter and make the gatekeeper open again only after 10 more values. This works robustly.
Many greetings
Arne
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.
Here is my problem: 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:
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
Many greetings
Arne
Re: Analog values through Rules - MQTT
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.
Who is online
Users browsing this forum: No registered users and 63 guests