Trigger an automation on a calculation

I would l like to write an automation that sends me an alert every time my solar battery charge is 10,20,30,40% etc. I have written one for each level at the moment, but I am hoping I can do it with a calculation.

I thought if I divide the value by 10 and it is a round number then trigger the automation.

Is this possible?

Sure, this is pretty straightforward. First I’d define a template sensor that calculates the charge modulo 10, like this:

template:
  - sensor:
      - name: Battery Level Mod 10
        state: "{{ states('sensor.battery_level')|int(default=-1) % 10 }}"

Then set up your automation to trigger whenever that template sensor goes to zero. The “default=-1” here would prevent the automation from triggering at HA startup or whenever the battery level is undefined.

Also I am interested for a different purpose (water tank increase) so thanks
Now, how would I know if it is rising or decreasing? Could this be done in the automation as a trigger from state being lower/higher than the trigger to state?

You can use either Template or Numeric state triggers that use the modulo function.

For a template sensor you can use the template that @wixoff supplied directly as a trigger:

trigger:
  - platform: template
    value_template: >
      {{ states('sensor.battery_level') | int(default=-1) % 10 == 0 }}

For Numeric state triggers, you can use the following (shown here with a condition to limit action execution for increasing battery level only, addressing @vingerha’s question) :

trigger:
  - platform: numeric_state
    entity_id: sensor.battery_level
    below: 1
    value_template: "{{ state.state | int % 10 }}"
condition:
  - alias: Is Increasing
    condition: template
    value_template: >
      {{ trigger.to_state.state | int > trigger.from_state.state | int }}
action: ...
4 Likes

That sounds perfect, thanks very much. Would you mind explaining the advantage of template over numeric state? Is just personal preference?

For this case, it’s mostly personal preference. Most users would likely just use the Template trigger… the configuration syntax for the Numeric state trigger with a value_template can be a little counterintuitive.

The cases where it makes a concrete difference is if you need to perform comparisons or math functions using more than one entity state value. The Template trigger will reevaluate when any of the included entities change value, but the Numeric state trigger will only be reevaluated when the entity listed in the trigger’s entity_id changes value.

These differences can be useful, but they can also be really frustrating if you don’t know the specific ways each trigger type works.

Thanks very much for the explanation. I have set this up, but the sun has been out all day and my battery hasn’t gone below 90% yet :slight_smile:

One other question if you don’t mind. Related to @vingerha question. I want to trigged when a notification when I start using the grid again. If I say the value has to be > 1 will it keep triggering when it goes to 2, then 3 etc. 0 is off grid, but anything above that will be on grid. I only want to trigger when it changes from 0 not every change.

If you plan on using this piece of information multiple times, such as other triggers or as a condition in other automations, this may be a good place to employee a template binary sensor. That way you don’t have to keep writing the same template over and over, and you machine doesn’t have to keep calculating it over and over…

template:
  - binary_sensor:
      - name: On Grid
        state: "{{ states('sensor.battery_level') | int(-1) > 0 }}"

No, state-based triggers only fire when they change from representing a false condition to a true one. For example, both of the following will only fire on the change from 0 to some value greater than 0… it will not re-trigger on the change from 1.2 to 1.3 or from 10 to 20 etc.

trigger:
  - platform: numeric_state
    entity_id: sensor.example
    above: 0
trigger:
  - platform: template
    value_template: "{{ states('sensor.example')| int(0) > 0 }}"

It is the use of modulo in the template of the previous trigger that makes it cycle through false-to-true transitions as the base value changes.

Thanks for your patience and explaining this. I am very new. My battery is now draining, but the automation did not trigger. This is my yaml. What did I miss?

alias: LuxPowerTek Battery Percentage Level Notification
description: LuxPowerTek Battery Percentage Level Notification
trigger:
  - platform: template
    value_template: |
      {{ states('sensor.battery_level') | int(default=-1) % 10 == 0 }}
condition:
  - condition: time
    after: "08:00:00"
    before: "21:00:00"
action:
  - service: notify.notify
    data:
      message: LuxPowerTek Battery % is {{ states("sensor.lux_battery") }}
      title: LuxPowerTek Battery
mode: single

I noticed in your example had a > after the value template, but when I add that it replaces it with a pipe (|)

For HA purposes, | and > are interchangeable as multi-line quote designators.

