How To Create a Counter, that counts how many times a device has been turned on?

Hello guys,
I recently started using HA and have amateur skills, meaning that I have difficulties getting along with the technicalities and YAML. Nevertheless, I tried my best to create a code, which allows me to see how many times a device has been turned on. This has been based on many templates and community posts I saw on the internet. The code is as follows:

counter:
  'counter.zahler_wasserspender':
    initial: 0
    step: 1
  -automation:
  -alias: 'Increment if over measurement'
    trigger:
     platform: time_pattern
     seconds: '/30'
   condition:
     condition: state
     value_state: "{{ states('sensor.shellyplug_s_c8c9a3b8d590_power') | int >= 5.5 }}"
   action:
     service: 'counter.increment'
     entity_id: 'counter.zahler_wasserspender'

If the device has a higher power than 5.5 Watts, it is considered to be on (based on the measurements and experiments I performed). I also created the counter with the ‘Helpers’ option, however for some reason the counter does not increment when the device is being used. I am not really sure if I have to use ‘state’ as a condition or ‘device’ and if ‘time_pattern’ is fitable as a trigger in that situation.

Where did I make any mistakes or do you have any suggestions?
Everything is extremely appreciated, thank you in advance!

Cheers

Welcome within HA community.

So first of all please use the “Preformatted text (Crtl+E)” option to post any YAML code :wink:
That makes reading easier for everyone and as YAML is a formatted language a error typically is some space missing at the beginning.

In regards to your code (after I brought it to some useful formatting) I found several errors:

  1. the counter is defined without the entityt type (so not counter.X, but only X) - see example at Counter - Home Assistant (home-assistant.io)

  2. time_pattern triggers are always a bad idea …try to use them as “last change” only solution.
    There are better options to really trigger your automation when it is needed only. - Check out: Automation Trigger - Home Assistant

  3. your automation (if it would be working) would increment the counter EVERY 30 seconds as long as your shelly plug is higher than 5.5 watts… so e.g. if your shelly plus is 2 minutes higher than 5.5watts the count would be 4 - as I understood this is not what you want to achieve.
    So, what is needed is a helper entity which keeps track if the power was lower than 5.5 watts since the last count. Only if the power goes lower than 5.5 watts once, it is considered off.

For point 3 there are two options how to solve it

a) MORE OBVIOUS - BEGINNER SOLUTION: Create an input_boolean which is turned on/off as part of the automation. Trigger the automation using numeric state trigger. One “turn_on” trigger if shelly plug is >= 5.5 v; One “turn_off” trigger if shelly plus is < 5.5.
Add for each trigger a condition that ensures

  • “on” tasks are only executed if the helper input_boolean is currently ‘off’ and
  • “off” tasks are only executed if hte helper input_boolean is currenly ‘on’

b) HA TEMPLATE SOLUTION - the one I will show here:
Create the counter entity:

counter:
  zahler_wasserspender:
    initial: 0
    step: 1

Create a helper template binary_sensor. This binary sensor has a value of “on” if shelly plug is >= 5.5V and “off” if the shelly plug is < 5.5V.

template:
  - binary_sensor:
      - name: "status_wasserspender"
        state: >
          {{ states('sensor.shellyplug_s_c8c9a3b8d590_power') | float(default=0) >= 5.5 }}

Create an automation which is triggered whenever the binary_sensor switches to ‘on’:

automation:
- alias: "Automation Name"
  trigger:
    - platform: state
      entity_id: binary_sensor.status_wasserspender
	  # adding from: off ensures not "unwanted" count if HA was offline and sensor state goes from "unknown" to "on"
      from: "off"
      to: "on"
    action:
      - service: counter.increment
        target:
          entity_id: counter.zahler_wasserspender
4 Likes

Here’s a full solution without using automations, that also does cycle interval durations and power.


input_number:
  cd_sump_on_threshold:
    min: 0.0
    max: 30.0
    step: 0.1
    mode: box
    unit_of_measurement: A

binary_sensor:
  - platform: template
    sensors:
      cd_sump_running:
        device_class: running
        value_template: >-
          {{ states("sensor.sump") | float(0) > states("input_number.cd_sump_on_threshold") | float(0) }}
