Refactor automation configurations and enhance documentation

- Updated guest_mode.yaml to clarify guest mode announcements and added a related issue reference.
- Enhanced night_watchdog.yaml with additional conditions for vacation mode and house sitter presence.
- Improved sunset_turn_on.yaml by refining action sequences and adding vacation presence logic.
- Expanded admin_sections.yaml to include new tiles for front door package detection and related inputs.
- Removed obsolete media player from media_players.yaml and updated switches.yaml to reflect new outdoor seasonal switch IDs.
- Enhanced home_modes.yaml and README.md to clarify home mode toggles and their usage.
- Updated docker_infrastructure.yaml to improve container outage notifications and streamline maintenance checks.
- Enhanced LLM Vision package to include front door package detection and related automation triggers.
closed https://github.com/CCOSTAN/Home-AssistantConfig/issues/793
feature/powerwall-live-activity-1598
Carlo Costanzo 4 days ago
parent 7dcc7e024d
commit 4457dc0bcd

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

@ -1,16 +1,13 @@
#-------------------------------------------
# Guest Mode Announcements
# Description: Manages audio announcements for guest mode activation and deactivation
#
# Features:
# - Announces when guest mode is enabled
# - Provides weather summary for guests
# - Resets guest mode when family returns home
#
# Integration: Uses speech_engine script for announcements
# uses ChromeCast for audio output
# Follow me on https://www.vcloudinfo.com/click-here
#-------------------------------------------
######################################################################
# @CCOSTAN - Follow Me on X
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Guest Mode Speech - guest arrival/departure announcements.
# Announces guest-mode changes without mixing in vacation/house-sitter logic.
# -------------------------------------------------------------------
# Related Issue: 793
######################################################################
- alias: 'Guest Mode Audio Feedback'
id: 3622ba04-9a28-4c02-807c-be4abc663fe0

@ -29,6 +29,14 @@
- condition: state
entity_id: input_boolean.guest_mode
state: 'off'
- condition: and
conditions:
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'off'
- condition: and
conditions:
- condition: state

