Automation to record peak power - stopping short

Hello, newbie here, so please be gentle. I have spent quite some time putting together an automation to record peak power for various items. This seems to work, to a degree. So, I have the installed code below which seems to trigger when it should and to increase the value as I’d expect. However, it seems stuck at a lower value. That is, it rose to around 35W but when I started the dishwasher running and it exceeded 2000W, it stayed stuck at the lower value. I suspect that it’s something to do with rounding etc, but I can’t see what,

- id: '1644321547640'
  alias: Store dishwasher peak power
  description: Calculate and store dishwasher peak power in input_value to survive
    a reboot
  trigger:
  - platform: state
    entity_id: sensor.dishwasher_power
  condition:
  - condition: numeric_state
    entity_id: sensor.dishwasher_power
    above: input_number.dishwasher_peak_power
  action:
  - service: input_number.set_value
    data:
      value: '{{ trigger.to_state.state | float(0) | round(3) }}'
    target:
      entity_id: input_number.dishwasher_peak_power

Any advice would be gratefully received.

I think this looks correct. I can’t understand why it does not work.

Can you post the graph history of the dishwasher_power?
Does the logs say anything?
The traces?

This is the graph which clearly shows the rise. I was also watching the entity as the dishwasher started and it was seen “live” too. It just didn’t push up the recorded value as I’d expected.

Ah-ha! I now see what’s wrong, I think:

2022-09-13 11:03:52.903 ERROR (MainThread) [homeassistant.components.automation.store_dishwasher_peak_power] Store dishwasher peak power: Error executing script. Invalid data for call_service at pos 1: Invalid value for input_number.dishwasher_peak_power: 2293.8 (range 0.0 - 1000.0)

When I came across the code, I did wonder what the 1000 meant. It now makes sense. My number was just too big, I think?

Thank you very much for your swift response.

If you’re interested, you can use a Trigger-based Template Sensor to report the peak power value.

template:
  - trigger:
      - platform: state
        entity_id: sensor.dishwasher_power
    sensor:
      - name: 'Dishwasher Peak Power'
        unique_id: 'dishwasher_peak_power'
        unit_of_measurement: 'W'
        device_class: power
        state: "{{ [trigger.to_state.state | float(0), this.state | float(0)] | max }}"

But isn’t sensors cleared on restart?

It gets restored after a restart.

From here:

The state, including attributes, of trigger-based sensors and binary sensors is restored when Home Assistant is restarted. The state of other trigger-based template entities is not restored.

Thanks for this. My understanding, though, is that that doesn’t survive a reboot? This was part of my requirement.

I’m also using it on my solar to measure maximum power generation, so this is especially important there.

What led you to that understanding?

My previous post contains an excerpt from the documentation explaining that a Trigger-based Template Sensors’s state (and attributes) is restored after a restart.

I can confirm the documentation is correct because I use a Trigger-based Template Sensor similar to the example I posted above (except it reports maximum daily outdoor temperature).

Simply what I’d read during my research. Much of what I’d read was very contradictory, though, so I’m not at all surprised that I’m wrong.

One other thing which occurs to me, too: presumably it should be possible to create one automation (or trigger) for multiple device’s power and have each increment based on the name of which is triggered? Although (and I must stress that I’m very new to this) does that imply that an automation would be needed in that scenario? That is, I could create a single automation (based on what I have) with multiple triggers and then refer to the triggered entity in the action?

Post a link to some of the research that contradicts the documentation.

I think I know what you’re proposing but I don’t think it leads to a simpler method of recording the highest value of each one of the multiple sensors. Each sensor still needs an Input Number helper to store its peak value. The automation will need some templating to determine which Input Number to update based on which one of multiple entities triggered the automation.

In contrast, a Trigger-based Template Sensor is effectively its own automation and its computed value survives a restart. Plus the resulting sensor entity can have a device_class, unit_of_measurement, etc (not available for Input Number) and its value, unlike an Input Number, can’t be accidentally modified by a user via the UI.

That’s very helpful. Thank you very much. I will look to change the method, I think.

Let me know if you encounter any problems making the change.

It looks not. It seems to be working fine, so thank you very much!

You’re welcome!

If my post above helped solve your problem, please consider marking it with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. This helps users find answers to similar questions.

For more information, refer to guideline 21 in the FAQ.

Done! and thanks once again.

1 Like