template:
  - trigger:
      - platform: state
        entity_id: binary_sensor.cd_sump_running
        from: "off"
        to: "on"
    sensor:
      - name: "cd_sump_last_start_time"
        state: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }} "
  - trigger:
      - platform: state
        entity_id: sensor.cd_sump_last_start_time
    sensor:
      - name: "cd_sump_off_duration"
        state: "{{ as_timestamp(now())|int(0) - as_timestamp(trigger.from_state.state)|int(0) }}"
        unit_of_measurement: sec
  - trigger:
      - platform: state
        entity_id: binary_sensor.cd_sump_running
        from: "off"
        to: "on"
    sensor:
      - name: "cd_sump_cycle_count"
        state: "{{ states('sensor.cd_sump_cycle_count')|int(0) + 1 }}"
        unit_of_measurement: cycles

sensor:
  - platform: statistics
    name: cd_sump_off_duration_average
    entity_id: sensor.cd_sump_off_duration
    state_characteristic: mean
    max_age:
      hours: 24
  - platform: template
    sensors:
      cd_sump_watts:
        device_class: power
        unit_of_measurement: watts
        value_template: >-
          {{ states("sensor.sump")|float(0) * states("sensor.switch_2_voltage")|float(0) }}
recorder:
  include:
    entities:
      - input_number.cd_sump_on_threshold
      - binary_sensor.cd_sump_running
      - sensor.cd_sump_last_start_time
      - sensor.cd_sump_off_duration
      - sensor.cd_sump_off_duration_average
      - sensor.cd_sump_cycle_count
7 Likes

Thank you very much, it is highly appreciated! :grinning:
However, I have two short questions:

1.How do I create the binary senspor exactly, with the helper tool or I have to paste the code inside sensor.yaml?
2. How do I get the entity_id?

Cheers

Thank you very much, I will consider your solution as well! :+1:

You may be able to create it all via the UI, don’t know, I do all my config in YAML since it’s easier.

What I do is create a packages subfolder off of the config directory and toss this in a file in there.

Then in configuration.yaml I have this statement

homeassistant:
  packages: !include_dir_named packages

That picks up and loads all the files in that directory. This way all the config for an item is in one file. As you add more things this provides a good organizational structure to keep this stuff together. I have about 100 packages, The example I posted is the current detector package for a sump pump.

1 Like

Thanks for the fast reply!
Do you have an idea on how to figure out the entity id of the binary sensor?

Cheers

Wow, nice!

I track the number of times my pumps have cycled in the last hour, and I came here thinking I might offer some assistance. Instead I found your post which tracks even more. I will be using at least parts of this! Thanks!!

In the example above it is binary_sensor.cd_sump_running

1 Like

Hi! I have implemented this and it works awesome! I have a question though. Is there a user friendly way to view/run historical reports? For example, if I want to run a report for June 29, or even some date range or time range. All help is appreciated.

Thank you!

I’ve found that the HA database isn’t optimized for archival data or reporting like you describe.

