260 lines
10 KiB
YAML
260 lines
10 KiB
YAML
#:########################################################################################:#
|
|
# Package: BYD Charging Schedule At Home
|
|
# File: byd_charging_schedule_athome.yaml
|
|
# Version: v1.1.0
|
|
# Date: 2026-07-23
|
|
#
|
|
# Purpose:
|
|
# Enables the BYD Atto 3 charging schedule when the car arrives home.
|
|
# Disables the schedule only after the car has been confirmed away for a
|
|
# configurable delay, to avoid rapid toggling from uncertain presence detection.
|
|
#
|
|
# Behaviour:
|
|
# - Confirmed arrival home:
|
|
# Sets the schedule to 9:00 PM through midnight with charge-to-full disabled,
|
|
# enables it, and retries cloud reconciliation once per minute.
|
|
#
|
|
# - Confirmed away:
|
|
# After away_confirm_minutes, disables the schedule and retries cloud
|
|
# reconciliation once per minute.
|
|
#
|
|
# - Manual control:
|
|
# If the car is already home and the user or another HA automation turns
|
|
# the schedule OFF manually, this package will not turn it back ON unless
|
|
# the car is later confirmed away and then arrives home again.
|
|
#
|
|
# Notes:
|
|
# - Home Assistant usually stores the device_tracker home state as "home",
|
|
# even if the UI displays "At Home".
|
|
# - Change away_confirm_minutes below if you want a longer/shorter debounce.
|
|
#:########################################################################################:#
|
|
|
|
input_boolean:
|
|
byd_atto3_charging_schedule_confirmed_away:
|
|
name: "BYD Atto 3 Charging Schedule - Confirmed Away"
|
|
icon: mdi:car-off
|
|
|
|
automation:
|
|
#:######################################################################################:#
|
|
# ARRIVAL - Reconcile and enable schedule after a confirmed away period
|
|
#:######################################################################################:#
|
|
- id: byd_atto3_charging_schedule_arrival_enable
|
|
alias: "BYD Atto 3 Charging Schedule - Arrival Enable"
|
|
description: >
|
|
Reconciles the BYD charging schedule to 9:00 PM through midnight and turns
|
|
it ON when the car arrives home after a confirmed away period. Rechecks the
|
|
cloud-confirmed state once per minute and retries failed updates.
|
|
mode: single
|
|
variables: &byd_charging_schedule_vars
|
|
tracker_entity: device_tracker.byd_atto3_ibeacon_bur4c2a_bermuda_tracker
|
|
schedule_switch_entity: switch.atto_3_schedule_enabled
|
|
schedule_start_time_entity: time.atto_3_start_time
|
|
schedule_end_time_entity: time.atto_3_end_time
|
|
schedule_charge_to_full_entity: switch.atto_3_charge_to_full
|
|
|
|
# HA normally stores "At Home" as "home".
|
|
home_state: "home"
|
|
|
|
# Required charging schedule settings.
|
|
expected_start_time: "21:00:00"
|
|
expected_end_time: "00:00:00"
|
|
|
|
# Adjustable YAML-only delay before the car is treated as truly away.
|
|
away_confirm_minutes: 10
|
|
|
|
# Verify cloud-confirmed schedule state at one-minute intervals.
|
|
schedule_verify_attempts: 6
|
|
schedule_verify_interval: "00:01:00"
|
|
|
|
# These states will not be treated as confirmed away.
|
|
ignored_tracker_states:
|
|
- "unknown"
|
|
- "unavailable"
|
|
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: device_tracker.byd_atto3_ibeacon_bur4c2a_bermuda_tracker
|
|
|
|
conditions:
|
|
- condition: template
|
|
value_template: >-
|
|
{{ trigger.to_state is not none
|
|
and trigger.from_state is not none
|
|
and trigger.to_state.state == home_state
|
|
and trigger.from_state.state == 'not_home' }}
|
|
|
|
actions:
|
|
- choose:
|
|
- conditions:
|
|
- condition: state
|
|
entity_id: input_boolean.byd_atto3_charging_schedule_confirmed_away
|
|
state: "on"
|
|
sequence:
|
|
- action: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.byd_atto3_charging_schedule_confirmed_away
|
|
|
|
- repeat:
|
|
count: "{{ schedule_verify_attempts | int(6) }}"
|
|
sequence:
|
|
- if:
|
|
- condition: template
|
|
value_template: "{{ is_state(tracker_entity, home_state) }}"
|
|
then:
|
|
- if:
|
|
- condition: template
|
|
value_template: >-
|
|
{{ states(schedule_start_time_entity) != expected_start_time }}
|
|
then:
|
|
- action: time.set_value
|
|
continue_on_error: true
|
|
target:
|
|
entity_id: "{{ schedule_start_time_entity }}"
|
|
data:
|
|
time: "{{ expected_start_time }}"
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: >-
|
|
{{ states(schedule_end_time_entity) != expected_end_time }}
|
|
then:
|
|
- action: time.set_value
|
|
continue_on_error: true
|
|
target:
|
|
entity_id: "{{ schedule_end_time_entity }}"
|
|
data:
|
|
time: "{{ expected_end_time }}"
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: >-
|
|
{{ not is_state(schedule_charge_to_full_entity, 'off') }}
|
|
then:
|
|
- action: switch.turn_off
|
|
continue_on_error: true
|
|
target:
|
|
entity_id: "{{ schedule_charge_to_full_entity }}"
|
|
|
|
- if:
|
|
- condition: template
|
|
value_template: >-
|
|
{{ not is_state(schedule_switch_entity, 'on') }}
|
|
then:
|
|
- action: switch.turn_on
|
|
continue_on_error: true
|
|
target:
|
|
entity_id: "{{ schedule_switch_entity }}"
|
|
|
|
- delay: "{{ schedule_verify_interval }}"
|
|
|
|
#:######################################################################################:#
|
|
# DEPARTURE - Disable schedule after confirmed away timeout
|
|
#:######################################################################################:#
|
|
- id: byd_atto3_charging_schedule_departure_disable_after_timeout
|
|
alias: "BYD Atto 3 Charging Schedule - Departure Disable After Timeout"
|
|
description: >
|
|
When the car leaves home, waits for the configured away timeout. If the car
|
|
is still away, marks it confirmed away, turns the BYD charging schedule OFF,
|
|
and retries failed cloud updates once per minute.
|
|
mode: restart
|
|
variables: *byd_charging_schedule_vars
|
|
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: device_tracker.byd_atto3_ibeacon_bur4c2a_bermuda_tracker
|
|
|
|
conditions:
|
|
- condition: template
|
|
value_template: >-
|
|
{% set new_state = trigger.to_state.state if trigger.to_state is not none else '' %}
|
|
{{ new_state != home_state
|
|
and new_state not in ignored_tracker_states }}
|
|
|
|
actions:
|
|
- delay:
|
|
minutes: "{{ away_confirm_minutes | int(10) }}"
|
|
|
|
- condition: template
|
|
value_template: >-
|
|
{% set current_state = states(tracker_entity) %}
|
|
{{ current_state != home_state
|
|
and current_state not in ignored_tracker_states }}
|
|
|
|
- action: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.byd_atto3_charging_schedule_confirmed_away
|
|
|
|
- repeat:
|
|
count: "{{ schedule_verify_attempts | int(6) }}"
|
|
sequence:
|
|
- if:
|
|
- condition: template
|
|
value_template: >-
|
|
{% set current_state = states(tracker_entity) %}
|
|
{{ current_state != home_state
|
|
and current_state not in ignored_tracker_states
|
|
and not is_state(schedule_switch_entity, 'off') }}
|
|
then:
|
|
- action: switch.turn_off
|
|
continue_on_error: true
|
|
target:
|
|
entity_id: "{{ schedule_switch_entity }}"
|
|
|
|
- delay: "{{ schedule_verify_interval }}"
|
|
|
|
#:######################################################################################:#
|
|
# STARTUP SAFETY - If HA restarts while the car is away, re-arm arrival logic
|
|
#:######################################################################################:#
|
|
- id: byd_atto3_charging_schedule_startup_away_check
|
|
alias: "BYD Atto 3 Charging Schedule - Startup Away Check"
|
|
description: >
|
|
On Home Assistant startup, if the car is already away and remains away
|
|
beyond the configured timeout, mark it confirmed away and reconcile the
|
|
charging schedule OFF so the next confirmed arrival can enable it.
|
|
mode: single
|
|
variables: *byd_charging_schedule_vars
|
|
|
|
triggers:
|
|
- trigger: homeassistant
|
|
event: start
|
|
|
|
actions:
|
|
- delay: "00:01:00"
|
|
|
|
- condition: template
|
|
value_template: >-
|
|
{% set current_state = states(tracker_entity) %}
|
|
{{ current_state != home_state
|
|
and current_state not in ignored_tracker_states }}
|
|
|
|
- delay:
|
|
minutes: "{{ away_confirm_minutes | int(10) }}"
|
|
|
|
- condition: template
|
|
value_template: >-
|
|
{% set current_state = states(tracker_entity) %}
|
|
{{ current_state != home_state
|
|
and current_state not in ignored_tracker_states }}
|
|
|
|
- action: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.byd_atto3_charging_schedule_confirmed_away
|
|
|
|
- repeat:
|
|
count: "{{ schedule_verify_attempts | int(6) }}"
|
|
sequence:
|
|
- if:
|
|
- condition: template
|
|
value_template: >-
|
|
{% set current_state = states(tracker_entity) %}
|
|
{{ current_state != home_state
|
|
and current_state not in ignored_tracker_states
|
|
and not is_state(schedule_switch_entity, 'off') }}
|
|
then:
|
|
- action: switch.turn_off
|
|
continue_on_error: true
|
|
target:
|
|
entity_id: "{{ schedule_switch_entity }}"
|
|
|
|
- delay: "{{ schedule_verify_interval }}"
|