@ -22,10 +22,32 @@
action:
- delay: '00:{{ (range(1, 20)|random|int) }}:00'
- service: script.speech_engine
data:
call_dark_outside: 1
call_window_check: 1
- variables:
vacation_presence_delay_minutes: "{{ 90 + (range(15, 31) | random | int) }}"
vacation_presence_runtime_minutes: "{{ 240 + (range(15, 31) | random | int) }}"
vacation_presence_delay: >-
{{ '%02d:%02d:00' | format((vacation_presence_delay_minutes | int) // 60, (vacation_presence_delay_minutes | int) % 60) }}
vacation_presence_runtime: >-
{{ '%02d:%02d:00' | format((vacation_presence_runtime_minutes | int) // 60, (vacation_presence_runtime_minutes | int) % 60) }}
vacation_presence_switch: >-
{{ 'switch.office_accent' if (range(0, 2) | random | int) == 0 else 'switch.front_office_lamp' }}
vacation_presence_light: >-
{{ 'light.upstairs_lamp' if (range(0, 2) | random | int) == 0 else 'light.ikea_1' }}
- choose:
- conditions:
- condition: or
conditions:
- condition: state
entity_id: group.family
state: 'home'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'on'
sequence:
- service: script.speech_engine
data:
call_dark_outside: 1
call_window_check: 1
- service: homeassistant.turn_on
entity_id:
- switch.front_landscaping
@ -40,25 +62,143 @@
brightness: >
{% if states.group.family.state == 'home' -%}
10
{% elif is_state('input_boolean.vacation_mode', 'on') and is_state('input_boolean.house_sitter_present', 'off') -%}
35
{% else %}
150
{% endif %}
- wait_template: >-
{{ states.group.family.state == 'home' }}
- service: homeassistant.turn_on
entity_id:
- group.master_bathroom_accents
- switch.back_landscaping
- switch.front_door_outlet
- switch.foyer_outlet
- switch.den_outlet
- switch.front_office_lamp
- switch.office_accent
- switch.living_room_outlet
- switch.living_room_tv_outlet
- service: light.turn_on
entity_id:
- light.living_room_accents
- light.upstairs_lamp
- light.ikea_1 #Upstairs Hallyway switchoutlet.
- choose:
- conditions:
- condition: state
entity_id: input_boolean.vacation_mode
state: 'off'
sequence:
- wait_template: >-
{{ states.group.family.state == 'home' }}
- service: homeassistant.turn_on
entity_id:
- group.master_bathroom_accents
- switch.back_landscaping
- switch.front_door_outlet
- switch.foyer_outlet
- switch.den_outlet
- switch.front_office_lamp
- switch.office_accent
- switch.living_room_outlet
- switch.living_room_tv_outlet
- service: light.turn_on
entity_id:
- light.living_room_accents
- light.upstairs_lamp
- light.ikea_1 #Upstairs Hallyway switchoutlet.
- conditions:
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'on'
sequence:
- service: homeassistant.turn_on
entity_id:
- group.master_bathroom_accents
- switch.back_landscaping
- switch.front_door_outlet
- switch.foyer_outlet
- switch.den_outlet
- switch.front_office_lamp
- switch.office_accent
- switch.living_room_outlet
- switch.living_room_tv_outlet
- service: light.turn_on
entity_id:
- light.living_room_accents
- light.upstairs_lamp
- light.ikea_1 #Upstairs Hallyway switchoutlet.
- conditions:
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'off'
sequence:
- delay: "{{ vacation_presence_delay }}"
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'off'
- choose:
- conditions:
- condition: template
value_template: "{{ vacation_presence_switch == 'switch.office_accent' }}"
sequence:
- service: homeassistant.turn_on
entity_id:
- switch.front_door_outlet
- switch.foyer_outlet
- switch.living_room_outlet
- switch.office_accent
default:
- service: homeassistant.turn_on
entity_id:
- switch.front_door_outlet
- switch.foyer_outlet
- switch.living_room_outlet
- switch.front_office_lamp
- choose:
- conditions:
- condition: template
value_template: "{{ vacation_presence_light == 'light.upstairs_lamp' }}"
sequence:
- service: light.turn_on
entity_id:
- light.living_room_accents
- light.upstairs_lamp
default:
- service: light.turn_on
entity_id:
- light.living_room_accents
- light.ikea_1
- delay: "{{ vacation_presence_runtime }}"
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'off'
- choose:
- conditions:
- condition: template
value_template: "{{ vacation_presence_switch == 'switch.office_accent' }}"
sequence:
- service: homeassistant.turn_off
entity_id:
- switch.front_door_outlet
- switch.foyer_outlet
- switch.living_room_outlet
- switch.office_accent
default:
- service: homeassistant.turn_off
entity_id:
- switch.front_door_outlet
- switch.foyer_outlet
- switch.living_room_outlet
- switch.front_office_lamp
- choose:
- conditions:
- condition: template
value_template: "{{ vacation_presence_light == 'light.upstairs_lamp' }}"
sequence:
- service: light.turn_off
entity_id:
- light.living_room_accents
- light.upstairs_lamp
default:
- service: light.turn_off
entity_id:
- light.living_room_accents
- light.ikea_1

@ -25,6 +25,16 @@
entity: update.llm_vision_update
- type: tile
entity: input_button.llmvision_garbage_check
- type: tile
entity: binary_sensor.front_door_packages_present
- type: tile
entity: input_text.llmvision_front_door_last_response
- type: tile
entity: input_datetime.llmvision_front_door_last_run
- type: tile
entity: input_text.llmvision_front_door_last_keyframe
- type: tile
entity: input_button.llmvision_front_door_package_check
- type: grid
cards:
- type: markdown

@ -26,7 +26,6 @@ media_players:
- media_player.master_bathroom
tvs:
entities:
- media_player.samsung_q70_series_65
- media_player.carlo_s_samsung_tv_2020_q
- media_player.fireplaceroku
- media_player.living_room_ultra

@ -1,10 +1,13 @@
#-------------------------------------------
# Switches Configuration
# Description: Groups and organizes various switches in the home
#
# Original Repository: https://github.com/CCOSTAN/Home-AssistantConfig
# Follow me on https://www.vcloudinfo.com/click-here
#-------------------------------------------
######################################################################
# @CCOSTAN - Follow Me on X
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Switch Groups - Grouped indoor and seasonal switch helpers
# Keep grouped entity IDs aligned with active switch entities.
# -------------------------------------------------------------------
# Notes: Replaced legacy holiday switch IDs that no longer exist.
######################################################################
Interior Switches:
entities:
@ -34,10 +37,9 @@ Master Bathroom Accents:
- switch.master_bathroom_accent_2
Outdoor Seasonal:
- switch.xmas1
- switch.xmas2
- switch.xmas3
- switch.xmas4
- switch.xmas_dual_outlet_1
- switch.xmas_dual_outlet_2
- switch.outdoor_xmas
- switch.outdoor_xmas_2_socket_1
- switch.outdoor_xmas_2_socket_2
- switch.outdoor_xmas_2_socket_3
- switch.outdoor_xmas_right_socket
- switch.xmas_dual_outlet_switch_1
- switch.xmas_dual_outlet_switch_2

@ -26,7 +26,7 @@ Mode and trigger toggles that drive automations (guest mode, parties, presence o
### Featured files to browse
| File | Why it matters |
| --- | --- |
| [home_modes.yaml](home_modes.yaml) | Guest, vacation, and quiet-mode toggles. |
| [home_modes.yaml](home_modes.yaml) | Guest, alert, and notification toggles used across automations. |
| [trigger_booleans.yaml](trigger_booleans.yaml) | One-off toggles used as automation guards. |
| [hidden_booleans.yaml](hidden_booleans.yaml) | Back-end toggles tucked away from the UI. |

@ -1,3 +1,13 @@
######################################################################
# @CCOSTAN - Follow Me on X
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Home Modes - occupancy and alert toggles for major house behaviors.
# Guest, alert, and notification modes used by automations/scripts.
# -------------------------------------------------------------------
######################################################################
guest_mode:
name: Guest Mode
icon: mdi:account-alert

@ -56,6 +56,7 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this
| [telegram_bot.yaml](telegram_bot.yaml) | Telegram script wrappers used by BearClaw and other ops flows (UI integration remains the source for bot config). | `script.joanna_send_telegram`, `telegram_bot.send_message` |
| [phynplus.yaml](phynplus.yaml) | Phyn shutoff automations with push + Activity feed + Repairs issues for leak events. | `valve.phyn_shutoff_valve`, `binary_sensor.phyn_leak_test_running`, `repairs.create` |
| [water_delivery.yaml](water_delivery.yaml) | ReadyRefresh delivery date helper with night-before + garage door Alexa reminders, plus helper-change audit logging and Telegram confirmations. | `input_datetime.water_delivery_date`, `script.send_to_logbook`, `script.joanna_send_telegram`, `notify.alexa_media_garage` |
| [vacation_mode.yaml](vacation_mode.yaml) | Auto-enable vacation mode after 24 hours away or no bed use, track sitter analytics/secure-house checks, and deliver Chromecast-first vacation briefings with a garage Alexa welcome. | `input_boolean.vacation_mode`, `input_boolean.house_sitter_present`, `sensor.vacation_house_sitter_*`, `group.garage_doors`, `lock.front_door`, `script.notify_engine`, `script.joanna_send_telegram` |
| [maintenance_log.yaml](maintenance_log.yaml) | Joanna maintenance webhook ingest for water softener salt with idempotent event handling, Activity feed logging, and recorder-backed helper history for long-term graphing. | `automation.maintenance_log_joanna_webhook_ingest`, `input_number.water_softener_salt_total_added_lb`, `counter.water_softener_salt_event_count`, `sensor.water_softener_salt_days_since_last_add` |
| [powerwall.yaml](powerwall.yaml) | Track Tesla Powerwall grid status and shed loads automatically when off-grid (alerts include Activity feed + Repairs). | `binary_sensor.powerwall_grid_status`, `sensor.powerwall_*`, `repairs.create` |
| [vacuum.yaml](vacuum.yaml) | Dreame vacuum orchestration with room tracking, push alerts, Activity feed, Repairs issues on errors, and Alexa one-off room-clean switches. | `input_select.l10s_vacuum_phase`, `sensor.l10s_vacuum_error`, `repairs.create` |

@ -930,14 +930,19 @@ automation:
- condition: state
entity_id: binary_sensor.docker_container_alerts_snoozed
state: "off"
- condition: template
value_template: >-
{% set down_items = state_attr('sensor.docker_containers_down_list', 'down_containers') | default([], true) | list %}
{{ down_items | count > 3 }}
action:
- variables:
down_items: "{{ state_attr('sensor.docker_containers_down_list', 'down_containers') | default([], true) | list }}"
down_count: "{{ down_items | count }}"
- service: script.notify_engine_two_button
data:
title: "Docker Maintenance Check"
value1: "{{ states('sensor.docker_containers_down_count') }} containers are currently down."
value2: >-
{% set down_items = state_attr('sensor.docker_containers_down_list', 'down_containers') | default([], true) | list %}
Down: {{ down_items | join(', ') if (down_items | count > 0) else 'none' }}
value1: "{{ down_count }} containers are currently down."
value2: "Down: {{ down_items | join(', ') if (down_count | int(0) > 0) else 'none' }}"
who: "carlo"
group: "maintenance"
title1: "Yes, snooze 1h"
@ -949,10 +954,7 @@ automation:
- service: script.send_to_logbook
data:
topic: "DOCKER"
message: >-
Maintenance prompt sent to Carlo ({{ states('sensor.docker_containers_down_count') }} down:
{% set down_items = state_attr('sensor.docker_containers_down_list', 'down_containers') | default([], true) | list %}
{{ down_items | join(', ') if (down_items | count > 0) else 'none' }}).
message: "Maintenance prompt sent to Carlo ({{ down_count }} down: {{ down_items | join(', ') if (down_count | int(0) > 0) else 'none' }})."
- alias: "Docker Maintenance Snooze 1H"
id: docker_maintenance_snooze_1h
@ -986,14 +988,13 @@ automation:
event_data:
action: DOCKER_MAINTENANCE_NOT_MAINTENANCE
action:
- variables:
down_items: "{{ state_attr('sensor.docker_containers_down_list', 'down_containers') | default([], true) | list }}"
down_count: "{{ down_items | count }}"
- service: script.send_to_logbook
data:
topic: "DOCKER"
message: >-
Maintenance snooze declined with {{ states('sensor.docker_containers_down_count') }}
containers down (
{% set down_items = state_attr('sensor.docker_containers_down_list', 'down_containers') | default([], true) | list %}
{{ down_items | join(', ') if (down_items | count > 0) else 'none' }}).
message: "Maintenance snooze declined with {{ down_count }} containers down ({{ down_items | join(', ') if (down_count | int(0) > 0) else 'none' }})."
- alias: "Docker Telemetry Template Refresh"
id: docker_telemetry_template_refresh

@ -374,9 +374,10 @@ automation:
data:
title: 'Check Garage Doors:'
value1: >
{% set open = [] %}
{% if is_state('cover.small_garage_door','open') %}{% set _ = open.append('Small garage door') %}{% endif %}
{% if is_state('cover.large_garage_door','open') %}{% set _ = open.append('Large garage door') %}{% endif %}
{% set open = [
'Small garage door' if is_state('cover.small_garage_door', 'open') else '',
'Large garage door' if is_state('cover.large_garage_door', 'open') else ''
] | reject('eq', '') | list %}
{% if open|length == 0 %}
All garage doors are closed.
{% elif open|length == 1 %}

@ -3,10 +3,11 @@
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# LLM Vision - Garage Cans X Check - detects reflective X on right wall
# Trigger with input_button.llmvision_garbage_check to update garbage_cans_out.
# LLM Vision - garage cans and front-door package checks
# Trigger with input_button.llmvision_garbage_check, input_button.llmvision_front_door_package_check, or front door person activity to update vision-backed package sensors.
# -------------------------------------------------------------------
# Notes: LLMVision analyzes camera.garagecam; expects strict "on"/"off" output.
# Notes: Front-door package detection runs 3 minutes after `sensor.frontdoorbell_person_active_count_2` goes above 0.
# Docs: https://llmvision.gitbook.io/getting-started/usage/image-analyzer
######################################################################
@ -14,11 +15,17 @@ input_button:
llmvision_garbage_check:
name: "LLM Vision: Garage cans check"
icon: mdi:delete-variant
llmvision_front_door_package_check:
name: "LLM Vision: Front door package check"
icon: mdi:package-variant-closed-check
input_boolean:
garbage_cans_out:
name: "Garbage Cans Out"
icon: mdi:trash-can
front_door_packages_present:
name: "Front Door Packages Present"
icon: mdi:package-variant-closed
input_text:
llmvision_garbage_last_response:
@ -27,12 +34,22 @@ input_text:
llmvision_garbage_last_keyframe:
name: "LLM Vision garage key frame"
max: 255
llmvision_front_door_last_response:
name: "LLM Vision front door response"
max: 255
llmvision_front_door_last_keyframe:
name: "LLM Vision front door key frame"
max: 255
input_datetime:
llmvision_garbage_last_run:
name: "LLM Vision garage last run"
has_date: true
has_time: true
llmvision_front_door_last_run:
name: "LLM Vision front door last run"
has_date: true
has_time: true
template:
- binary_sensor:
@ -46,6 +63,16 @@ template:
last_key_frame: "{{ states('input_text.llmvision_garbage_last_keyframe') }}"
source_camera: camera.garagecam
- name: "Front Door Packages Present"
unique_id: llmvision_front_door_packages_present
device_class: presence
state: "{{ is_state('input_boolean.front_door_packages_present', 'on') }}"
attributes:
last_run: "{{ states('input_datetime.llmvision_front_door_last_run') }}"
last_response: "{{ states('input_text.llmvision_front_door_last_response') }}"
last_key_frame: "{{ states('input_text.llmvision_front_door_last_keyframe') }}"
source_camera: camera.frontdoorbell
automation:
- alias: LLM Vision - Garbage cans out
id: d88a2e6d-78f3-4bb7-9d9f-c4d06e6eb5a9
@ -94,3 +121,111 @@ automation:
entity_id: input_datetime.llmvision_garbage_last_run
data:
datetime: "{{ now() }}"
- alias: LLM Vision - Front door packages
id: 8647b555-7ba0-41d5-98de-cfd3094e5b4f
mode: restart
trigger:
- platform: numeric_state
entity_id: sensor.frontdoorbell_person_active_count_2
above: 0
for: "00:03:00"
id: person_count
- platform: state
entity_id: input_button.llmvision_front_door_package_check
id: manual_check
variables:
prompt_text: >-
Examine the front door camera image for delivery packages. Focus only on boxes, padded envelopes,
or shopping bags left on the porch or by the front door. If one or more packages are clearly visible,
respond exactly: on. If no packages are clearly visible, respond exactly: off. No other words.
action:
- service: llmvision.data_analyzer
response_variable: llmvision_result
data:
provider: !secret llmvision_provider_entry
model: gpt-4.1-nano
message: "{{ prompt_text }}"
sensor_entity: input_boolean.front_door_packages_present
image_entity:
- camera.frontdoorbell
include_filename: false
target_width: 1280
max_tokens: 16
expose_images: true
- service: input_text.set_value
target:
entity_id: input_text.llmvision_front_door_last_response
data:
value: "{{ (llmvision_result.response_text | default('unknown'))[:250] }}"
- choose:
- conditions: "{{ llmvision_result is defined and llmvision_result.key_frame is defined }}"
sequence:
- service: input_text.set_value
target:
entity_id: input_text.llmvision_front_door_last_keyframe
data:
value: "{{ llmvision_result.key_frame }}"
default:
- service: input_text.set_value
target:
entity_id: input_text.llmvision_front_door_last_keyframe
data:
value: ""
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.llmvision_front_door_last_run
data:
datetime: "{{ now() }}"
- service: script.send_to_logbook
data:
topic: PACKAGES
message: >-
Front door package vision check ran via {{ 'manual button' if trigger.id == 'manual_check' else 'front door person activity' }}
and returned {{ llmvision_result.response_text | default(states('input_boolean.front_door_packages_present')) | lower }}.
- choose:
- conditions:
- condition: template
value_template: "{{ trigger.id == 'manual_check' }}"
sequence:
- service: script.notify_engine
data:
title: Front door package test
value1: >-
LLM Vision returned {{ llmvision_result.response_text | default(states('input_boolean.front_door_packages_present')) | lower }}
for the front door package check.
who: carlo
group: information
level: active
camera_entity: camera.frontdoorbell
- alias: LLM Vision - Front door package notify
id: 0ddf0fb5-4600-4eff-9236-95b2af3739a6
mode: restart
trigger:
- platform: state
entity_id: input_boolean.front_door_packages_present
to: 'on'
for: "00:01:00"
action:
- variables:
package_message: >-
Front door camera thinks a package may be waiting at the door.
notify_target: >-
{% if is_state('group.family', 'home') %}
family
{% else %}
carlo
{% endif %}
- service: script.notify_engine
data:
title: Package check
value1: "{{ package_message }}"
who: "{{ notify_target }}"
group: information
level: active
camera_entity: camera.frontdoorbell
- service: script.send_to_logbook
data:
topic: PACKAGES
message: "{{ package_message }}"

@ -0,0 +1,682 @@
######################################################################
# @CCOSTAN - Follow Me on X
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Vacation Mode - house-sitter arrival, analytics, and security checks.
# Detects long absences, tracks sitter visits, and delivers vacation-specific reminders.
# -------------------------------------------------------------------
# Related Issue: 793
# Notes: Vacation mode auto-enables after 24 hours of family absence or 24 hours without bed use while the family is away.
# Notes: General vacation speech uses Chromecast only; the garage Alexa welcome is the one local-device exception.
# Notes: Visit analytics come from native entity attributes plus recorder-backed sensors instead of extra helper entities.
######################################################################
input_boolean:
vacation_mode:
name: Vacation Mode
icon: mdi:palm-tree
initial: off
house_sitter_present:
name: House Sitter Present
icon: mdi:account-key
initial: off
sensor:
- platform: history_stats
name: Vacation House Sitter Visit Count
entity_id: input_boolean.house_sitter_present
state: 'on'
type: count
start: >-
{% if is_state('input_boolean.vacation_mode', 'on') %}
{{ states.input_boolean.vacation_mode.last_changed }}
{% else %}
{{ now() }}
{% endif %}
end: "{{ now() }}"
template:
- sensor:
- name: "Vacation House Sitter Analytics"
unique_id: vacation_house_sitter_analytics
icon: mdi:clipboard-text-clock-outline
state: "{{ states('sensor.vacation_house_sitter_visit_count') | int(0) }}"
attributes:
vacation_started_at: >-
{% if is_state('input_boolean.vacation_mode', 'on') %}
{{ as_local(states.input_boolean.vacation_mode.last_changed).isoformat() }}
{% else %}
none
{% endif %}
last_arrival_at: >-
{% set vacation_start = as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) %}
{% set raw = state_attr('automation.vacation_mode_house_sitter_arrival', 'last_triggered') %}
{% set ts = as_timestamp(raw, 0) %}
{% if ts >= vacation_start and ts > 0 %}
{{ as_local(raw).isoformat() }}
{% else %}
none
{% endif %}
last_departure_at: >-
{% set vacation_start = as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) %}
{% set raw = state_attr('automation.vacation_mode_house_sitter_departure', 'last_triggered') %}
{% set ts = as_timestamp(raw, 0) %}
{% if ts >= vacation_start and ts > 0 %}
{{ as_local(raw).isoformat() }}
{% else %}
none
{% endif %}
last_visit_minutes: >-
{% set vacation_start = as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) %}
{% set arrival = state_attr('automation.vacation_mode_house_sitter_arrival', 'last_triggered') %}
{% set departure = state_attr('automation.vacation_mode_house_sitter_departure', 'last_triggered') %}
{% set arrival_ts = as_timestamp(arrival, 0) %}
{% set departure_ts = as_timestamp(departure, 0) %}
{% if arrival_ts >= vacation_start and departure_ts >= arrival_ts %}
{{ ((departure_ts - arrival_ts) / 60) | round(1) }}
{% else %}
0
{% endif %}
hours_since_last_visit: >-
{% set vacation_start = as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) %}
{% set departure = state_attr('automation.vacation_mode_house_sitter_departure', 'last_triggered') %}
{% set departure_ts = as_timestamp(departure, 0) %}
{% if departure_ts >= vacation_start %}
{{ ((as_timestamp(now()) - departure_ts) / 3600) | round(1) }}
{% else %}
0
{% endif %}
active_visit_minutes: >-
{% if is_state('input_boolean.house_sitter_present', 'on') %}
{{ ((as_timestamp(now()) - as_timestamp(states.input_boolean.house_sitter_present.last_changed, 0)) / 60) | round(1) }}
{% else %}
0
{% endif %}
automation:
- alias: 'Vacation Mode Enable'
id: 163f4434-2a2f-4528-a53c-8fc6e1fd8e14
mode: single
trigger:
- platform: state
entity_id: group.family
to: 'not_home'
for: "24:00:00"
- platform: state
entity_id: group.bed
to: 'off'
for: "24:00:00"
- platform: homeassistant
event: start
- platform: time_pattern
hours: "/1"
condition:
- condition: state
entity_id: input_boolean.vacation_mode
state: 'off'
- condition: template
value_template: >-
{% set family_away = is_state('group.family', 'not_home') %}
{% set family_away_seconds = as_timestamp(now()) - as_timestamp(states.group.family.last_changed, 0) %}
{% set bed_unused_seconds = as_timestamp(now()) - as_timestamp(states.group.bed.last_changed, 0) %}
{{ (family_away and family_away_seconds >= 86400)
or (family_away and is_state('group.bed', 'off') and bed_unused_seconds >= 86400) }}
action:
- variables:
vacation_reason: >-
{% set family_away_seconds = as_timestamp(now()) - as_timestamp(states.group.family.last_changed, 0) %}
{% set bed_unused_seconds = as_timestamp(now()) - as_timestamp(states.group.bed.last_changed, 0) %}
{% if is_state('group.bed', 'off') and bed_unused_seconds >= 86400 and family_away_seconds < 86400 %}
Bed inactivity while the family remained away
{% elif is_state('group.bed', 'off') and bed_unused_seconds >= 86400 %}
Family absence and no bed use
{% else %}
Family absence
{% endif %}
- service: input_boolean.turn_on
entity_id:
- input_boolean.vacation_mode
- service: input_boolean.turn_off
entity_id:
- input_boolean.house_sitter_present
- service: script.send_to_logbook
data:
topic: VACATION MODE
message: >-
Vacation mode enabled after 24 hours based on {{ vacation_reason | lower }}.
- alias: 'Vacation Mode Reset'
id: d7d33f43-22f6-4db4-8a7d-c38f3c6d0c65
mode: single
trigger:
- platform: state
entity_id: group.family
to: 'home'
condition:
- condition: template
value_template: >-
{{ is_state('input_boolean.vacation_mode', 'on')
and trigger.from_state is not none
and trigger.from_state.state == 'not_home' }}
action:
- service: input_boolean.turn_off
entity_id:
- input_boolean.vacation_mode
- input_boolean.house_sitter_present
- service: script.speech_engine
data:
value1: >-
Vacation Mode has been disabled and normal automations will continue.
call_no_announcement: 1
- alias: 'Vacation Mode Garage Welcome'
id: 63ac9268-c895-4a1b-b0df-92b5bb8e9d01
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: group.garage_doors
to: 'open'
for: "00:00:15"
condition:
- condition: template
value_template: >-
{{ is_state('group.family', 'not_home')
and is_state('input_boolean.vacation_mode', 'on')
and is_state('input_boolean.house_sitter_present', 'off')
and trigger.to_state is not none }}
action:
- delay: "00:00:30"
- condition: state
entity_id: group.family
state: 'not_home'
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'off'
- service: notify.alexa_media_garage
data:
message: >-
Welcome back to Bear Stone. Please check whether any packages are waiting at the front door.
data:
type: announce
- alias: 'Vacation Mode House Sitter Arrival'
id: 8058a1e1-8517-4a07-839b-ef8f30ec24e4
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: group.garage_doors
to: 'open'
for: "00:00:15"
id: garage
- platform: state
entity_id: binary_sensor.mcu1_gpio5
to: 'on'
for: "00:00:02"
id: front_door_sensor
- platform: state
entity_id: lock.front_door
to: 'unlocked'
for: "00:02:00"
id: front_door_unlock
condition:
- condition: template
value_template: >-
{{ is_state('group.family', 'not_home')
and is_state('input_boolean.vacation_mode', 'on')
and is_state('input_boolean.house_sitter_present', 'off') }}
action:
- variables:
entry_label: >-
{{ 'garage door' if trigger.id == 'garage' else 'front door' }}
entry_delay: >-
{{ '00:05:00' if trigger.id == 'garage' else '00:02:00' }}
vacation_start_ts: "{{ as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) }}"
last_departure_raw: "{{ state_attr('automation.vacation_mode_house_sitter_departure', 'last_triggered') }}"
last_departure_ts: "{{ as_timestamp(last_departure_raw, 0) }}"
visit_number: "{{ (states('sensor.vacation_house_sitter_visit_count') | int(0)) + 1 }}"
away_duration: >-
{% set seconds = (as_timestamp(now()) - as_timestamp(states.group.family.last_changed, 0)) | int(0) %}
{% set days = (seconds // 86400) | int(0) %}
{% set hours = ((seconds % 86400) // 3600) | int(0) %}
{% set minutes = ((seconds % 3600) // 60) | int(0) %}
{% if days > 0 %}
{{ days }} day{{ 's' if days != 1 else '' }}{% if hours > 0 %} and {{ hours }} hour{{ 's' if hours != 1 else '' }}{% endif %}
{% elif hours > 0 %}
{{ hours }} hour{{ 's' if hours != 1 else '' }}{% if minutes > 0 %} and {{ minutes }} minute{{ 's' if minutes != 1 else '' }}{% endif %}
{% else %}
{{ minutes }} minute{{ 's' if minutes != 1 else '' }}
{% endif %}
last_visit_gap: >-
{% set gap_seconds = (as_timestamp(now()) - (last_departure_ts | float(0))) | int(0) %}
{% set hours = (gap_seconds // 3600) | int(0) %}
{% set minutes = ((gap_seconds % 3600) // 60) | int(0) %}
{% if hours > 0 %}
{{ hours }} hour{{ 's' if hours != 1 else '' }}{% if minutes > 0 %} and {{ minutes }} minute{{ 's' if minutes != 1 else '' }}{% endif %}
{% else %}
{{ minutes }} minute{{ 's' if minutes != 1 else '' }}
{% endif %}
visit_context: >-
{% if (last_departure_ts | float(0)) >= (vacation_start_ts | float(0)) %}
This is visit number {{ visit_number }} for this vacation. The last visit ended about {{ last_visit_gap }} ago.
{% else %}
This is the first house-sitter visit for this vacation.
{% endif %}
carlo_location: >-
{% set place = states('sensor.carlo_place') %}
{{ place if place not in ['unknown', 'unavailable', 'none', ''] else states('person.carlo') }}
stacey_location: >-
{% set place = states('sensor.stacey_place') %}
{{ place if place not in ['unknown', 'unavailable', 'none', ''] else states('person.stacey') }}
justin_location: >-
{% set place = states('sensor.justin_place') %}
{{ place if place not in ['unknown', 'unavailable', 'none', ''] else states('person.justin') }}
paige_location: >-
{% set place = states('sensor.paige_place') %}
{{ place if place not in ['unknown', 'unavailable', 'none', ''] else states('person.paige') }}
garbage_message: >-
{% set day = now().strftime('%a') %}
{% if day in ['Tue', 'Sat'] %}
If you have a chance, please take the garbage cans out tonight.
{% elif day in ['Wed', 'Sun'] %}
If the garbage cans are still outside today, please bring them back in.
{% else %}
{% endif %}
package_message: >-
{% if trigger.id == 'garage' and is_state('binary_sensor.front_door_packages_present', 'on') %}
Please also check whether any packages are waiting at the front door.
{% else %}
{% endif %}
arrival_message: >-
House sitter arrival detected through the {{ entry_label }}.
The family was last home {{ away_duration }} ago.
{{ visit_context }}
Carlo is at {{ carlo_location }}. Stacey is at {{ stacey_location }}.
Justin is at {{ justin_location }}. Paige is at {{ paige_location }}.
Please check Molly's food, water, and litter box.
{{ package_message }}
{{ garbage_message }}
push_message: >-
House sitter arrival detected via the {{ entry_label }} after {{ away_duration }} away.
{{ visit_context }}
Carlo={{ carlo_location }}, Stacey={{ stacey_location }}, Justin={{ justin_location }}, Paige={{ paige_location }}.
Molly reminder is included.
{{ package_message }}
{{ garbage_message }}
- delay: "{{ entry_delay }}"
- condition: template
value_template: >-
{{ is_state('group.family', 'not_home')
and is_state('input_boolean.vacation_mode', 'on')
and is_state('input_boolean.house_sitter_present', 'off') }}
- service: input_boolean.turn_on
entity_id:
- input_boolean.house_sitter_present
- service: automation.trigger
target:
entity_id: automation.late_night_helper
data:
skip_condition: false
- choose:
- conditions:
- condition: template
value_template: "{{ trigger.id == 'front_door_unlock' }}"
sequence:
- service: automation.trigger
target:
entity_id: automation.late_night_helper_outside
data:
skip_condition: false
- service: script.send_to_logbook
data:
topic: HOUSE SITTER
message: >-
House sitter arrival inferred from the {{ entry_label }} after {{ away_duration }} of family absence.
{{ visit_context }}
- service: script.notify_engine
data:
title: House sitter arrival
value1: "{{ push_message }}"
who: carlo
group: information
level: active
- service: script.speech_processing
data:
media_player: media_player.livingroomcc
speech_message: "{{ arrival_message }}"
- alias: 'Vacation Mode Sitter Checklist Follow-Up'
id: 4bd37a05-e6b6-493f-9ddb-fc8d9781c4df
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: input_boolean.house_sitter_present
to: 'on'
for: "00:10:00"
condition:
- condition: template
value_template: >-
{{ is_state('input_boolean.vacation_mode', 'on')
and is_state('input_boolean.house_sitter_present', 'on') }}
action:
- variables:
garage_status: >-
{% if is_state('group.garage_doors', 'open') %}
If the garage door is still open, please close it before you leave.
{% else %}
The garage doors already look closed.
{% endif %}
checklist_message: >-
Quick reminder. Please check Molly's food, water, and litter box.
{{ garage_status }}
The front door should auto-lock when you leave.
- service: script.speech_processing
data:
media_player: media_player.livingroomcc
speech_message: "{{ checklist_message }}"
- alias: 'Vacation Mode House Sitter Departure'
id: 04f5ab9e-65a8-4cd5-a8e9-0f40c82a2f62
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: group.garage_doors
to: 'closed'
for: "00:00:15"
id: garage
- platform: state
entity_id: binary_sensor.mcu1_gpio5
to: 'off'
for: "00:00:02"
id: front_door
condition:
- condition: template
value_template: >-
{% set seconds = as_timestamp(now()) - as_timestamp(states.input_boolean.house_sitter_present.last_changed, 0) %}
{{ is_state('input_boolean.house_sitter_present', 'on')
and seconds >= 60 }}
action:
- variables:
exit_label: >-
{{ 'garage door' if trigger.id == 'garage' else 'front door' }}
visit_count: "{{ states('sensor.vacation_house_sitter_visit_count') | int(0) }}"
visit_duration: >-
{% set seconds = (as_timestamp(now()) - as_timestamp(states.input_boolean.house_sitter_present.last_changed, 0)) | int(0) %}
{% set minutes = (seconds // 60) | int(0) %}
{% set remainder = (seconds % 60) | int(0) %}
{{ minutes }} minute{{ 's' if minutes != 1 else '' }}{% if remainder > 0 %} and {{ remainder }} second{{ 's' if remainder != 1 else '' }}{% endif %}
- service: homeassistant.turn_off
target:
entity_id: input_boolean.house_sitter_present
- service: script.send_to_logbook
data:
topic: HOUSE SITTER
message: >-
House sitter departure inferred when the {{ exit_label }} closed after {{ visit_duration }}.
Visit count this vacation is now {{ visit_count }}.
- service: script.notify_engine
data:
title: House sitter left
value1: >-
House sitter presence was cleared after the {{ exit_label }} closed about {{ visit_duration }} into visit number {{ visit_count }}.
who: carlo
group: information
level: active
- alias: 'Vacation Mode Secure House Check'
id: 5c4f6a2d-d976-4f9f-b204-ab444b24d76f
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id: input_boolean.house_sitter_present
from: 'on'
to: 'off'
for: "00:25:00"
condition:
- condition: template
value_template: >-
{{ is_state('input_boolean.vacation_mode', 'on')
and is_state('input_boolean.house_sitter_present', 'off') }}
action:
- variables:
visit_count: "{{ states('sensor.vacation_house_sitter_visit_count') | int(0) }}"
visit_minutes: "{{ state_attr('sensor.vacation_house_sitter_analytics', 'last_visit_minutes') | float(0) }}"
front_door_issue: "{{ '' if is_state('lock.front_door', 'locked') else 'front door is ' ~ states('lock.front_door') }}"
garage_issue: "{{ 'a garage door is open' if is_state('group.garage_doors', 'open') else '' }}"
entry_issue: "{{ 'an entry point is still open' if is_state('group.entry_points', 'on') else '' }}"
issue_count: >-
{{ [front_door_issue, garage_issue, entry_issue] | reject('equalto', '') | list | count }}
unsecured_message: >-
{% set items = [front_door_issue, garage_issue, entry_issue] | reject('equalto', '') | list %}
{% if items | count > 0 %}
{{ items | join(', ') }}
{% else %}
all entry points are secure
{% endif %}
joanna_message: >-
Vacation house check after a sitter visit found: {{ unsecured_message }}.
Visit count this vacation: {{ visit_count }}.
Last visit duration: {{ visit_minutes | round(1) }} minutes.
Front door state: {{ states('lock.front_door') }}.
Garage state: {{ states('group.garage_doors') }}.
Entry points state: {{ states('group.entry_points') }}.
- choose:
- conditions:
- condition: template
value_template: "{{ issue_count | int(0) > 0 }}"
sequence:
- service: script.notify_engine
data:
title: Vacation secure-house alert
value1: >-
After the sitter left, {{ unsecured_message }}. Last visit was {{ visit_minutes | round(1) }} minutes.
who: carlo
group: information
level: critical
- service: script.joanna_send_telegram
data:
message: "{{ joanna_message }}"
- service: script.send_to_logbook
data:
topic: VACATION MODE
message: >-
Secure-house check failed after sitter departure because {{ unsecured_message }}.
default:
- service: script.send_to_logbook
data:
topic: VACATION MODE
message: >-
Secure-house check passed 25 minutes after the sitter left.
- alias: 'Vacation Mode Missed Visit Alert'
id: 9f83b8cf-57ef-45b3-b72b-ea6f6c8446ec
mode: single
max_exceeded: silent
trigger:
- platform: time_pattern
minutes: "30"
condition:
- condition: template
value_template: >-
{% set vacation_start = as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) %}
{% set last_departure = as_timestamp(state_attr('automation.vacation_mode_house_sitter_departure', 'last_triggered'), 0) %}
{% set baseline = last_departure if last_departure >= vacation_start else vacation_start %}
{{ is_state('input_boolean.vacation_mode', 'on')
and is_state('input_boolean.house_sitter_present', 'off')
and (as_timestamp(now()) - baseline) >= 172800 }}
- condition: template
value_template: >-
{% set last_alert = as_timestamp(state_attr('automation.vacation_mode_missed_visit_alert', 'last_triggered'), 0) %}
{{ last_alert == 0 or (as_timestamp(now()) - last_alert) >= 86400 }}
action:
- variables:
visit_count: "{{ states('sensor.vacation_house_sitter_visit_count') | int(0) }}"
vacation_start: "{{ as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) }}"
last_departure: "{{ as_timestamp(state_attr('automation.vacation_mode_house_sitter_departure', 'last_triggered'), 0) }}"
baseline: >-
{{ last_departure if (last_departure | float(0)) >= (vacation_start | float(0)) else vacation_start }}
hours_since: "{{ ((as_timestamp(now()) - (baseline | float(0))) / 3600) | round(1) }}"
baseline_label: >-
{% if (last_departure | float(0)) >= (vacation_start | float(0)) %}
the last sitter departure
{% else %}
vacation mode started
{% endif %}
alert_message: >-
No sitter visit has been detected for {{ hours_since }} hours since {{ baseline_label }}.
Visit count this vacation is {{ visit_count }}.
- service: script.notify_engine
data:
title: Vacation missed visit alert
value1: "{{ alert_message }}"
who: carlo
group: information
level: active
- service: script.joanna_send_telegram
data:
message: "{{ alert_message }}"
- service: script.send_to_logbook
data:
topic: VACATION MODE
message: "{{ alert_message }}"
- alias: 'Vacation Mode Room Hints'
id: e0d4e35c-2bf4-435d-adff-52d836812999
mode: single
max_exceeded: silent
trigger:
- platform: state
entity_id: light.kitchen_lights
from: 'off'
to: 'on'
for: "00:00:05"
id: kitchen
- platform: state
entity_id: light.living_room_lights
from: 'off'
to: 'on'
for: "00:00:05"
id: living_room
- platform: state
entity_id: light.living_room_accents
from: 'off'
to: 'on'
for: "00:00:05"
id: living_room
- platform: state
entity_id: light.office_lights
from: 'off'
to: 'on'
for: "00:00:05"
id: office
- platform: state
entity_id: light.garage_lights
from: 'off'
to: 'on'
for: "00:00:05"
id: garage
- platform: state
entity_id: light.upstairs_lights
from: 'off'
to: 'on'
for: "00:00:05"
id: upstairs
condition:
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: state
entity_id: input_boolean.house_sitter_present
state: 'on'
- condition: or
conditions:
- condition: and
conditions:
- condition: state
entity_id: group.bed
state: 'off'
- condition: time
after: '08:00:00'
before: '22:00:00'
- condition: state
entity_id: input_boolean.alert_mode
state: 'on'
action:
- variables:
hint_message: >-
{% set hints = {
'kitchen': 'House tip. The kitchen lights are on. You can also say, Alexa, turn on the sink light or turn off the kitchen accents.',
'living_room': 'House tip. The living room lights are on. You can also say, Alexa, turn on the TV stand light or turn on the living room accents.',
'office': 'House tip. The office lights are on. You can also say, Alexa, turn on the office accent or turn off the office lamp switch.',
'garage': 'House tip. The garage lights are on. You can also say, Alexa, turn on the garage hallway or open the large garage door.',
'upstairs': 'House tip. The upstairs lights are on. You can also say, Alexa, turn on the upstairs lamp or turn off the upstairs lights.'
} %}
{{ hints.get(trigger.id, 'House tip. Alexa can help with the lights in this room.') }}
- service: script.speech_processing
data:
media_player: media_player.livingroomcc
speech_message: "{{ hint_message }}"
- delay: "00:20:00"

@ -87,11 +87,11 @@ notify_engine_two_button:
data:
actions:
- title: "{{ title1|default('', true) }}"
action: "{{ action1 }}"
action: "{{ action1|default('', true) }}"
icon: "{{ icon1|default ('sfsymbols:house.circle', true) }}"
destructive: "{{ destructive1|default('false', true) }}"
- title: "{{ title2|default('', true) }}"
action: "{{ action2 }}"
action: "{{ action2|default('', true) }}"
icon: "{{ icon2|default ('sfsymbols:house.circle', true) }}"
destructive: "{{ destructive2|default('false', true) }}"
group: "{{ group|default('information'),true }}"
group: "{{ group|default('information', true) }}"

@ -4,9 +4,10 @@
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Speech Engine Script - queued announcements to Chromecast targets
# Sends templated speech briefings to media players when family/guests are home.
# Sends templated speech briefings to media players when family, guests, or vacation sitters are active.
# -------------------------------------------------------------------
# Notes: Optional call_* flags control sections (dark_outside, window/garage checks, garbage day, inside/outside weather). Defaults to living room Chromecast if no media_player is provided.
# Notes: Allows announcements while `input_boolean.vacation_mode` is on for house-sitter flows.
######################################################################
# Usage example:
# service: script.speech_engine
@ -25,7 +26,7 @@ speech_engine:
mode: queued
# Define the sequence of actions to be performed
sequence:
# If the state of the "group.family" entity is "home" or the state of the "input_boolean.guest_mode" entity is "on", proceed with the script
# If family is home or a guest/vacation mode is active, proceed with the script
- condition: or
conditions:
- condition: state
@ -34,6 +35,9 @@ speech_engine:
- condition: state
entity_id: input_boolean.guest_mode
state: 'on'
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
# Run the "script.speech_processing" service with the specified media player and speech message
- service: script.speech_processing

@ -4,7 +4,7 @@
#
# Features:
# - Operates during specified hours
# - Only activates when family is home or guest mode is on
# - Activates when family is home or guest/vacation mode is on
# - Adjustable volume based on time of day
#
# Usage:
@ -36,6 +36,9 @@ speech_processing:
- condition: state
entity_id: input_boolean.guest_mode
state: 'on'
- condition: state
entity_id: input_boolean.vacation_mode
state: 'on'
- condition: or
conditions:
- condition: and

Loading…
Cancel
Save

Powered by TurnKey Linux.