Custom period with utility_meter and service reset by automation

Is it possible to use the utility_meter without a cycle, using only an automation to reset its counter?

I would like to track the number of kilometers travelled for each charge of my car, but not with an input number because my goal is having statistics for each charge. utility_meter seems perfect for this purpose, but I can’t find the correct way to reset it when I’m charging the vehicle (and using without tariffs and cycles).

This is my current automation.reset_distance_travelled:

id: '1652210702680'
alias: Reset distance travelled
description: When charging, reset the counter of the distance in km
trigger:
  - platform: state
    entity_id: switch.car_charging
    from: 'off'
    to: 'on'
condition: []
action:
  - service: utility_meter.reset
    entity_id: sensor.km_foreach_charge
mode: single

The utility_meter sensor.km_foreach_charge helper is defined like so:

state_class: total_increasing
source: sensor.car_odometer
status: collecting
last_period: '0'
last_reset: '2022-05-10T19:15:18.507533+00:00'
unit_of_measurement: km
icon: mdi:counter
friendly_name: km for each charge

It works, as it’s counting the distance travelled (by calculating the km difference from the odometer), but even if the automation has been triggered during charging, the status is still collecting with the distance not being 0 (27 at the moment).

It should have moved the previous value to the last_period attribute and started a new cycle.

The log seems correct:

this:
  entity_id: automation.reset_distance_travelled
  state: 'on'
  attributes:
    last_triggered: null
    mode: single
    current: 0
    id: '1652210702680'
    friendly_name: Reset distance travelled when charging
  last_changed: '2022-05-11T15:49:38.183144+00:00'
  last_updated: '2022-05-11T15:49:38.183144+00:00'
  context:
    id: b5376f08ebff13d067f0bc4b947733b7
    parent_id: null
    user_id: null
trigger:
  id: '0'
  idx: '0'
  platform: state
  entity_id: switch.car_charging
  from_state:
    entity_id: switch.car_charging
    state: 'off'
    attributes:
      last_result: ''
      last_updated: null
    last_changed: '2022-05-11T21:04:48.690588+00:00'
    last_updated: '2022-05-11T21:04:48.690588+00:00'
    context:
      id: 6af6d443d5125e2d655411aad32ed336
      parent_id: null
      user_id: null
  to_state:
    entity_id: switch.car_charging
    state: 'on'
    attributes:
      last_result: ''
      last_updated: null
    last_changed: '2022-05-12T03:09:55.285780+00:00'
    last_updated: '2022-05-12T03:09:55.285780+00:00'
    context:
      id: 187c722c1960a2c459b99811332b0509
      parent_id: null
      user_id: null
  for: null
  attribute: null
  description: state of switch.car_charging

This would be my desired output:

Sample

So a graph with the last 10 distances travelled with every car charge; unfortunately it doesn’t seem so simple to do as there’s no documentation about this type of request.

It isn’t very hard to create a uitility_meter like sensor that resets when you want it to. The problem however is that the horizontal axis is not time anymore, as there is no even distribution of charge cycles over time. So having a utility_meter like you describe does not fully solve your problem.

The graph you would get is a sawtooth-like line. It would show you what you need to know, but not as nice in a bar chart as you’d hoped. Maybe someone else knows how to do that.

The way to create such a sensor is by creating two entities: one numerical input helper to represent the usage value (or odometer value) at the time of last charge. The other is a template sensor that substracts that value from the current usage number (or odometer value). Every time you charge, you copy the current total usage to the input helper, effectively resetting the sensor that holds the difference.

You could by the way also use the input as a counter and reset it. I do not understand why you discard that as an option, because the history of the counter would produce the same graph. The reason for me to describe it as I did is because I think the total sum is as useful as the counter.

Come to think of it: you could produce a block shaped line too if you use an input helper to store the value of the last charge cycle. Problem is it would only show finished cycles, so it would be one period behind. You would always miss the current charge cycle.

Do note that to keep long term statistics, influxdb or something similar is needed. AFAIK that is not different with the utility_meter sensors. They stil rely on recorder, which is not meant to hold long term storage. And Grafana is more likely to be able to get a bar chart out of it, though I do not know enough of it to know how to.

1 Like

Thanks for your answer. Yes, in fact that’s the major issue in using utility_helper: it doesn’t provide “custom cycles”, not related with a time base.

I discarded it because I thought there was a way to store the previous “sums” in the database instead of having the sawtooth graph. In fact I had the sawtooth chart with the counter.