I have a similar requirement for a sensor which totals up the run-time of my heating system boiler. I save daily run-time statistics to a flat file I can then analyze using external tools (like Excel or whatever statistical analysis package you use.

I described it some time ago, here.

1 Like

Hi,
I’m very appreciating this reply as it gives a very good start for all the sensor i want to create.

My question right now is: let’s say I prepare a list of sensors like your example which can be applied to a specific appliance. I already have around 30-40 differente power sensors that are providing me a Watt value. Is there a way I can replicate this structure as a “template”?

Something like blueprints, but instead of using for only automation I’m actually bulk-definining new sensors.

I do that outside of home assistant. Meaning I’ll take that package, perform string replace on it and save as a new YAML file. I automate that by creating a shell script to perform the search and replace. This way if I improve the template I can rerun the shell script and update all instances of the template.

module_scripts.sh

current_detector_template()
# NAME
# CURRENT_SENSOR
# VOLTAGE_SENSOR
{
   sed "s/NAME/$1/g" current_detector_template_package.yaml | 
   sed "s/CURRENT_SENSOR/$2/g" | sed "s/VOLTAGE_SENSOR/$3/g" > $TARGET/packages/current_detector_template_$1_package.yaml
}

build.sh

TARGET="/mnt/c/github/ha_config"

source ./module_scripts.sh

current_detector_template sump sensor.sump sensor.switch_2_voltage

current_detector_template_package.yaml

input_number:
  cd_NAME_on_threshold:
    min: 0.0
    max: 30.0
    step: 0.1
    mode: box
    unit_of_measurement: A

binary_sensor:
  - platform: template
    sensors:
      cd_NAME_running:
        device_class: running
        value_template: >-
          {{ states("CURRENT_SENSOR") | float(0) > states("input_number.cd_NAME_on_threshold") | float(0) }}

template:
  - trigger:
      - platform: state
        entity_id: binary_sensor.cd_NAME_running
        from: "off"
        to: "on"
    sensor:
      - name: "cd_NAME_last_start_time"
        state: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
  - trigger:
      - platform: state
        entity_id: sensor.cd_NAME_last_start_time
    sensor:
      - name: "cd_NAME_off_duration"
        state: "{{ as_timestamp(now())|int(0) - as_timestamp(trigger.from_state.state)|int(0) }}"
        unit_of_measurement: sec
  - trigger:
      - platform: state
        entity_id: binary_sensor.cd_NAME_running
        from: "off"
        to: "on"
    sensor:
      - name: "cd_NAME_cycle_count"
        state: "{{ states('sensor.cd_NAME_cycle_count')|int(0) + 1 }}"
        unit_of_measurement: cycles

sensor:
  - platform: statistics
    name: cd_NAME_off_duration_average
    entity_id: sensor.cd_NAME_off_duration
    state_characteristic: mean
    max_age:
      hours: 24
  - platform: template
    sensors:
      cd_NAME_watts:
        device_class: power
        unit_of_measurement: W
        value_template: >-
          {{ states("CURRENT_SENSOR")|float(0) * states("VOLTAGE_SENSOR")|float(0) }}

recorder:
  include:
    entities:
      - input_number.cd_NAME_on_threshold
      - binary_sensor.cd_NAME_running
      - sensor.cd_NAME_last_start_time
      - sensor.cd_NAME_off_duration
      - sensor.cd_NAME_off_duration_average
      - sensor.cd_NAME_cycle_count
1 Like

Hi @PeteRage,

starting from your example, I ended up creating a whole series of sensors that can monitor the activity cycles of a device, the energy consumed, the cost of this energy, the number of cycles performed, and the duration of these cycles.

See image for reference:

Most of the sensors are only intermediate values used as source for the long-term utility-meter, this dashboard is only for demostration to understand the existing sensor related to a single device (even if most of them are excluded directly from the recorder)

I’m sharing my result with you so maybe can take additional ideas on how to improve it. I went a little bit heavy on the comments, but I guess it is all help you can receive to understand the structure.

This package comes in 3 parts, the basic one required (basic energy meter) and the other optionals (cycles and standby). Optional because like for example it makes sense to monitor the running cycles of an oven but not the main switch of the house which is never off.

This first package defines the initial sensors needed for the basic energy monitor
Here you can find the conversion from W to KwH, the calculation for the energy cost and the utility meters on multiple cycles for both the metrics

This packages defines the structure needed to monitor the energy consumption of a running cycle
Cycle: the device goes on (cycle starts) | the device goes off (cycle ends).
With these 2 marker I can calculate how long was the cycle, how many energy consumed and which is the cost of that energy

This packages defines the structure needed to monitor the energy consumption of the device when it is in stand-by
While the device remains off, a sensor records the energy consumed while in this state, and from there calculate the cost of that energy
Utility meters on multiple cycles are defined to keep track of this standby energy

From here, the second step of my idea is to now get this template and clone it multiple times using your suggestion of the script, at the end I only need to customize the input power sensor, the watt threshold to determine on/off and changes the prefix of all entities to make the ids unique…

Also, I still need to explorer the platform: statistics you are using in your example

1 Like

Very cool! Yes, you need variations and I like the way you are structuring it.

I use this technique for 90% of my HA configuration. We have 2 homes with two different HAs, so having one set of “templates” provides consistency. And there’s nothing better than adding a new feature to a “template” and running the script and updating all the instances. While it takes a little more time and you’ll debug build scripts, the benefits later on are tremendous. As an example, I have a template for monitoring zwave devices. Between both systems I have 120 devices. Change 1 template, run the build and I’ve updated 120 packages.

Another item to look at is lovelace_gen, this allows dynamic construction of the dashboards. I’ll have the build script generate a YAML file (for example with the list of current detectors) and then have lovelace Gen construct the dashboard (with a section per current detector or a view). This way you have the UI, data (aka HA templates) and automations. And I have a consistent experience across multiple systems.

Keep me updated on your progress.