mirror of
https://github.com/CCOSTAN/Home-AssistantConfig.git
synced 2026-06-27 10:34:26 -07:00
Merge PR #1639: Migrate docker_monitored_containers to modern Group integration
Migrate docker_monitored_containers to modern Group integration
This commit is contained in:
@@ -70,6 +70,7 @@ hacs
|
||||
alexa_media
|
||||
custom_components
|
||||
config/www/community
|
||||
config/.cache/brands/integrations/
|
||||
community
|
||||
image
|
||||
tts
|
||||
@@ -80,3 +81,4 @@ panel-notes
|
||||
docker_14
|
||||
docker_69
|
||||
.codex_tmp/
|
||||
|
||||
|
||||
@@ -194,11 +194,10 @@
|
||||
card_param: cards
|
||||
filter:
|
||||
include:
|
||||
- group: group.docker_monitored_containers
|
||||
- group: switch.docker_monitored_containers
|
||||
options:
|
||||
type: custom:button-card
|
||||
template: bearstone_infra_container_row
|
||||
icon: mdi:docker
|
||||
sort:
|
||||
method: name
|
||||
|
||||
|
||||
@@ -449,7 +449,7 @@
|
||||
card_param: cards
|
||||
filter:
|
||||
include:
|
||||
- group: group.docker_monitored_containers
|
||||
- group: switch.docker_monitored_containers
|
||||
options:
|
||||
type: custom:button-card
|
||||
template: bearstone_infra_container_row
|
||||
@@ -636,4 +636,3 @@
|
||||
name: Download
|
||||
- entity: sensor.speedtest_upload
|
||||
name: Upload
|
||||
|
||||
|
||||
@@ -614,7 +614,7 @@ bearstone_infra_container_row:
|
||||
}
|
||||
const switchEntity = key ? `switch.${key}_container` : '';
|
||||
const switchEntityAlt = key ? `switch.${key}_container_2` : '';
|
||||
const monitored = states['group.docker_monitored_containers']?.attributes?.entity_id || [];
|
||||
const monitored = states['switch.docker_monitored_containers']?.attributes?.entity_id || [];
|
||||
const restartCandidates = key ? [
|
||||
`button.${key}_restart_container`,
|
||||
`button.${key}_restart_container_2`,
|
||||
|
||||
@@ -59,6 +59,7 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this
|
||||
| [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` |
|
||||
| [tesla_model_y.yaml](tesla_model_y.yaml) | Remind the garage and parents to plug in the Model Y after low-battery arrivals and after 8 PM when it is home but not charging. | `sensor.spaceship_battery_level`, `switch.spaceship_charge`, `notify.alexa_media_garage`, `script.notify_engine` |
|
||||
| [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` |
|
||||
| [hass_agent_homepc.yaml](hass_agent_homepc.yaml) | Mirrors PC lock/unlock state from HASS.Agent to the office lamp for instant desk presence cues. | `sensor.carlo_homepc_carlo_homepc_sessionstate`, `switch.office_lamp_switch` |
|
||||
| [sleepiq.yaml](sleepiq.yaml) | Sleep Number presence/snore automations; Overview Health consumes direct SleepIQ integration entities for scores, vitals, pressure, and bed controls. | `sensor.sleepnumber_carlo_carlo_sleep_score`, `sensor.sleepnumber_carlo_stacey_sleep_score`, `number.sleepnumber_carlo_carlo_firmness`, `select.sleepnumber_carlo_foundation_preset_right` |
|
||||
|
||||
@@ -383,6 +383,15 @@ automation:
|
||||
action:
|
||||
- variables:
|
||||
message: "{{ trigger.json.message | default('Joanna: empty reply') }}"
|
||||
telegram_message: "{{ trigger.json.telegram_message | default(message, true) }}"
|
||||
telegram_parse_mode: >-
|
||||
{% set raw = trigger.json.telegram_parse_mode | default('plain_text', true) | string | lower | trim %}
|
||||
{% if raw in ['html', 'plain_text'] %}
|
||||
{{ raw }}
|
||||
{% else %}
|
||||
plain_text
|
||||
{% endif %}
|
||||
telegram_disable_preview: "{{ trigger.json.disable_web_page_preview | default(true, true) }}"
|
||||
level: "{{ trigger.json.level | default('active') | lower }}"
|
||||
inline_keyboard_payload: >-
|
||||
{% set kb = trigger.json.inline_keyboard if trigger.json.inline_keyboard is defined else none %}
|
||||
@@ -408,14 +417,16 @@ automation:
|
||||
- service: telegram_bot.send_message
|
||||
data:
|
||||
chat_id: !secret telegram_allowed_chat_id_carlo
|
||||
message: "{{ message }}"
|
||||
parse_mode: plain_text
|
||||
disable_web_page_preview: true
|
||||
message: "{{ telegram_message }}"
|
||||
parse_mode: "{{ telegram_parse_mode }}"
|
||||
disable_web_page_preview: "{{ telegram_disable_preview }}"
|
||||
inline_keyboard: "{{ inline_keyboard_payload }}"
|
||||
default:
|
||||
- service: script.joanna_send_telegram
|
||||
data:
|
||||
message: "{{ message }}"
|
||||
message: "{{ telegram_message }}"
|
||||
parse_mode: "{{ telegram_parse_mode }}"
|
||||
disable_web_page_preview: "{{ telegram_disable_preview }}"
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: JOANNA
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
|
||||
# -------------------------------------------------------------------
|
||||
# Docker Infrastructure - Host patching and container alerts
|
||||
# Related Issue: 1632, 1584
|
||||
# APT webhook results (docker_10/14/17/69) and container down repairs.
|
||||
# -------------------------------------------------------------------
|
||||
# Related Issue: 1584
|
||||
# Notes: Hosts run weekly Wed 12:00 APT job and POST JSON to webhooks.
|
||||
# Notes: Reboots are handled directly on each host by apt_weekly.sh.
|
||||
# Notes: Reboot staggering: docker_14 first, docker_69 second, docker_10 third.
|
||||
@@ -66,9 +66,10 @@ input_text:
|
||||
name: "docker_69 APT last result"
|
||||
max: 255
|
||||
|
||||
group:
|
||||
docker_monitored_containers:
|
||||
switch:
|
||||
- platform: group
|
||||
name: Docker Monitored Containers
|
||||
unique_id: docker_monitored_containers
|
||||
entities:
|
||||
- switch.cloudflared_kch_container
|
||||
- switch.cloudflared_wp_container
|
||||
@@ -206,14 +207,14 @@ template:
|
||||
unique_id: docker_monitored_container_count
|
||||
icon: mdi:format-list-numbered
|
||||
state: >-
|
||||
{{ state_attr('group.docker_monitored_containers', 'entity_id') | default([], true) | count }}
|
||||
{{ state_attr('switch.docker_monitored_containers', 'entity_id') | default([], true) | count }}
|
||||
|
||||
- name: "Docker Monitored Unavailable Count"
|
||||
unique_id: docker_monitored_unavailable_count
|
||||
icon: mdi:lan-disconnect
|
||||
state: >-
|
||||
{% set ns = namespace(keys=[], unavailable=0) %}
|
||||
{% set monitored = state_attr('group.docker_monitored_containers', 'entity_id') | default([], true) %}
|
||||
{% set monitored = state_attr('switch.docker_monitored_containers', 'entity_id') | default([], true) %}
|
||||
{% for switch_entity in monitored %}
|
||||
{% set key = switch_entity | replace('switch.', '') | regex_replace('_container(?:_2)?$', '') %}
|
||||
{% if key not in ns.keys %}
|
||||
@@ -257,7 +258,7 @@ template:
|
||||
icon: mdi:docker
|
||||
state: >-
|
||||
{% set ns = namespace(keys=[], down=[]) %}
|
||||
{% set monitored = state_attr('group.docker_monitored_containers', 'entity_id') | default([], true) | list %}
|
||||
{% set monitored = state_attr('switch.docker_monitored_containers', 'entity_id') | default([], true) | list %}
|
||||
{% set telemetry_degraded = is_state('binary_sensor.docker_container_telemetry_degraded', 'on') %}
|
||||
{% for switch_entity in monitored %}
|
||||
{% set key = switch_entity | replace('switch.', '') | regex_replace('_container(?:_2)?$', '') %}
|
||||
@@ -301,7 +302,7 @@ template:
|
||||
attributes:
|
||||
down_containers: >-
|
||||
{% set ns = namespace(keys=[], down=[]) %}
|
||||
{% set monitored = state_attr('group.docker_monitored_containers', 'entity_id') | default([], true) | list %}
|
||||
{% set monitored = state_attr('switch.docker_monitored_containers', 'entity_id') | default([], true) | list %}
|
||||
{% set telemetry_degraded = is_state('binary_sensor.docker_container_telemetry_degraded', 'on') %}
|
||||
{% for switch_entity in monitored %}
|
||||
{% set key = switch_entity | replace('switch.', '') | regex_replace('_container(?:_2)?$', '') %}
|
||||
@@ -437,7 +438,7 @@ script:
|
||||
status_entity_alt: "binary_sensor.{{ container_key }}_status_2"
|
||||
state_entity: "sensor.{{ container_key }}_state"
|
||||
state_entity_alt: "sensor.{{ container_key }}_state_2"
|
||||
monitored_switches: "{{ state_attr('group.docker_monitored_containers', 'entity_id') | default([], true) }}"
|
||||
monitored_switches: "{{ state_attr('switch.docker_monitored_containers', 'entity_id') | default([], true) }}"
|
||||
tracked_container: "{{ switch_entity in monitored_switches or switch_entity_alt in monitored_switches }}"
|
||||
effective_entity: >-
|
||||
{% if expand(status_entity) | count > 0 %}
|
||||
@@ -798,7 +799,7 @@ automation:
|
||||
entity_id: "{{ trigger.event.data.entity_id | default('') }}"
|
||||
old_state: "{{ (trigger.event.data.old_state.state if trigger.event.data.old_state is not none else '') | lower }}"
|
||||
new_state: "{{ (trigger.event.data.new_state.state if trigger.event.data.new_state is not none else '') | lower }}"
|
||||
monitored_switches: "{{ state_attr('group.docker_monitored_containers', 'entity_id') | default([], true) | list }}"
|
||||
monitored_switches: "{{ state_attr('switch.docker_monitored_containers', 'entity_id') | default([], true) | list }}"
|
||||
is_monitored_container_event: >-
|
||||
{% set ent = entity_id %}
|
||||
{% if ent.startswith('switch.') and (ent.endswith('_container') or ent.endswith('_container_2')) %}
|
||||
@@ -888,7 +889,7 @@ automation:
|
||||
minutes: "/55"
|
||||
action:
|
||||
- variables:
|
||||
monitored_switches: "{{ state_attr('group.docker_monitored_containers', 'entity_id') | default([], true) | list }}"
|
||||
monitored_switches: "{{ state_attr('switch.docker_monitored_containers', 'entity_id') | default([], true) | list }}"
|
||||
- repeat:
|
||||
for_each: "{{ monitored_switches }}"
|
||||
sequence:
|
||||
|
||||
@@ -330,13 +330,8 @@ automation:
|
||||
|
||||
trigger:
|
||||
- platform: time_pattern
|
||||
minutes: '/45'
|
||||
- platform: state
|
||||
entity_id:
|
||||
- cover.large_garage_door
|
||||
- cover.small_garage_door
|
||||
to: 'open'
|
||||
for: "00:01:00"
|
||||
minutes: '/30'
|
||||
|
||||
- platform: state
|
||||
entity_id: group.family
|
||||
to: not_home
|
||||
@@ -392,46 +387,3 @@ automation:
|
||||
- service: script.speech_engine
|
||||
data:
|
||||
value1: "Check the garage doors. The Small garage is {{ states('cover.small_garage_door')}} and the large garage is {{ states('cover.large_garage_door')}} [Always mention the specific garage door that is currently open and remind us to close it for the night]"
|
||||
|
||||
# - alias: 'Garage Camera on Alexa Shows'
|
||||
# id: 4373df2a-77f2-4e19-be7c-46c7b27ca583
|
||||
# mode: single
|
||||
# trigger:
|
||||
# - platform: state
|
||||
# entity_id:
|
||||
# - cover.large_garage_door
|
||||
# - cover.small_garage_door
|
||||
# from: 'closed'
|
||||
# to: 'open'
|
||||
# for: "00:00:15"
|
||||
|
||||
# - platform: state
|
||||
# entity_id: binary_sensor.mcu1_gpio12 #interior Garage Doors
|
||||
# from: 'off'
|
||||
# to: 'on'
|
||||
# for: "00:00:05"
|
||||
|
||||
# - platform: state
|
||||
# entity_id:
|
||||
# - person.carlo
|
||||
# - person.stacey
|
||||
# - person.paige
|
||||
# - person.justin
|
||||
# to: 'not_home'
|
||||
# from: 'home'
|
||||
|
||||
# action:
|
||||
# - service: media_player.play_media
|
||||
# target:
|
||||
# entity_id: media_player.kitchen
|
||||
# data:
|
||||
# media_content_id: 'show garage camera from home assistant'
|
||||
# media_content_type: custom
|
||||
# - delay: '00:20:00'
|
||||
# - service: media_player.play_media
|
||||
# target:
|
||||
# entity_id: media_player.kitchen
|
||||
# data:
|
||||
# media_content_id: 'hide garage camera'
|
||||
# media_content_type: custom
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# 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.
|
||||
# Notes: Front-door package detection waits 3 minutes after person activity or 20 seconds after the front door relocks, then analyzes a short live stream for better package accuracy.
|
||||
# Docs: https://llmvision.gitbook.io/getting-started/usage/image-analyzer
|
||||
######################################################################
|
||||
|
||||
@@ -129,30 +129,79 @@ automation:
|
||||
- platform: numeric_state
|
||||
entity_id: sensor.frontdoorbell_person_active_count_2
|
||||
above: 0
|
||||
for: "00:03:00"
|
||||
id: person_count
|
||||
- platform: state
|
||||
entity_id: lock.front_door
|
||||
from: unlocked
|
||||
to: locked
|
||||
id: front_door_locked
|
||||
- platform: state
|
||||
entity_id: input_button.llmvision_front_door_package_check
|
||||
id: manual_check
|
||||
variables:
|
||||
trigger_source: >-
|
||||
{% if trigger.id == 'manual_check' %}
|
||||
manual button
|
||||
{% elif trigger.id == 'front_door_locked' %}
|
||||
front door relock
|
||||
{% else %}
|
||||
front door person activity
|
||||
{% endif %}
|
||||
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.
|
||||
Examine these front door camera frames for delivery packages. Focus on the porch and doorstep area
|
||||
near the wall and doormat in the lower-right part of the image. Treat cardboard boxes, padded mailers,
|
||||
poly bags, and shopping bags as packages. Ignore the street, cars, landscaping, and anything not resting
|
||||
on the porch or doorstep. If any package is clearly visible, respond exactly: on. If no package is
|
||||
clearly visible, respond exactly: off. No other words.
|
||||
action:
|
||||
- service: llmvision.data_analyzer
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ trigger.id == 'person_count' }}"
|
||||
sequence:
|
||||
- delay: "00:03:00"
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: "{{ trigger.id == 'front_door_locked' }}"
|
||||
sequence:
|
||||
- delay: "00:00:20"
|
||||
- service: llmvision.stream_analyzer
|
||||
response_variable: llmvision_result
|
||||
data:
|
||||
provider: !secret llmvision_provider_entry
|
||||
model: gpt-4.1-nano
|
||||
model: gpt-4.1-mini
|
||||
message: "{{ prompt_text }}"
|
||||
sensor_entity: input_boolean.front_door_packages_present
|
||||
image_entity:
|
||||
- camera.frontdoorbell
|
||||
duration: 6
|
||||
max_frames: 5
|
||||
include_filename: false
|
||||
target_width: 1280
|
||||
target_width: 1920
|
||||
max_tokens: 16
|
||||
expose_images: true
|
||||
- variables:
|
||||
normalized_response: "{{ llmvision_result.response_text | default('') | trim | lower }}"
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ normalized_response in ['on', 'yes', 'true']
|
||||
or normalized_response.startswith('on')
|
||||
or normalized_response.startswith('yes') }}
|
||||
sequence:
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ normalized_response in ['off', 'no', 'false']
|
||||
or normalized_response.startswith('off')
|
||||
or normalized_response.startswith('no') }}
|
||||
sequence:
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id: input_boolean.front_door_packages_present
|
||||
- service: input_text.set_value
|
||||
target:
|
||||
entity_id: input_text.llmvision_front_door_last_response
|
||||
@@ -181,7 +230,7 @@ automation:
|
||||
data:
|
||||
topic: PACKAGES
|
||||
message: >-
|
||||
Front door package vision check ran via {{ 'manual button' if trigger.id == 'manual_check' else 'front door person activity' }}
|
||||
Front door package vision check ran via {{ trigger_source }}
|
||||
and returned {{ llmvision_result.response_text | default(states('input_boolean.front_door_packages_present')) | lower }}.
|
||||
- choose:
|
||||
- conditions:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
# Script wrappers for Telegram messaging using UI-configured integration.
|
||||
# -------------------------------------------------------------------
|
||||
# Notes: Do not add `telegram_bot:` YAML here; integration is UI-only.
|
||||
# Notes: Joanna transport sends as plain_text to avoid Telegram parse-entity failures.
|
||||
# Notes: Joanna transport defaults to plain_text, but can opt into HTML when the appliance provides a vetted rich message.
|
||||
# Notes: Keep Skills logic in docker_17/codex_appliance; this package is delivery/transport only.
|
||||
######################################################################
|
||||
|
||||
@@ -20,9 +20,23 @@ script:
|
||||
message:
|
||||
description: Message body to send.
|
||||
example: Joanna is online.
|
||||
parse_mode:
|
||||
description: Telegram parse mode (`plain_text` or `html`).
|
||||
example: html
|
||||
disable_web_page_preview:
|
||||
description: Whether Telegram should suppress web page previews.
|
||||
example: true
|
||||
sequence:
|
||||
- variables:
|
||||
chunk_size: 3400
|
||||
requested_parse_mode: >-
|
||||
{% set raw = parse_mode | default('plain_text', true) | string | lower | trim %}
|
||||
{% if raw in ['html', 'plain_text'] %}
|
||||
{{ raw }}
|
||||
{% else %}
|
||||
plain_text
|
||||
{% endif %}
|
||||
preview_disabled: "{{ disable_web_page_preview | default(true, true) }}"
|
||||
normalized_message: >-
|
||||
{% set raw = message | default('', true) | string %}
|
||||
{{ raw | replace('\r\n', '\n') | replace('\r', '\n') | trim }}
|
||||
@@ -60,8 +74,8 @@ script:
|
||||
data:
|
||||
chat_id: !secret telegram_allowed_chat_id_carlo
|
||||
message: "{{ chunk_message }}"
|
||||
parse_mode: plain_text
|
||||
disable_web_page_preview: true
|
||||
parse_mode: "{{ requested_parse_mode }}"
|
||||
disable_web_page_preview: "{{ preview_disabled }}"
|
||||
response_variable: telegram_send_response
|
||||
- choose:
|
||||
- conditions:
|
||||
@@ -77,4 +91,4 @@ script:
|
||||
chat_id: !secret telegram_allowed_chat_id_carlo
|
||||
message: "{{ fallback_message if fallback_message | length > 0 else 'Joanna: message delivery fallback (content omitted)' }}"
|
||||
parse_mode: plain_text
|
||||
disable_web_page_preview: true
|
||||
disable_web_page_preview: "{{ preview_disabled }}"
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
######################################################################
|
||||
# @CCOSTAN - Follow Me on X
|
||||
# For more info visit https://www.vcloudinfo.com/click-here
|
||||
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
|
||||
# -------------------------------------------------------------------
|
||||
# Tesla Model Y - Arrival and nightly plug-in reminders
|
||||
# Garage speech + parents push reminders when the Tesla comes home low.
|
||||
# -------------------------------------------------------------------
|
||||
# Related Issue: 1279
|
||||
# Notes: Expects Tesla Fleet UI entities `sensor.spaceship_battery_level`
|
||||
# and `switch.spaceship_charge`.
|
||||
# Notes: Uses `device_tracker.spaceship_location` for arrival/home state.
|
||||
# Notes: The nightly parents reminder starts at 8 PM, waits until the
|
||||
# car is home, then loops every 30 minutes via a custom event until it
|
||||
# is charging or no longer home.
|
||||
######################################################################
|
||||
|
||||
automation:
|
||||
- alias: "Tesla Model Y - Garage Plug In Reminder"
|
||||
id: 6a873341-c823-4d5d-9d42-fc2df52b93db
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: device_tracker.spaceship_location
|
||||
to: 'home'
|
||||
condition:
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ trigger.from_state is not none and
|
||||
trigger.from_state.state not in ['home', 'unknown', 'unavailable'] }}
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set battery = states('sensor.spaceship_battery_level') %}
|
||||
{{ battery not in ['unknown', 'unavailable', 'none', ''] and
|
||||
(battery | float(100)) < 50 and
|
||||
is_state('switch.spaceship_charge', 'off') }}
|
||||
action:
|
||||
- wait_for_trigger:
|
||||
- platform: state
|
||||
entity_id: cover.large_garage_door
|
||||
from: 'closed'
|
||||
to: 'open'
|
||||
for: '00:03:20'
|
||||
timeout: '00:10:00'
|
||||
continue_on_timeout: false
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set battery = states('sensor.spaceship_battery_level') %}
|
||||
{{ battery not in ['unknown', 'unavailable', 'none', ''] and
|
||||
(battery | float(100)) < 50 and
|
||||
is_state('switch.spaceship_charge', 'off') }}
|
||||
- service: notify.alexa_media_garage
|
||||
data:
|
||||
message: >-
|
||||
Reminder: the Tesla battery is at
|
||||
{{ states('sensor.spaceship_battery_level') | float(0) | round(0) }} percent.
|
||||
Please plug in the Model Y.
|
||||
data:
|
||||
type: announce
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "TESLA"
|
||||
message: >-
|
||||
Garage reminder announced to plug in the Model Y at
|
||||
{{ states('sensor.spaceship_battery_level') | float(0) | round(0) }} percent.
|
||||
|
||||
- alias: "Tesla Model Y - Nightly Plug In Reminder"
|
||||
id: 8b243b63-f5c3-4436-b596-0ec00a2108ab
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: time
|
||||
at: '20:00:00'
|
||||
- platform: event
|
||||
event_type: event_tesla_model_y_nightly_loop
|
||||
action:
|
||||
- wait_template: "{{ is_state('device_tracker.spaceship_location', 'home') }}"
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set battery = states('sensor.spaceship_battery_level') %}
|
||||
{{ is_state('device_tracker.spaceship_location', 'home') and
|
||||
battery not in ['unknown', 'unavailable', 'none', ''] and
|
||||
(battery | float(100)) < 50 and
|
||||
is_state('switch.spaceship_charge', 'off') }}
|
||||
- service: script.notify_engine
|
||||
data:
|
||||
title: "Tesla Plug In Reminder"
|
||||
value1: >-
|
||||
The Model Y is home, below 50 percent, and not plugged in.
|
||||
Current battery:
|
||||
{{ states('sensor.spaceship_battery_level') | float(0) | round(0) }} percent.
|
||||
who: 'parents'
|
||||
group: 'Tesla_Model_Y'
|
||||
- service: script.send_to_logbook
|
||||
data:
|
||||
topic: "TESLA"
|
||||
message: >-
|
||||
Nightly plug-in reminder sent because the Model Y is home below 50 percent and not charging.
|
||||
- delay: '00:30:00'
|
||||
- event: event_tesla_model_y_nightly_loop
|
||||
@@ -131,6 +131,12 @@
|
||||
{%- endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro front_door_packages() -%}
|
||||
{% if is_state('binary_sensor.front_door_packages_present', 'on') -%}
|
||||
There appears to be a package waiting at the front door.
|
||||
{%- endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro medicine() -%}
|
||||
{% if is_state('input_boolean.medicine', 'off') -%}
|
||||
It looks like Carlo has not taken his medicine yet. Please make sure Carlo takes his medicine now.
|
||||
@@ -293,6 +299,8 @@
|
||||
{{ window_check() }}
|
||||
{% endif %}
|
||||
|
||||
{{ front_door_packages() }}
|
||||
|
||||
{{ NewDevice | default }}
|
||||
|
||||
{% if call_garbage_day == 1 %}
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Open OneNote</title>
|
||||
<style>
|
||||
:root { color-scheme: light; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
background: linear-gradient(180deg, #f5f7fb 0%, #e8eef8 100%);
|
||||
color: #122033;
|
||||
}
|
||||
main {
|
||||
max-width: 32rem;
|
||||
margin: 0 auto;
|
||||
min-height: 100vh;
|
||||
padding: 2rem 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
.card {
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
border: 1px solid rgba(18, 32, 51, 0.08);
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 18px 40px rgba(18, 32, 51, 0.12);
|
||||
padding: 1.25rem;
|
||||
}
|
||||
h1 {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 1.35rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.title {
|
||||
margin-top: 0.75rem;
|
||||
font-size: 0.95rem;
|
||||
color: #41556f;
|
||||
word-break: break-word;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.button {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
padding: 0.9rem 1rem;
|
||||
border-radius: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.button.primary {
|
||||
background: #166534;
|
||||
color: #fff;
|
||||
}
|
||||
.button.secondary {
|
||||
background: #fff;
|
||||
color: #122033;
|
||||
border: 1px solid rgba(18, 32, 51, 0.14);
|
||||
}
|
||||
.hint {
|
||||
font-size: 0.88rem;
|
||||
color: #5c708a;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<section class="card">
|
||||
<h1>Opening OneNote</h1>
|
||||
<p>Joanna is handing this note to the OneNote app now.</p>
|
||||
<p id="note-title" class="title"></p>
|
||||
<div class="actions">
|
||||
<a id="app-link" class="button primary" href="#">Open in OneNote App</a>
|
||||
<a id="web-link" class="button secondary" href="https://www.onenote.com/">Open Web Copy</a>
|
||||
</div>
|
||||
<p class="hint">If the app does not open automatically in a second or two, tap the OneNote button.</p>
|
||||
</section>
|
||||
</main>
|
||||
<script>
|
||||
(function () {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var clientUrl = String(params.get('client') || '').trim();
|
||||
var webUrl = String(params.get('web') || '').trim() || 'https://www.onenote.com/';
|
||||
var title = String(params.get('title') || '').trim();
|
||||
var appLink = document.getElementById('app-link');
|
||||
var webLink = document.getElementById('web-link');
|
||||
var titleNode = document.getElementById('note-title');
|
||||
|
||||
if (title) {
|
||||
titleNode.textContent = title;
|
||||
} else {
|
||||
titleNode.textContent = 'OneNote note';
|
||||
}
|
||||
|
||||
webLink.href = webUrl;
|
||||
if (!/^onenote:/i.test(clientUrl)) {
|
||||
appLink.style.display = 'none';
|
||||
window.location.replace(webUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
appLink.href = clientUrl;
|
||||
var fallbackTimer = window.setTimeout(function () {
|
||||
window.location.replace(webUrl);
|
||||
}, 1400);
|
||||
var cancelFallback = function () {
|
||||
window.clearTimeout(fallbackTimer);
|
||||
};
|
||||
window.addEventListener('pagehide', cancelFallback, { once: true });
|
||||
document.addEventListener('visibilitychange', function () {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
cancelFallback();
|
||||
}
|
||||
}, { once: true });
|
||||
window.location.href = clientUrl;
|
||||
}());
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user