Hi,
I tried the same syntax to determine the peak power:

  - trigger:
      - platform: state
        entity_id: sensor.fusionsolar_realtime_power_w
    sensor:
      - name: 'test'
        unique_id: 'test'
        unit_of_measurement: 'W'
        device_class: power
        state: "{{ [trigger.to_state.state | float(0), this.state | float(0)] | max }}"

which works fine,
Now I’d like to reset the peak-value at midnight.

I tried a second trigger platform:time, and tried to use trigger-id’s, but I can’t get it working.

Anybody a solution?

Try this version.

  - trigger:
      - platform: time
        at: '00:00:00'
      - platform: state
        entity_id: sensor.fusionsolar_realtime_power_w
        not_to:
          - 'unavailable' 
          - 'unknown'
    sensor:
      - name: 'test'
        unique_id: 'test'
        unit_of_measurement: 'W'
        device_class: power
        state: >
          {% set p = states('sensor.fusionsolar_realtime_power_w') | float(0) %}
          {{ [p, this.state | float(0)] | max if trigger.platform != 'time' else p }}

EDIT

Correction. Modified how power sensor’s value is retrieved.

1 Like

Thanks a lot, this works perfect!
Using the trigger.platform did the trick.

1 Like

I was too quick…
The reset works fine, but now I got the error:

Logger: homeassistant.helpers.sensor
Source: helpers/trigger_template_entity.py:209
First occurred: 11:16:45 (1 occurrences)
Last logged: 11:16:45

Error rendering state template for sensor.fusionsolar_daypeak: TypeError: '>' not supported between instances of 'int' and 'str'

(the time stap doesn’t correspond with the real first occurrence, as I reloaded and restarted HA already).

I noticed a missing data-type for the trigger.to_state.state compared with the initial template, so I changed to:

  - trigger:
      - platform: time
        at: '00:00:00'
      - platform: state
        entity_id: sensor.fusionsolar_realtime_power_w
        not_to:
          - 'unavailable' 
          - 'unknown'
    sensor:
      - name: 'fusionsolar_daypeak'
        unique_id: 'fusionsolar_daypeak'
        unit_of_measurement: 'W'
        device_class: power
        state: >
          "{{ [trigger.to_state.state | float(0), this.state | float(0)] | max
            if trigger.platform != 'time' else
            states('sensor.fusionsolar_realtime_power_w') | float(0) }}"

Unfortunately, same result.
I also added the " " around the state-template. Same result.

The signal sensor.fusionsolar_realtime_power_w is available and is displayed with the correct value.

However, the logfile reports:

2024-04-11 11:25:46.953 ERROR (MainThread) [homeassistant.helpers.event] Error while dispatching event for sensor.fusionsolar_realtime_power_w to <Job track state_changed event ['sensor.fusionsolar_realtime_power_w'] HassJobType.Callback <function async_attach_trigger.<locals>.state_automation_listener at 0xffff50247ec0>>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 668, in state
    numerical_value = float(value)  # type:ignore[arg-type]
                      ^^^^^^^^^^^^
ValueError: could not convert string to float: '"1317.0"'

and:

ValueError: Sensor sensor.fusionsolar_daypeak has device class 'power', state class 'None' unit 'W' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: '"1317.0"' (<class 'str'>)

(note the double quoting around 1317.0 )

The template sensor itself was defined as:

      - name: "FusionSolar realtime power W"
        device_class: power
        icon: mdi:solar-power
        unit_of_measurement: "W"
        availability: "{{ is_number(states('sensor.ew16_garage_realtime_power')) }}"
        state: "{{ states('sensor.ew16_garage_realtime_power')|float * 1000  }}"
        unique_id: "FusionSolar realtime power W"

I tried removing the quotes around the state template, but that again resulted in an error.

Cannot quick reload all YAML configurations because the configuration is not valid: Error loading /config/configuration.yaml: invalid key: "{"states('sensor.ew16_garage_realtime_power')|float(0) * 1000": None}" in "/config/packages/solarpanels/solarpanels.yaml", line 74, column 0

Anybody?

Sorry about that, I overlooked to include it while redesigning the template. I have modified the example posted above.

It should have eliminated the error message so I am surprised to hear that it didn’t because now both values in the list are converted to floating point numbers so max should have no trouble determining which number is larger.

That’s definitely incorrect because it’s a multi-line template and the double-quotes will be included in the template’s result. You can see that in the error message.

I suggest you try the corrected version posted above.