Configure sensor to show increments / delta changes of other cumulative sensor

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.

Any advice?

Use a utility meter with an hourly cycle?

You can use the derivative integration to measure the change in a sensor over a selected time window.

1 Like

I’m really lost here and assume I do something fundamentally wrong.

First, I tried the utility meter as suggested by @tom_l

# AdGuard DNS queries blocked
utility_meter:
  adguard_dns_queries_blocked_1h:
    source: sensor.adguard_dns_queries_blocked
    cycle: hourly

when I plot this, it looks like this:

image

The corresponding yaml for plotting is:

type: 'custom:mini-graph-card'
entities:
  - entity: sensor.adguard_dns_queries_blocked_1h
show:
  labels: true
  icon: false
  name: false
  graph: bar
line_color: red
hour24: true
lower_bound: 0
hours_to_show: 24
points_per_hour: 1

Unfortunately, counting the blocked requests by hand inside AdGuard for an exemplary hour gives me a result that’s 2x what is plotted here.

I then tried the derivative integration as suggested by @Michael-M

# AdGuard DNS queries blocked
sensor:
  - platform: derivative
    source: sensor.adguard_dns_queries_blocked
    name: adguard_dns_queries_blocked_1hd
    round: 0
    unit_time: h
    time_window: "01:00:00"

The plot looks like this:

image

The code for plotting is pretty much the same:

type: 'custom:mini-graph-card'
entities:
  - entity: sensor.adguard_dns_queries_blocked_1hd
show:
  labels: true
  icon: false
  name: false
  graph: bar
line_color: red
hour24: true
lower_bound: 0
hours_to_show: 24
points_per_hour: 1

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.

Is there anyone who could enlighten me?

Using the utility meter try this:

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:

image

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).

You should probably read point 16 here.

Apologies, post edited.

1 Like