feat(ha): add vacation house digests and Codex reset docs

This commit is contained in:
Carlo Costanzo
2026-06-25 17:05:55 -04:00
parent d3dc5db95f
commit fb91e8fd73
7 changed files with 291 additions and 18 deletions
+4 -3
View File
@@ -18,10 +18,10 @@
Live, personal Home Assistant configuration shared for **browsing and inspiration**. This is not a turnkey clone-and-run setup; borrow ideas, adapt entity IDs/secrets, and test in your own environment.
### Latest video: Home Assistant Leak Detection Automations
[![Home Assistant Leak Detection Automations](https://www.vcloudinfo.com/wp-content/uploads/2026/06/maxresdefault.jpg)](https://youtu.be/xbhgWnomFYI)
### Latest video: Track Codex Resets in Home Assistant Before They Expire
[![Track Codex Resets in Home Assistant Before They Expire](https://www.vcloudinfo.com/wp-content/uploads/2026/06/codex-resets-home-assistant-thumbnail.png)](https://youtu.be/7wKhtrvtyiI)
This walkthrough breaks down the water-leak response loop I use in Home Assistant: a shutoff valve state, a maintenance guard, Activity Feed context, Repairs tracking, and critical phone recovery actions. [Watch the video](https://youtu.be/xbhgWnomFYI), read the [companion blog post](https://www.vcloudinfo.com/2026/06/home-assistant-leak-detection-automations.html), browse the YAML in [config/packages/phynplus.yaml](config/packages/phynplus.yaml), and see the older Phyn Plus backstory in the [original write-up](https://www.vcloudinfo.com/2020/05/phyn-plus-smart-water-shutoff-device.html).
This walkthrough shows how I track Codex reset credits in Home Assistant: a reset-credit JSON feed, REST/template sensors, a dashboard card with expiration dates, and a Repair that stays open while any reset is within 7 days of expiring. [Watch the video](https://youtu.be/7wKhtrvtyiI), read the [companion blog post](https://www.vcloudinfo.com/2026/06/track-codex-resets-home-assistant.html), browse the YAML in [config/packages/bearclaw.yaml](config/packages/bearclaw.yaml), and see the dashboard source in [config/dashboards/infrastructure](config/dashboards/infrastructure).
### Quick navigation
- You are here: `/` (root repo guide)
@@ -48,6 +48,7 @@ This walkthrough breaks down the water-leak response loop I use in Home Assistan
- Alarm and perimeter monitoring: [config/packages/alarm.yaml](config/packages/alarm.yaml)
- Garage routines and entry lighting: [config/packages/garadget.yaml](config/packages/garadget.yaml), [config/automation/garage_entry_light.yaml](config/automation/garage_entry_light.yaml), [video walkthrough](https://youtu.be/wFO0H5zgnzk)
- LLM Vision package reminders: [config/packages/llmvision.yaml](config/packages/llmvision.yaml), [video walkthrough](https://youtu.be/nAhCezFetvI)
- Codex reset-credit tracking: [config/packages/bearclaw.yaml](config/packages/bearclaw.yaml), [config/dashboards/infrastructure](config/dashboards/infrastructure), [video walkthrough](https://youtu.be/7wKhtrvtyiI)
- Water leak response loop: [config/packages/phynplus.yaml](config/packages/phynplus.yaml), [video walkthrough](https://youtu.be/xbhgWnomFYI)
- Bedroom camera kiosk tablet: [config/packages/kiosk_tablet.yaml](config/packages/kiosk_tablet.yaml), [config/dashboards/kiosk](config/dashboards/kiosk), [video walkthrough](https://youtu.be/ChgEu0IDWzc)
- Holiday/front-of-house color scenes: [config/scene/monthly_colors.yaml](config/scene/monthly_colors.yaml), [config/script/monthly_color_scene.yaml](config/script/monthly_color_scene.yaml)
+1 -1
View File
@@ -51,7 +51,7 @@ Live view of the `config/` directory my production Home Assistant instance loads
| Dashboards & Media | UI chrome, floorplans, sound bites, and automation assets. | [dashboards/kiosk](dashboards/kiosk), [www/custom_ui/floorplan/images/branding/Bear-Stone-Docker-Diagram.jpg](www/custom_ui/floorplan/images/branding/Bear-Stone-Docker-Diagram.jpg), [media/](media) |
| Seasonal Audio | Cuckoo clock with Halloween and Christmas sound packs. | [automation/System/CucKoo_Clock.yaml](automation/System/CucKoo_Clock.yaml) |
The latest walkthrough shows a practical leak-detection response loop in Home Assistant: [video](https://youtu.be/xbhgWnomFYI), [companion post](https://www.vcloudinfo.com/2026/06/home-assistant-leak-detection-automations.html), YAML in [packages/phynplus.yaml](packages/phynplus.yaml), and the original Phyn Plus backstory in the [older write-up](https://www.vcloudinfo.com/2020/05/phyn-plus-smart-water-shutoff-device.html). The earlier kiosk and LLM Vision walkthroughs are still available with examples in [packages/kiosk_tablet.yaml](packages/kiosk_tablet.yaml) and [packages/llmvision.yaml](packages/llmvision.yaml).
The latest walkthrough shows Codex reset-credit tracking in Home Assistant: [video](https://youtu.be/7wKhtrvtyiI), [companion post](https://www.vcloudinfo.com/2026/06/track-codex-resets-home-assistant.html), YAML in [packages/bearclaw.yaml](packages/bearclaw.yaml), and the dashboard source in [dashboards/infrastructure](dashboards/infrastructure). The earlier leak-detection, kiosk, and LLM Vision walkthroughs are still available with examples in [packages/phynplus.yaml](packages/phynplus.yaml), [packages/kiosk_tablet.yaml](packages/kiosk_tablet.yaml), and [packages/llmvision.yaml](packages/llmvision.yaml).
### Gear tied to these automations (affiliate links)
Only including devices that have active references in the files above.
@@ -39,11 +39,6 @@
entity: sensor.codex_reset_credits_available
name: Resets
icon: mdi:backup-restore
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.codex_reset_credits_expiring_soon
name: Reset Warnings
icon: mdi:alert-clock
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_all_dispatches_24h
@@ -62,7 +57,7 @@
- type: grid
column_span: 4
columns: 2
columns: 3
square: false
cards:
- type: custom:vertical-stack-in-card
@@ -184,11 +179,6 @@
return `${enabled ? 'enabled' : 'disabled'} | ${age} min ago`;
]]]
- type: grid
column_span: 4
columns: 1
square: false
cards:
- type: custom:vertical-stack-in-card
card_mod:
style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml
@@ -8,6 +8,8 @@
# -------------------------------------------------------------------
# Notes: Uses telemetry from /api/bearclaw/status ingested by bearclaw.yaml.
# Notes: Shows Codex reset-credit expiry data from the codexUsage status field.
# Notes: Codex reset walkthrough: https://youtu.be/7wKhtrvtyiI
# Notes: Codex reset companion post: https://www.vcloudinfo.com/2026/06/track-codex-resets-home-assistant.html
######################################################################
type: sections
+4 -3
View File
@@ -59,11 +59,11 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this
| [processmonitor.yaml](processmonitor.yaml) | Root filesystem disk-pressure monitoring with immediate digest/logbook notes at 80%, Joanna review after 10 minutes above 80%, and delayed phone alerts only if the issue stays unresolved after dispatch. | `sensor.disk_use_percent`, `repairs.create`, `script.joanna_dispatch`, `tts.clear_cache` |
| [tugtainer_updates.yaml](tugtainer_updates.yaml) | Tugtainer container update notifications via webhook + persistent alerts, plus event-based Joanna dispatch when reports include `### Available:` (24h cooldown via `mode: single` + delay, no new helpers). | `persistent_notification.create`, `event: tugtainer_available_detected`, `script.joanna_dispatch`, `input_datetime.tugtainer_last_update` |
| [printer.yaml](printer.yaml) | Epson ink watchdog with one-day and one-week mobile snooze actions for low-ink reminders. | `input_datetime.printer_ink_snooze_until`, `sensor.epson_*`, mobile app action events |
| [bearclaw.yaml](bearclaw.yaml) | Joanna/BearClaw bridge automations that forward Telegram commands to codex_appliance, include LLM-first routing context for freeform text, relay replies back, ingest `/api/bearclaw/status` telemetry, and expose dispatch, QMD/memory-index, plus Codex reset-credit expiry sensors and Repairs for Infrastructure dashboards. | `rest_command.bearclaw_*`, `sensor.bearclaw_status_telemetry`, `sensor.joanna_*`, `sensor.codex_reset_*`, `binary_sensor.joanna_*`, `binary_sensor.codex_reset_credit_expiring_soon`, `automation.bearclaw_*`, `automation.codex_reset_credit_expiry_repair`, `repairs.create`, `repairs.remove`, `script.send_to_logbook` |
| [bearclaw.yaml](bearclaw.yaml) | Joanna/BearClaw bridge automations that forward Telegram commands to codex_appliance, include LLM-first routing context for freeform text, relay replies back, ingest `/api/bearclaw/status` telemetry, and expose dispatch, QMD/memory-index, plus Codex reset-credit expiry sensors and Repairs for Infrastructure dashboards; see the [Codex reset tracking video](https://youtu.be/7wKhtrvtyiI) and [companion post](https://www.vcloudinfo.com/2026/06/track-codex-resets-home-assistant.html). | `rest_command.bearclaw_*`, `sensor.bearclaw_status_telemetry`, `sensor.joanna_*`, `sensor.codex_reset_*`, `binary_sensor.joanna_*`, `binary_sensor.codex_reset_credit_expiring_soon`, `automation.bearclaw_*`, `automation.codex_reset_credit_expiry_repair`, `repairs.create`, `repairs.remove`, `script.send_to_logbook` |
| [telegram_bot.yaml](telegram_bot.yaml) | Legacy Telegram transport marker for BearClaw; the shared `joanna_send_telegram` helper now forwards through the codex_appliance direct Telegram API. | `rest_command.bearclaw_telegram_send`, `script.joanna_send_telegram` |
| [phynplus.yaml](phynplus.yaml) | Phyn shutoff automations with leak-test guard, Activity Feed context, Repairs tracking, and critical push recovery when the valve closes; see the [leak detection automation video](https://youtu.be/xbhgWnomFYI). | `valve.phyn_shutoff_valve`, `binary_sensor.phyn_leak_test_running`, `script.phyn_send_actionable_leak_notification`, `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, stale-visit timeout protection, and deliver exact sitter-facing briefings with garage Alexa support. | `input_boolean.vacation_mode`, `input_boolean.house_sitter_present`, `input_datetime.vacation_house_sitter_*`, `sensor.vacation_house_sitter_*`, `group.garage_doors`, `lock.front_door`, `script.vacation_house_sitter_clear_presence`, `script.notify_engine`, `script.joanna_send_telegram` |
| [vacation_mode.yaml](vacation_mode.yaml) | Auto-enable vacation mode after 24 hours away or no bed use, track sitter analytics/secure-house checks, stale-visit timeout protection, deliver sitter-facing briefings, and send 10 AM/10 PM house digests with Powerwall/security/backup status plus Joanna review. | `input_boolean.vacation_mode`, `input_boolean.house_sitter_present`, `input_datetime.vacation_house_sitter_*`, `input_datetime.vacation_house_status_digest_last_sent`, `sensor.vacation_house_sitter_*`, `binary_sensor.powerwall_grid_status`, `sensor.powerwall_charge`, `group.garage_doors`, `lock.front_door`, `script.vacation_house_sitter_clear_presence`, `script.vacation_house_status_digest`, `script.notify_engine`, `rest_command.bearclaw_command`, `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` |
| [kiosk_tablet.yaml](kiosk_tablet.yaml) | Keeps the bedroom Fully Kiosk Fire tablet pinned to the dedicated camera kiosk dashboard when the page or foreground app drifts; normal wake events only restore brightness/focus. See the [video walkthrough](https://youtu.be/ChgEu0IDWzc). | `sensor.alarm_panel_1_current_page`, `sensor.alarm_panel_1_foreground_app`, `button.alarm_panel_1_bring_to_foreground`, `button.alarm_panel_1_load_start_url` |
| [powerwall.yaml](powerwall.yaml) | Track Tesla Powerwall grid status, push live outage tracking to mobile targets, and shed loads automatically when off-grid (alerts include Activity feed + Repairs). | `binary_sensor.powerwall_grid_status`, `sensor.powerwall_*`, `script.notify_live_activity`, `repairs.create` |
@@ -99,6 +99,7 @@ When a package has a dedicated blog post or video, I link it right inside the YA
| Package | Why read/watch | Deep dive links |
| --- | --- | --- |
| [bearclaw.yaml](bearclaw.yaml) + [Infrastructure dashboard](../dashboards/infrastructure) | Codex reset-credit expiry tracking with REST telemetry, template sensors, dashboard cards, and Repairs that stay open until the reset clears. | [Video walkthrough](https://youtu.be/7wKhtrvtyiI) · [Companion post](https://www.vcloudinfo.com/2026/06/track-codex-resets-home-assistant.html) |
| [finance.yaml](finance.yaml) | Custom Yahoo Finance integration overview and setup notes. | [Blog](https://www.vcloudinfo.com/2020/10/how-to-track-stocks-in-home-assistant-using-a-custom-component.html) |
| [garadget.yaml](garadget.yaml) | Garage arrival hub with auto-open guardrails, entry prompts, wind alerts, nighttime reminders, camera context, and the older MQTT/token setup notes. | [Video walkthrough](https://youtu.be/wFO0H5zgnzk) · [Companion post](https://www.vcloudinfo.com/2026/05/home-assistant-garage-automations-arrival-alerts-tesla.html) · [Blog: Integration guide](https://www.vcloudinfo.com/2019/03/how-to-add-garadget-to-home-assistant.html) · [Blog: Token fix](https://www.vcloudinfo.com/2020/05/fixing-garadget-in-home-assistant.html) |
| [garage_entry_light.yaml](../automation/garage_entry_light.yaml) | Simple door-open and door-closed hallway lighting pattern from the garage walkthrough. | [Video walkthrough](https://youtu.be/wFO0H5zgnzk) · [Companion post](https://www.vcloudinfo.com/2026/05/home-assistant-garage-automations-arrival-alerts-tesla.html) |
@@ -110,7 +111,7 @@ When a package has a dedicated blog post or video, I link it right inside the YA
| [lightning.yaml](lightning.yaml) | Blitzortung detector wiring, strike alerts, and snooze workflow. | [Blog](https://www.vcloudinfo.com/2020/08/adding-a-lightning-sensor-to-home-assistant.html) |
| [phynplus.yaml](phynplus.yaml) | Leak-detection response loop with valve state, maintenance guard, Activity Feed context, Repairs tracking, and critical push recovery. | [Video walkthrough](https://youtu.be/xbhgWnomFYI) · [Companion post](https://www.vcloudinfo.com/2026/06/home-assistant-leak-detection-automations.html) · [Original Phyn Plus post](https://www.vcloudinfo.com/2020/05/phyn-plus-smart-water-shutoff-device.html) |
| [powerwall.yaml](powerwall.yaml) | Monitoring Tesla Powerwall health + what to automate when the grid drops. | [Blog](https://www.vcloudinfo.com/2018/01/going-green-to-save-some-green-in-2018.html) |
| [vacation_mode.yaml](vacation_mode.yaml) | Sustained-away Vacation Mode, house-sitter visit tracking, reminders, missed-visit alerts, and secure-house checks. | [Video walkthrough](https://youtu.be/15kRcFaVV2Y) · [Blog](https://www.vcloudinfo.com/2026/05/home-assistant-vacation-mode-house-sitter-automation.html) |
| [vacation_mode.yaml](vacation_mode.yaml) | Sustained-away Vacation Mode, house-sitter visit tracking, reminders, missed-visit alerts, secure-house checks, and vacation house digests that keep Powerwall status visible. | [Video walkthrough](https://youtu.be/15kRcFaVV2Y) · [Blog](https://www.vcloudinfo.com/2026/05/home-assistant-vacation-mode-house-sitter-automation.html) |
| [vacuum.yaml](vacuum.yaml) | Dreame away-only cleaning, room queues, sweep/mop phases, Alexa one-off room commands, and rescue notifications. | [Video walkthrough](https://youtu.be/KKOWSKuF5jA) · [Companion post](https://www.vcloudinfo.com/2026/05/home-assistant-vacuum-automations-dreame-2026.html) · [Older Neato post](https://www.vcloudinfo.com/2020/05/home-assistant-neato-vacuum-automation.html) |
| [pihole_ha.yaml](pihole_ha.yaml) | Sync Pi-hole blocking state across HA DNS nodes. | |
| [grafana.yaml.disabled](grafana.yaml.disabled) | Rendering Grafana dashboards to images for Lovelace and social posts. | [Blog](https://www.vcloudinfo.com/2018/01/going-green-to-save-some-green-in-2018.html) · [Blog](https://www.vcloudinfo.com/2018/09/re-installing-tesla-solar-panels-again.html) · [Video](https://youtu.be/BartadUzGOA) |
+21
View File
@@ -14,6 +14,8 @@
# Notes: The callback webhook writes JOANNA activity entries to logbook for traceability and optional HA alerts.
# Notes: Status telemetry polling expects !secret bearclaw_status_url (token header stays !secret bearclaw_token).
# Notes: Codex reset-credit expiry telemetry is sourced from the appliance `codexUsage` status field.
# Notes: Codex reset walkthrough: https://youtu.be/7wKhtrvtyiI
# Notes: Codex reset companion post: https://www.vcloudinfo.com/2026/06/track-codex-resets-home-assistant.html
# Notes: Nightly Duplicati verification calls a codex_appliance admin endpoint and returns structured health to HA via response_variable.
# Notes: v2 intake is the primary HA contract; legacy command/ingest routes remain appliance-side shims.
# Notes: Command payload supports async_only for automation-first queueing when immediate inline handling is not required.
@@ -504,6 +506,25 @@ automation:
topic: JOANNA
message: "{{ status | upper }}: {{ logbook_message }}"
- choose:
- conditions:
- condition: template
value_template: >-
{{ source == 'home_assistant_automation.vacation_house_status_digest'
and status == 'completed' }}
sequence:
- service: script.notify_engine
data:
title: Vacation digest review
value1: >-
{% set compact = (message if message | trim != '' else summary) | replace('\r', ' ') | replace('\n', ' ') | trim %}
{% if compact | length > 420 %}
{{ compact[:417] ~ '...' }}
{% else %}
{{ compact }}
{% endif %}
who: carlo
group: vacation
level: active
- conditions:
- condition: template
value_template: "{{ severity in ['warning', 'error', 'critical'] or status in ['failed', 'canceled'] }}"
+258
View File
@@ -7,12 +7,16 @@
# Detects long absences, tracks sitter visits, and delivers vacation-specific reminders.
# -------------------------------------------------------------------
# Related Issue: 793
# Related Issue: 1791
# Related Issue: 1792
# 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 use recorder-backed visit counts plus arrival/departure helpers for accurate durations.
# Notes: Dorm zones are reported as away locations, not Bear Stone home.
# Notes: Recent-departure lockout and a 3-hour stale-visit timeout prevent missed close edges from creating inflated visit durations.
# Notes: Missed sitter alerts include 2-day and 3-day snooze actions that clear after a visit.
# Notes: 10 AM and 10 PM house digests send lock-screen pushes and dispatch a richer snapshot to Joanna for vacation-mode review.
# Notes: Powerwall/grid status is always included in vacation digests because power events are high signal.
# Video: https://youtu.be/15kRcFaVV2Y
# Blog: https://www.vcloudinfo.com/2026/05/home-assistant-vacation-mode-house-sitter-automation.html
# Snooze video: https://youtu.be/y47KSflS1aw
@@ -42,6 +46,10 @@ input_datetime:
name: Vacation House Sitter Missed Visit Snooze Until
has_date: true
has_time: true
vacation_house_status_digest_last_sent:
name: Vacation House Status Digest Last Sent
has_date: true
has_time: true
input_number:
vacation_house_sitter_last_visit_minutes:
@@ -80,6 +88,235 @@ script:
target:
entity_id: input_boolean.house_sitter_present
vacation_house_status_digest:
alias: Vacation House Status Digest
mode: queued
fields:
digest_mode:
description: Digest window label, usually morning or night.
example: morning
sequence:
- variables:
digest_mode_value: "{{ digest_mode | default('morning', true) | lower }}"
- variables:
digest_label: "{{ 'Night' if digest_mode_value == 'night' else 'Morning' }}"
last_digest_ts: "{{ as_timestamp(states('input_datetime.vacation_house_status_digest_last_sent'), 0) }}"
vacation_started_ts: "{{ as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) }}"
vacation_duration: >-
{% set started = as_timestamp(states.input_boolean.vacation_mode.last_changed, 0) %}
{% if is_state('input_boolean.vacation_mode', 'on') and started > 0 %}
{% set hours = ((as_timestamp(now()) - started) / 3600) | int(0) %}
{% set days = (hours // 24) | int(0) %}
{% set remaining_hours = (hours % 24) | int(0) %}
{{ days ~ 'd ' ~ remaining_hours ~ 'h' if days > 0 else remaining_hours ~ 'h' }}
{% else %}
inactive
{% endif %}
sitter_summary: >-
{% set visit_count = states('sensor.vacation_house_sitter_visit_count') | int(0) %}
{% set hours_since = state_attr('sensor.vacation_house_sitter_analytics', 'hours_since_last_visit') | float(0) %}
{% if is_state('input_boolean.house_sitter_present', 'on') %}
Sitter is currently at the house.
{% elif visit_count > 0 %}
Sitter visits: {{ visit_count }}; last visit {{ hours_since | round(1) }}h ago.
{% else %}
No sitter visit recorded yet this vacation.
{% endif %}
powerwall_grid_label: >-
{% set grid = states('binary_sensor.powerwall_grid_status') %}
{% if grid == 'on' %}
grid up
{% elif grid == 'off' %}
GRID DOWN
{% else %}
grid {{ grid }}
{% endif %}
powerwall_charge_label: >-
{% set charge = states('sensor.powerwall_charge') %}
{% if charge in ['unknown', 'unavailable', 'none', ''] %}
battery unavailable
{% else %}
battery {{ charge | float(0) | round(0) | int(0) }}%
{% endif %}
powerwall_grid_changed_ts: >-
{% set entity = states.binary_sensor.powerwall_grid_status if states.binary_sensor.powerwall_grid_status is defined else none %}
{{ as_timestamp(entity.last_changed, 0) if entity is not none else 0 }}
powerwall_recent_event: >-
{% set changed = powerwall_grid_changed_ts | float(0) %}
{{ last_digest_ts | float(0) > 0 and changed > last_digest_ts | float(0) }}
powerwall_summary: >-
{% set summary = 'Powerwall: ' ~ powerwall_grid_label | trim ~ ', ' ~ powerwall_charge_label | trim ~ '.' %}
{% if powerwall_recent_event | bool(false) %}
{{ summary }} Grid status changed since the last digest at {{ (powerwall_grid_changed_ts | float(0)) | timestamp_custom('%H:%M', true) }}.
{% else %}
{{ summary }}
{% endif %}
powerwall_issues: >-
{% set ns = namespace(items=[]) %}
{% set charge = states('sensor.powerwall_charge') %}
{% if is_state('binary_sensor.powerwall_grid_status', 'off') %}
{% set ns.items = ns.items + ['grid is down'] %}
{% endif %}
{% if charge in ['unknown', 'unavailable', 'none', ''] %}
{% set ns.items = ns.items + ['Powerwall charge unavailable'] %}
{% elif charge | float(100) < 60 %}
{% set ns.items = ns.items + ['Powerwall charge ' ~ (charge | float(0) | round(0) | int(0)) ~ '%'] %}
{% endif %}
{{ ns.items | join('; ') if ns.items | count > 0 else 'none' }}
security_issues: >-
{% set ns = namespace(items=[]) %}
{% if states('lock.front_door') != 'locked' %}
{% set ns.items = ns.items + ['front door ' ~ states('lock.front_door')] %}
{% endif %}
{% if states('group.locks') != 'locked' %}
{% set ns.items = ns.items + ['locks ' ~ states('group.locks')] %}
{% endif %}
{% if states('group.garage_doors') not in ['closed', 'off'] %}
{% set ns.items = ns.items + ['garage ' ~ states('group.garage_doors')] %}
{% endif %}
{% if states('group.entry_points') not in ['off', 'closed'] %}
{% set ns.items = ns.items + ['entry points ' ~ states('group.entry_points')] %}
{% endif %}
{{ ns.items | join('; ') if ns.items | count > 0 else 'none' }}
security_summary: >-
{% if security_issues == 'none' %}
Secure: locks locked, garage closed, entry points closed.
{% else %}
Needs security attention: {{ security_issues }}.
{% endif %}
climate_summary: >-
{% set down_temp = state_attr('climate.downstairs', 'current_temperature') %}
{% set up_temp = state_attr('climate.upstairs', 'current_temperature') %}
Climate: downstairs {{ down_temp if down_temp is not none else states('climate.downstairs') }}, upstairs {{ up_temp if up_temp is not none else states('climate.upstairs') }}.
safety_issues: >-
{% set ns = namespace(items=[]) %}
{% set fridge = states('sensor.refrigerator_fridge_temp') %}
{% set freezer = states('sensor.refrigerator_freezer_temp') %}
{% set flow = states('sensor.phyn_water_flowing') %}
{% if states('valve.phyn_shutoff_valve') != 'open' %}
{% set ns.items = ns.items + ['Phyn valve ' ~ states('valve.phyn_shutoff_valve')] %}
{% endif %}
{% if flow in ['unknown', 'unavailable', 'none', ''] %}
{% set ns.items = ns.items + ['water telemetry ' ~ flow] %}
{% elif flow in ['on', 'true'] or flow | float(0) > 0 %}
{% set ns.items = ns.items + ['water flowing ' ~ flow] %}
{% endif %}
{% if is_state('binary_sensor.refrigerator_door_open', 'on') %}
{% set ns.items = ns.items + ['refrigerator door open'] %}
{% endif %}
{% if fridge in ['unknown', 'unavailable', 'none', ''] and freezer in ['unknown', 'unavailable', 'none', ''] %}
{% set ns.items = ns.items + ['refrigerator telemetry unavailable'] %}
{% endif %}
{% if fridge not in ['unknown', 'unavailable', 'none', ''] and fridge | float(0) > 45 %}
{% set ns.items = ns.items + ['fridge ' ~ (fridge | float(0) | round(1)) ~ 'F'] %}
{% endif %}
{% if freezer not in ['unknown', 'unavailable', 'none', ''] and freezer | float(0) > 15 %}
{% set ns.items = ns.items + ['freezer ' ~ (freezer | float(0) | round(1)) ~ 'F'] %}
{% endif %}
{% if is_state('binary_sensor.front_door_packages_present', 'on') %}
{% set ns.items = ns.items + ['package at front door'] %}
{% endif %}
{{ ns.items | join('; ') if ns.items | count > 0 else 'none' }}
infra_issues: >-
{% set ns = namespace(items=[]) %}
{% if is_state('binary_sensor.mqtt_broker_problem', 'on') %}
{% set ns.items = ns.items + ['MQTT broker problem'] %}
{% endif %}
{% if is_state('binary_sensor.infra_nebula_sync_degraded', 'on') %}
{% set ns.items = ns.items + ['Nebula Sync DNS degraded'] %}
{% endif %}
{% if is_state('binary_sensor.infra_pihole_iot_dns_degraded', 'on') %}
{% set ns.items = ns.items + ['IoT Pi-hole DNS degraded'] %}
{% endif %}
{% if is_state('input_boolean.infra_duplicati_backup_repair_active', 'on') %}
{% set ns.items = ns.items + ['Duplicati backup repair active'] %}
{% endif %}
{{ ns.items | join('; ') if ns.items | count > 0 else 'none' }}
- variables:
action_items: >-
{% set ns = namespace(items=[]) %}
{% if powerwall_issues != 'none' %}
{% set ns.items = ns.items + ['Powerwall: ' ~ powerwall_issues] %}
{% endif %}
{% if security_issues != 'none' %}
{% set ns.items = ns.items + ['Security: ' ~ security_issues] %}
{% endif %}
{% if safety_issues != 'none' %}
{% set ns.items = ns.items + ['Safety: ' ~ safety_issues] %}
{% endif %}
{% if infra_issues != 'none' %}
{% set ns.items = ns.items + ['Infra: ' ~ infra_issues] %}
{% endif %}
{{ ns.items | join(' | ') if ns.items | count > 0 else 'No material issues found.' }}
fallback_message_one: >-
{% set msg = 'Vacation ' ~ digest_label | lower ~ ' (' ~ vacation_duration | trim ~ '): ' ~ powerwall_summary | trim ~ ' ' ~ security_summary | trim ~ ' ' ~ sitter_summary | trim %}
{{ msg[:447] ~ '...' if msg | length > 450 else msg }}
fallback_message_two: >-
{% set msg = 'Actions: ' ~ action_items | trim ~ ' ' ~ climate_summary | trim %}
{{ msg[:447] ~ '...' if msg | length > 450 else msg }}
joanna_diagnostics: >-
vacation_mode={{ states('input_boolean.vacation_mode') }};
digest={{ digest_mode_value }};
vacation_duration={{ vacation_duration | trim }};
last_digest_ts={{ last_digest_ts }};
powerwall_grid={{ states('binary_sensor.powerwall_grid_status') }};
powerwall_charge={{ states('sensor.powerwall_charge') }};
powerwall_recent_event={{ powerwall_recent_event | trim }};
security={{ security_issues }};
safety={{ safety_issues }};
infra={{ infra_issues }};
sitter={{ sitter_summary | trim }};
climate={{ climate_summary | trim }};
entities=binary_sensor.powerwall_grid_status,sensor.powerwall_charge,group.locks,lock.front_door,group.garage_doors,group.entry_points,input_boolean.house_sitter_present,sensor.vacation_house_sitter_analytics,sensor.phyn_water_flowing,valve.phyn_shutoff_valve,binary_sensor.refrigerator_door_open,sensor.refrigerator_fridge_temp,sensor.refrigerator_freezer_temp,binary_sensor.front_door_packages_present,binary_sensor.mqtt_broker_problem,binary_sensor.infra_nebula_sync_degraded,binary_sensor.infra_pihole_iot_dns_degraded,input_boolean.infra_duplicati_backup_repair_active
- service: script.notify_engine
data:
title: "Vacation {{ digest_label }} House Digest"
value1: "{{ fallback_message_one }}"
who: carlo
group: vacation
level: active
- service: script.notify_engine
data:
title: "Vacation {{ digest_label }} Power/Issues"
value1: "{{ fallback_message_two }}"
who: carlo
group: vacation
level: active
- service: rest_command.bearclaw_command
data:
source: home_assistant_automation.vacation_house_status_digest
user: carlo
context: "Vacation Mode {{ digest_label }} House Status Digest"
domain_hint: ops
lane_hint: joanna.ops
priority: high
async_only: true
metadata:
vacationMode: true
digestMode: "{{ digest_mode_value }}"
houseDigest: true
powerwallImportant: true
text: >-
Vacation {{ digest_label | lower }} house digest snapshot.
Fallback push 1: {{ fallback_message_one }}
Fallback push 2: {{ fallback_message_two }}
Diagnostics: {{ joanna_diagnostics }}
Request: Use the vacation-mode heavier reasoning profile. Return one concise Home Assistant push paragraph under 420 characters. Powerwall/grid status is high signal and must always be mentioned. Mention only material issues or actions; avoid Docker/AP recovery noise unless unresolved. Start with "Vacation {{ digest_label }}:".
- service: script.send_to_logbook
data:
topic: VACATION DIGEST
message: "{{ digest_label }} vacation digest sent. {{ action_items }}"
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.vacation_house_status_digest_last_sent
data:
timestamp: "{{ now().timestamp() }}"
sensor:
- platform: history_stats
name: Vacation House Sitter Visit Count
@@ -257,6 +494,27 @@ automation:
data:
datetime: "{{ (now() - timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') }}"
- alias: 'Vacation Mode House Digest Schedule'
id: ed48b582-107f-4424-ab47-bb54cbd8ad38
mode: single
trigger:
- platform: time
id: morning
at: "10:00:00"
- platform: time
id: night
at: "22:00:00"
condition:
- condition: template
value_template: "{{ is_state('input_boolean.vacation_mode', 'on') }}"
action:
- service: script.vacation_house_status_digest
data:
digest_mode: "{{ trigger.id }}"
- alias: 'Vacation Mode Garage Welcome'
id: 63ac9268-c895-4a1b-b0df-92b5bb8e9d01
mode: single