The trigger really only has two things that would explain a lack of firing.

  1. Your sensor’s entity ID isn’t actually sensor.battery_level.

  2. The state passed the multiple of 10 without actually settling on a multiple of 10… i.e. it dropped from 91 to 89. You can modify the template to insure reliability in this regard, at the cost of some accuracy. The next-most accurate variation would be:

value_template: |
  {% set x = states('sensor.battery_level') | int %}
  {{ (2 * (x / 2)|round(0, 'floor')) % 10 == 0 }}

If that doesn’t work for your case you can take it a step further:

value_template: |
  {% set x = states('sensor.battery_level') | int %}
  {{ (5 * (x / 5)|round) % 10 == 0 }}

Thanks so much. I have it working. I really should stop copying your example and not changing the sensor name!! I was doubtful that the battery could discharge so fast to miss the 10%, but you never now. I set up both examples and they both worked. As you said, the last one is not as accurate, but it was only 1% out. The 10% version is spot on, thanks so much. In case it helps others below are both versions.

alias: LuxPowerTek Battery Percentage Level Notification
description: LuxPowerTek Battery Percentage Level Notification
trigger:
  - platform: template
    value_template: |
      {{ states('sensor.lux_battery') | int(default=-1) % 10 == 0 }}
condition:
  - condition: time
    after: "07:00:00"
    before: "21:00:00"
action:
  - service: notify.notify
    data:
      message: LuxPowerTek Battery % is {{ states("sensor.lux_battery") }}
      title: LuxPowerTek Battery Level
mode: single
alias: LuxPowerTek Battery Percentage Level Notification 2
description: LuxPowerTek Battery Percentage Level Notification 2
trigger:
  - platform: template
    value_template: |
      {% set x = states('sensor.lux_battery') | int %}
      {{ (2 * (x / 2)|round(0, 'floor')) % 10 == 0 }}
condition:
  - condition: time
    after: "07:00:00"
    before: "21:00:00"
action:
  - service: notify.notify
    data:
      message: LuxPowerTek Battery % is {{ states("sensor.lux_battery") }}
      title: LuxPowerTek Battery Level 2
mode: single

Hi,

I have a Shelly plug connected to our fridge and I need an automation that sends a notification as soon as the power consumption increases by 10 for longer than 60 seconds (because the door sometimes doesn´t shut completely).

At the moment I have the following automation, that uses a fixed value of >55.

alias: Kuehlschrank_Audio
description: ""
trigger:
  - platform: numeric_state
    entity_id: sensor.shelly_stecker_5_power
    for:
      hours: 0
      minutes: 1
      seconds: 0
    above: 55
condition: []
action:
  - service: tts.google_translate_say
    data:
      cache: false
      entity_id: media_player.box
      message: KĂĽhlschranktĂĽr ist auf!
  - repeat:
      until:
        - condition: numeric_state
          entity_id: sensor.shelly_stecker_5_power
          below: "55"
      sequence:
        - service: tts.google_translate_say
          data:
            cache: false
            entity_id: media_player.box
            message: KĂĽhlschranktĂĽr ist auf!
        - wait_template: "{{ is_state('media_player.box', 'idle') }}"
mode: single

Thank you!

Hi, I’m trying to calculate 90% of the peak power in a numeric state.

If I put this in the template editor. It spits out the correct value

"{{ states("sensor.p1_meter_66_peak_demand_current_month") | int / 0.9 }}"

But when i put it inside the numeric state it does not work.
I also tried this.

platform: numeric_state
entity_id:
  - sensor.p1_meter_66_active_power
above: "{{ state.sensor.p1_meter_66_peak_demand_current_month | int / 0.9 }}"
for: "00:02:00"

Without any luck, can someone spot my mistake? :slight_smile:

You cannot use templates everywhere… if you want to trigger based on your template I would suggest using a Template trigger:

  trigger:
    - platform: template
      value_template: |
        {{  states("sensor.p1_meter_66_active_power")|float(0) >
        states("sensor.p1_meter_66_peak_demand_current_month") | int / 0.9 }}
      for: "00:02:00"

You could also use the value_template option in a Numeric state trigger, but the setup for this option is less straight-forward than the simple greater-than of the template trigger.

  trigger:
    - platform: numeric_state
      entity_id: sensor.p1_meter_66_active_power
      value_template: |
        {{ state.state|float(0) - (states("sensor.p1_meter_66_peak_demand_current_month") | int / 0.9) }}
      above: 0
      for: "00:02:00"
1 Like