I would like to have a sensor that shows me how much another sensor changed over the last hour (or whatever time interval I chose). From the posts I read this should somehow be possible with a template and a statistics sensor, but documentation is so bad that I cannot figure it out myself.
In my specific case, I would like to graph the DNS queries blocked by AdGuard within a 1h time interval, to see activity going up and down. The sensor.adguard_dns_queries_blocked is cumulative and keeps increasing all the time, so that’s difficult to read in the frontend.
I tried something like this:
# AdGuard DNS queries blocked in last hour
- platform: statistics
name: adguard_dns_queries_blocked_stats_1h
entity_id: sensor.adguard_dns_queries_blocked
max_age:
minutes: 60
- platform: template
sensors:
adguard_dns_queries_blocked_1h:
value_template: "{{ state_attr('sensor.adguard_dns_queries_blocked_stats_1h', 'change') }}"
unit_of_measurement: "ads/h"
But the resulting sensor actually gives negative numbers, which doesn’t make sense for a result, so something must be wrong.
The graph here shows something totally different and I honestly have no idea what it shows. It’s also not clear how the derivative can ever be negative for a base sensor that’s constantly increasing.
type: 'custom:mini-graph-card'
entities:
- entity: sensor.adguard_dns_queries_blocked_1h
aggregate_func: max
group_by: hour
show:
labels: true
icon: false
name: false
graph: bar
line_color: red
hour24: true
lower_bound: 0
hours_to_show: 24
points_per_hour: 60
This will take a reading every minute and record the maximum for the hour. It might be slightly less than you see in AdGuard if the last minute of the hour has a lot of blocking events. The only way to improve this is to increase the points per hour.
The way you had it the graph averaged the whole hour to produce one point. Hence it was half way between the start (0) and end value for the hour.
Thanks for the continued advice. Here are the two graphs, the upper one is my previous configuration, the lower one is the configuration suggested above:
It still doesn’t add up. Ignoring the last bar (as that hour is not over yet), the one for 15:00 to 15:59 shows 47 queries. When I manually count the log on AdGuard it is 52. The bar from 13:00 to 13:59 shows 49 queries. The log has 105.
Maybe the primary counter of the integration is wrong? So I checked that. And indeed. The history of the sensor.adguard_dns_queries_blocked from 13:00 to 13:59 differs by exactly 49. And from 15:00 to 15:59 the difference is 47.
So the calculation and configuration with the utility_meter seems right, but the AdGuard sensor doesn’t seem to reflect the log. Argh.
Going down the rabbit hole, checking the AdGuard Home python API client I notice that for the it retrieves a statistic called num_blocked_filtering. Following this to the AdGuard API, it looks like this is a total number of queries blocked, probably depending on the AdGuard setting of how long to keep the statistics data.
If that’s the case, I don’t think the sensor can be easily used to what I’m looking for. For every hour that new data is coming in, old data is going out at the end of the time interval. That would mean that my assumption of an ever increasing sensor is not true and the delta measured by the utility_meter captures both, the change of the last hour and the change of the first hour in the interval. Which would mean it can go negative.
There is another statistic exposed by the AdGuard Home API called (ironically) blocked_filtering and it seems to be an array of blockings per time interval, which can be hours or days. Unfortunately, the Python client doesn’t expose this so the HA integration cannot build a sensor on top.
I’ve marked the answer of @tom_l referring to utility_meter as solution as the question was generic and not necessarily about AdGuard Home, even though that was where I am struggeling (and which is still unsolved).