To extract a derivative of a sensor (or even simply delta), is it best to create a global variable to store previous value and compare with current value? Is there a better method?
For a delta sensor, if you need to do it in ESPHome you can put this on a copy sensor:
filters:
- lambda: |-
static float last_value = 0;
float change = 0;
change = x - last_value;
last_value = x;
return change;
And on ESPHome Discord if you search for “Delta Sensor (Change from previous value). Survive Deep Sleep” there’s also a way using globals that will survive a deep sleep.
I didn’t realize that’s how the static keyword works in lambdas. Nice. That solves the issue.
Just out of curiosity; how can I use a copy sensor to get delta? Do I understand correctly that it simply mirrors the state of another?
EDIT: right, I think I get it: instead of creating a separate sensor that fetches the value of the other sensor, it’s easier to create a copy sensor
for the delta purpose.
Copy sensors are a newer thing. Before that you’d probably use a template sensor to duplicate an existing one.
Most of the solution came from somewhere else on the internet with a few additional improvements then suggested by jesserockz on Discord.
My solution for a time derivative, so far stable for me.
- platform: copy
source_id: wasser_boiler
id: "wasser_boiler_derivative"
unit_of_measurement: "°C/h"
name: "Warmwasseränderung Boiler"
filters:
- lambda: |-
static float last_value = 0;
static float last_time = 0;
float time = (float) millis();
if (last_time == 0){
last_value = x;
last_time = time;
return {};
}
float change = ( ( x - last_value ) / ( time - last_time ) ) *1000*60*60;
last_value = x;
last_time = time;
return change;
- sliding_window_moving_average:
window_size: 3
send_every: 2
- or:
- delta: 0.01
- heartbeat: 120minutes
- throttle: 1minutes
Note: the delta is on the derivative, so compared to the source a acceleration filter.