I have a sensor which shows the state of a charger sensor.charging_system_status
, and it can have a few possible states:
charging_system_charging
charging_system_done
charging_system_fault
charging_system_idle
charging_system_scheduled
charging_system_unspecified
I just want to have a sensor which is “on” if the system is charging (only the first option in the list), and “off” if it is not charging (all others in the list). And then I want these state changes to be pushed to InfluxDB integration.
Attempt #1
First I tried to make a simple trigger-based binary template sensor like this:
- trigger:
- platform: state
entity_id: sensor.charging_system_status
binary_sensor:
- name: "Is Charging"
unique_id: is_charging
device_class: battery_charging
state: >-
{{ trigger.to_state.state == 'charging_system_charging' }}
availability: >-
{{ trigger.to_state.state not in ['unavailable', 'unknown'] }}
This kind of works, but the problem is that when Home Assistant restarts, a state change is fired for sensor.charging_system_status
even if the real value of the state didnt change (i.e. even though the device is physically still charging, the sensor temporarily gets an unknown state during the restart). This leads to sequential duplicate data being inserted into InfluxDB, which I definitely don’t want:
> select * from is_charging
name: is_charging
time domain entity_id state value
---- ------------- ----------- ----- -----
1748280058 binary_sensor is_charging off 0
1748284119 binary_sensor is_charging off 0
1748284254 binary_sensor is_charging on 1
1748284389 binary_sensor is_charging on 1
1748284525 binary_sensor is_charging on 1
1748284660 binary_sensor is_charging off 0
1748284795 binary_sensor is_charging off 0
Attempt #2
So I changed my approach, and used an input boolean helper to store the state, and update its value in an automation instead. This gives me more control to be able to guard against state changes where the real value hasn’t changed. This is my automation:
alias: Toggle Charging Input Boolean
description: "Turn on input boolean if sensor switches to charging, and turn off if it switches to anything else"
triggers:
- trigger: state
entity_id:
- sensor.charging_system_status
id: triggered_by_state_change
- trigger: homeassistant
event: start
id: triggered_by_hass_restart
actions:
- choose:
# TRIGGER IF THE STATE OF SENSOR REALLY CHANGES
- conditions:
- condition: trigger
id: triggered_by_state_change
- condition: template
value_template: >-
{{ trigger.from_state is not none
and trigger.to_state.state != trigger.from_state.state }}
sequence:
- choose:
# IF SYSTEM SWITCHED TO CHARGING, TURN ON BOOLEAN
- conditions:
- condition: template
value_template: "{{ trigger.to_state.state == 'charging_system_charging' }}"
sequence:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.is_charging
# IF SYSTEM SWITCHED FROM CHARGING AND WAS NOT ALREADY CHARGING, TURN OFF BOOLEAN
- conditions:
- condition: template
value_template: >-
{{ trigger.from_state.state == 'charging_system_charging'
and trigger.to_state.state != 'charging_system_charging' }}
sequence:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.is_charging
# CHECK 1 MIN AFTER HASS RESTART IF BOOLEAN NEEDS TO BE UPDATED
- conditions:
- condition: trigger
id: triggered_by_hass_restart
sequence:
- delay:
minutes: 1
# MAKE SURE SENSOR HAS A VALID VALUE
- condition: template
value_template: "{{ states('sensor.charging_system_status') not in ['unknown', 'unavailable'] }}"
- choose:
# IF SYSTEM IS CHARGING AND BOOLEAN WAS NOT ALREADY ON, THEN TURN IT ON
- conditions:
- condition: template
value_template: >-
{{ states('sensor.charging_system_status') == 'charging_system_charging'
and states('input_boolean.is_charging') != 'on' }}
sequence:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.is_charging
# IF SYSTEM IS NOT CHARGING AND BOOLEAN WAS NOT ALREADY OFF, THEN TURN IT OFF
- conditions:
- condition: template
value_template: >-
{{ states('sensor.charging_system_status') != 'charging_system_charging'
and states('input_boolean.is_charging') != 'off' }}
sequence:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.is_charging
As far as I can tell, this seems to work (at least from the testing so far, but maybe I’ve missed something). It doesn’t give duplicate values in the database:
> select * from is_charging
name: is_charging
time domain entity_id state value
---- ------ --------- ----- -----
1748341910 input_boolean is_charging on 1
1748342027 input_boolean is_charging off 0
1748342059 input_boolean is_charging on 1
1748342161 input_boolean is_charging off 0
This automation is pretty complicated logic for something that I would think is quite basic. So I want to know is there a simpler way to get this behaviour (either with automations and helper booleans, or template sensors).
My requirements are just:
- Insert a value in the InfluxDB database only when there is a real change of the sensor to/from charging to not charging.
- Don’t duplicate values on restart
- Make sure the entity reflects the true state (i.e. in the automation above, I am guarding against the case where the state of the charging system really changed whilst Home Assistant was down during a restart. Therefore, I always check 1 minute after restart if the input boolean needs updating).
Hoping to learn something here, so any ideas welcome. Thanks.