I thought it was possible - and I though the utility_meter did that, actually - to keep the sensor “collecting” the data of the distances (with the total_increasing sensor) within the current charge and, when triggering the service reset by the automation (i.e. during the charge), only the total value before the reset would have stored in the db.
So for example: 45 km, 40 km, 51 km, 49 km and so on… and then display those in a bar chart.

So are you saying what I’ve written before in your opinion is not possible using the HA db? Isn’t it what the utility_meter does when dealing with monthly cycles, for example? I don’t think the db stores every single value that is then “grouped” into months for visualization, but only an array of the last_period attributes. Or maybe I’m wrong and it doesn’t work like that… :confused:

Again, in my opinion the documentation is not so clear about this.

OK, suppose I deal with the problem from another perspective, the one you suggested.

I have now the template sensor:

# Template sensors
template:
  - sensor:
      - unique_id: km_since_last_car_charge
        name: 'km since last charge'
        icon: mdi:counter
        unit_of_measurement: 'km'
        state: >
          {{ states('sensor.car_odometer')|int(0) - states('var.previous_car_charge_odometer')|int(0) }}
        availability: >
          {{ states('sensor.car_odometer') | is_number() and 
             states('sensor.car_odometer')|int(0) >= states('var.previous_car_charge_odometer')|int(0) }}

It works well and when I’m starting the charge I’m updating the underlying variable like this (i.e. copying the odometer):

id: '1652210702680'
alias: Reset distance travelled
description: When charging, reset the counter of the distance in km
trigger:
  - platform: state
    entity_id: switch.car_charging
    from: 'off'
    to: 'on'
condition: []
action:
  - service: var.set
    data:
      entity_id: var.previous_car_charge_odometer
      value: '{{ states(''sensor.car_odometer'') | int(0) }}'
mode: single

In the same automation, when starting a charge, I would like to store the contents of the km_since_last_car_charge sensor above before copying the odometer, so I can get the historic values. What is the correct way to do that?

What do you mean: store the last charge value in the template sensor? You cannot set its value, as the value is always the result of the calculation.

The km_since_last_car_charge sensor will produce the sawtooth all on it’s own, because when you set the pervious charge value on charging, it drops to zero and starts counting the next cycle. The top of each sawtooth is the total of that charge cycle. The last saw tooth will sow the value up to now for the current charge cycle.

It will store history for as long as the recorder keeps data. The default is 10 days. If you use Influxdb, you can set that to keep history indefinitely, as that is way better at storing large amounts of data efficiently. “Normal” history is based on the recorder, which is not suited for long periods of history.

If you want to to create a block shape graph in history (with only full charge cycle values) then you do not need a template sensor. You could just use an input helper. At the end of each charge cycle, you could copy the difference between the current total and the total at the start of the cycle. After that you can set the variable for the last total at the end of the cycle. Home assistant will perform the actions in the automation in consecutive order.

The recorder will also keep history for input helpers for as long as the recorder is set to keep it. Again, if you use influxdb, you can keep the data indefinitely.

The second option will look the most like a bar chart, but will always be one charge cycle behind, because you only change the value when the full charge cycle is known.

1 Like

I mean storing the value in another tag/variable.

In fact it does.

Yep, correct. I’ve modified the automation above with this:

id: '1652210702680'
alias: Reset distance travelled
description: When charging, reset the counter of the distance in km
trigger:
  - platform: state
    entity_id: switch.car_charging
    from: 'on'
    to: 'off'
condition: []
action:
  - service: var.set
    data:
      entity_id: var.previous_car_charge_distance
      value: '{{ states(''sensor.km_since_last_car_charge'') | int(0) }}'
  - service: var.set
    data:
      entity_id: var.previous_car_charge_odometer
      value: '{{ states(''sensor.car_odometer'') | int(0) }}'
mode: single

The first of the two action is new, and copies the template sensor into a new variable var.previous_car_charge_distance. This is the variable I would like to graph and save history.

OK, so I’m forced to use InfluxDB even for this specific (and easy) task.

Of course, as there are no other ways to do that. Or can InfluxDB make the calculations to create a bar chart from the sawtooth data? I mean to display the max value after each zero cross as a bar.

Yes. Bessides the energy panel, which has its own long term storage, pretty much everyting else needs a tool dedicated to it. Grafana would be the tool of choice to display Infludb data. It may well be able to convert the sawtooth to bars, but I as I said in my first post, Ido not know how.