diff --git a/config/.cache/brands/integrations/_placeholder/icon.png b/config/.cache/brands/integrations/_placeholder/icon.png new file mode 100644 index 00000000..02cc160d Binary files /dev/null and b/config/.cache/brands/integrations/_placeholder/icon.png differ diff --git a/config/.cache/brands/integrations/ai_task/icon.png b/config/.cache/brands/integrations/ai_task/icon.png new file mode 100644 index 00000000..54615129 Binary files /dev/null and b/config/.cache/brands/integrations/ai_task/icon.png differ diff --git a/config/.cache/brands/integrations/airly/icon.png b/config/.cache/brands/integrations/airly/icon.png new file mode 100644 index 00000000..9ead38d3 Binary files /dev/null and b/config/.cache/brands/integrations/airly/icon.png differ diff --git a/config/.cache/brands/integrations/alarm_control_panel/icon.png b/config/.cache/brands/integrations/alarm_control_panel/icon.png new file mode 100644 index 00000000..cb75862b Binary files /dev/null and b/config/.cache/brands/integrations/alarm_control_panel/icon.png differ diff --git a/config/.cache/brands/integrations/alert/icon.png b/config/.cache/brands/integrations/alert/icon.png new file mode 100644 index 00000000..ee55f2f6 Binary files /dev/null and b/config/.cache/brands/integrations/alert/icon.png differ diff --git a/config/.cache/brands/integrations/alexa/icon.png b/config/.cache/brands/integrations/alexa/icon.png new file mode 100644 index 00000000..605cdf60 Binary files /dev/null and b/config/.cache/brands/integrations/alexa/icon.png differ diff --git a/config/.cache/brands/integrations/analytics/icon.png b/config/.cache/brands/integrations/analytics/icon.png new file mode 100644 index 00000000..e411a7b8 Binary files /dev/null and b/config/.cache/brands/integrations/analytics/icon.png differ diff --git a/config/.cache/brands/integrations/api/icon.png b/config/.cache/brands/integrations/api/icon.png new file mode 100644 index 00000000..226fb689 Binary files /dev/null and b/config/.cache/brands/integrations/api/icon.png differ diff --git a/config/.cache/brands/integrations/application_credentials/icon.png b/config/.cache/brands/integrations/application_credentials/icon.png new file mode 100644 index 00000000..3c1836f7 Binary files /dev/null and b/config/.cache/brands/integrations/application_credentials/icon.png differ diff --git a/config/.cache/brands/integrations/assist_pipeline/icon.png b/config/.cache/brands/integrations/assist_pipeline/icon.png new file mode 100644 index 00000000..da4e5159 Binary files /dev/null and b/config/.cache/brands/integrations/assist_pipeline/icon.png differ diff --git a/config/.cache/brands/integrations/august/icon.png b/config/.cache/brands/integrations/august/icon.png new file mode 100644 index 00000000..2bfe9cdd Binary files /dev/null and b/config/.cache/brands/integrations/august/icon.png differ diff --git a/config/.cache/brands/integrations/auth/icon.png b/config/.cache/brands/integrations/auth/icon.png new file mode 100644 index 00000000..bfeea1c7 Binary files /dev/null and b/config/.cache/brands/integrations/auth/icon.png differ diff --git a/config/.cache/brands/integrations/backup/icon.png b/config/.cache/brands/integrations/backup/icon.png new file mode 100644 index 00000000..a60580fb Binary files /dev/null and b/config/.cache/brands/integrations/backup/icon.png differ diff --git a/config/.cache/brands/integrations/battery_notes/icon.png b/config/.cache/brands/integrations/battery_notes/icon.png new file mode 100644 index 00000000..8f5e6c7d Binary files /dev/null and b/config/.cache/brands/integrations/battery_notes/icon.png differ diff --git a/config/.cache/brands/integrations/binary_sensor/icon.png b/config/.cache/brands/integrations/binary_sensor/icon.png new file mode 100644 index 00000000..aa4e658a Binary files /dev/null and b/config/.cache/brands/integrations/binary_sensor/icon.png differ diff --git a/config/.cache/brands/integrations/blink/icon.png b/config/.cache/brands/integrations/blink/icon.png new file mode 100644 index 00000000..17f545e8 Binary files /dev/null and b/config/.cache/brands/integrations/blink/icon.png differ diff --git a/config/.cache/brands/integrations/blitzortung/icon.png b/config/.cache/brands/integrations/blitzortung/icon.png new file mode 100644 index 00000000..ec6dc1c1 Binary files /dev/null and b/config/.cache/brands/integrations/blitzortung/icon.png differ diff --git a/config/.cache/brands/integrations/blueprint/icon.png b/config/.cache/brands/integrations/blueprint/icon.png new file mode 100644 index 00000000..aeadc6d5 Binary files /dev/null and b/config/.cache/brands/integrations/blueprint/icon.png differ diff --git a/config/.cache/brands/integrations/bluetooth/icon.png b/config/.cache/brands/integrations/bluetooth/icon.png new file mode 100644 index 00000000..4ee2e081 Binary files /dev/null and b/config/.cache/brands/integrations/bluetooth/icon.png differ diff --git a/config/.cache/brands/integrations/bluetooth_adapters/icon.png b/config/.cache/brands/integrations/bluetooth_adapters/icon.png new file mode 100644 index 00000000..641b5a21 Binary files /dev/null and b/config/.cache/brands/integrations/bluetooth_adapters/icon.png differ diff --git a/config/.cache/brands/integrations/brands/icon.png b/config/.cache/brands/integrations/brands/icon.png new file mode 100644 index 00000000..e69de29b diff --git a/config/.cache/brands/integrations/button/icon.png b/config/.cache/brands/integrations/button/icon.png new file mode 100644 index 00000000..a16b6b4e Binary files /dev/null and b/config/.cache/brands/integrations/button/icon.png differ diff --git a/config/.cache/brands/integrations/calendar/icon.png b/config/.cache/brands/integrations/calendar/icon.png new file mode 100644 index 00000000..30d782ad Binary files /dev/null and b/config/.cache/brands/integrations/calendar/icon.png differ diff --git a/config/.cache/brands/integrations/camera/icon.png b/config/.cache/brands/integrations/camera/icon.png new file mode 100644 index 00000000..69a2a575 Binary files /dev/null and b/config/.cache/brands/integrations/camera/icon.png differ diff --git a/config/.cache/brands/integrations/cast/icon.png b/config/.cache/brands/integrations/cast/icon.png new file mode 100644 index 00000000..55119969 Binary files /dev/null and b/config/.cache/brands/integrations/cast/icon.png differ diff --git a/config/.cache/brands/integrations/climate/icon.png b/config/.cache/brands/integrations/climate/icon.png new file mode 100644 index 00000000..ee58d5f5 Binary files /dev/null and b/config/.cache/brands/integrations/climate/icon.png differ diff --git a/config/.cache/brands/integrations/cloud/icon.png b/config/.cache/brands/integrations/cloud/icon.png new file mode 100644 index 00000000..874cd91d Binary files /dev/null and b/config/.cache/brands/integrations/cloud/icon.png differ diff --git a/config/.cache/brands/integrations/co2signal/icon.png b/config/.cache/brands/integrations/co2signal/icon.png new file mode 100644 index 00000000..3c2bada0 Binary files /dev/null and b/config/.cache/brands/integrations/co2signal/icon.png differ diff --git a/config/.cache/brands/integrations/command_line/icon.png b/config/.cache/brands/integrations/command_line/icon.png new file mode 100644 index 00000000..a3ec392f Binary files /dev/null and b/config/.cache/brands/integrations/command_line/icon.png differ diff --git a/config/.cache/brands/integrations/config/icon.png b/config/.cache/brands/integrations/config/icon.png new file mode 100644 index 00000000..f23d170e Binary files /dev/null and b/config/.cache/brands/integrations/config/icon.png differ diff --git a/config/.cache/brands/integrations/conversation/icon.png b/config/.cache/brands/integrations/conversation/icon.png new file mode 100644 index 00000000..acb638a3 Binary files /dev/null and b/config/.cache/brands/integrations/conversation/icon.png differ diff --git a/config/.cache/brands/integrations/counter/icon.png b/config/.cache/brands/integrations/counter/icon.png new file mode 100644 index 00000000..7c116040 Binary files /dev/null and b/config/.cache/brands/integrations/counter/icon.png differ diff --git a/config/.cache/brands/integrations/cover/icon.png b/config/.cache/brands/integrations/cover/icon.png new file mode 100644 index 00000000..c29ea574 Binary files /dev/null and b/config/.cache/brands/integrations/cover/icon.png differ diff --git a/config/.cache/brands/integrations/default_config/icon.png b/config/.cache/brands/integrations/default_config/icon.png new file mode 100644 index 00000000..65508a5b Binary files /dev/null and b/config/.cache/brands/integrations/default_config/icon.png differ diff --git a/config/.cache/brands/integrations/device_automation/icon.png b/config/.cache/brands/integrations/device_automation/icon.png new file mode 100644 index 00000000..94af35b7 Binary files /dev/null and b/config/.cache/brands/integrations/device_automation/icon.png differ diff --git a/config/.cache/brands/integrations/device_tracker/icon.png b/config/.cache/brands/integrations/device_tracker/icon.png new file mode 100644 index 00000000..cec946d5 Binary files /dev/null and b/config/.cache/brands/integrations/device_tracker/icon.png differ diff --git a/config/.cache/brands/integrations/dhcp/icon.png b/config/.cache/brands/integrations/dhcp/icon.png new file mode 100644 index 00000000..8974c5ab Binary files /dev/null and b/config/.cache/brands/integrations/dhcp/icon.png differ diff --git a/config/.cache/brands/integrations/diagnostics/icon.png b/config/.cache/brands/integrations/diagnostics/icon.png new file mode 100644 index 00000000..93cb2748 Binary files /dev/null and b/config/.cache/brands/integrations/diagnostics/icon.png differ diff --git a/config/.cache/brands/integrations/dlna_dmr/icon.png b/config/.cache/brands/integrations/dlna_dmr/icon.png new file mode 100644 index 00000000..763d2422 Binary files /dev/null and b/config/.cache/brands/integrations/dlna_dmr/icon.png differ diff --git a/config/.cache/brands/integrations/dreame_vacuum/icon.png b/config/.cache/brands/integrations/dreame_vacuum/icon.png new file mode 100644 index 00000000..c59df818 Binary files /dev/null and b/config/.cache/brands/integrations/dreame_vacuum/icon.png differ diff --git a/config/.cache/brands/integrations/duke_energy/icon.png b/config/.cache/brands/integrations/duke_energy/icon.png new file mode 100644 index 00000000..c7e46d2d Binary files /dev/null and b/config/.cache/brands/integrations/duke_energy/icon.png differ diff --git a/config/.cache/brands/integrations/econet/icon.png b/config/.cache/brands/integrations/econet/icon.png new file mode 100644 index 00000000..8f47c948 Binary files /dev/null and b/config/.cache/brands/integrations/econet/icon.png differ diff --git a/config/.cache/brands/integrations/energy/icon.png b/config/.cache/brands/integrations/energy/icon.png new file mode 100644 index 00000000..ba5bc370 Binary files /dev/null and b/config/.cache/brands/integrations/energy/icon.png differ diff --git a/config/.cache/brands/integrations/esphome/icon.png b/config/.cache/brands/integrations/esphome/icon.png new file mode 100644 index 00000000..0a4a375d Binary files /dev/null and b/config/.cache/brands/integrations/esphome/icon.png differ diff --git a/config/.cache/brands/integrations/event/icon.png b/config/.cache/brands/integrations/event/icon.png new file mode 100644 index 00000000..cd40834b Binary files /dev/null and b/config/.cache/brands/integrations/event/icon.png differ diff --git a/config/.cache/brands/integrations/fan/icon.png b/config/.cache/brands/integrations/fan/icon.png new file mode 100644 index 00000000..e7c61fe8 Binary files /dev/null and b/config/.cache/brands/integrations/fan/icon.png differ diff --git a/config/.cache/brands/integrations/feedreader/icon.png b/config/.cache/brands/integrations/feedreader/icon.png new file mode 100644 index 00000000..425a6e56 Binary files /dev/null and b/config/.cache/brands/integrations/feedreader/icon.png differ diff --git a/config/.cache/brands/integrations/ffmpeg/icon.png b/config/.cache/brands/integrations/ffmpeg/icon.png new file mode 100644 index 00000000..96c2ba68 Binary files /dev/null and b/config/.cache/brands/integrations/ffmpeg/icon.png differ diff --git a/config/.cache/brands/integrations/file/icon.png b/config/.cache/brands/integrations/file/icon.png new file mode 100644 index 00000000..933266ac Binary files /dev/null and b/config/.cache/brands/integrations/file/icon.png differ diff --git a/config/.cache/brands/integrations/file_upload/icon.png b/config/.cache/brands/integrations/file_upload/icon.png new file mode 100644 index 00000000..4482e3f8 Binary files /dev/null and b/config/.cache/brands/integrations/file_upload/icon.png differ diff --git a/config/.cache/brands/integrations/flux_led/icon.png b/config/.cache/brands/integrations/flux_led/icon.png new file mode 100644 index 00000000..27d9e3f2 Binary files /dev/null and b/config/.cache/brands/integrations/flux_led/icon.png differ diff --git a/config/.cache/brands/integrations/frigate/icon.png b/config/.cache/brands/integrations/frigate/icon.png new file mode 100644 index 00000000..a6cbb8b9 Binary files /dev/null and b/config/.cache/brands/integrations/frigate/icon.png differ diff --git a/config/.cache/brands/integrations/frontend/icon.png b/config/.cache/brands/integrations/frontend/icon.png new file mode 100644 index 00000000..e5267faf Binary files /dev/null and b/config/.cache/brands/integrations/frontend/icon.png differ diff --git a/config/.cache/brands/integrations/fully_kiosk/icon.png b/config/.cache/brands/integrations/fully_kiosk/icon.png new file mode 100644 index 00000000..48cbd767 Binary files /dev/null and b/config/.cache/brands/integrations/fully_kiosk/icon.png differ diff --git a/config/.cache/brands/integrations/geo_location/icon.png b/config/.cache/brands/integrations/geo_location/icon.png new file mode 100644 index 00000000..9e6d1f95 Binary files /dev/null and b/config/.cache/brands/integrations/geo_location/icon.png differ diff --git a/config/.cache/brands/integrations/glances/icon.png b/config/.cache/brands/integrations/glances/icon.png new file mode 100644 index 00000000..fda5b488 Binary files /dev/null and b/config/.cache/brands/integrations/glances/icon.png differ diff --git a/config/.cache/brands/integrations/go2rtc/icon.png b/config/.cache/brands/integrations/go2rtc/icon.png new file mode 100644 index 00000000..1c2f4b82 Binary files /dev/null and b/config/.cache/brands/integrations/go2rtc/icon.png differ diff --git a/config/.cache/brands/integrations/google_generative_ai_conversation/icon.png b/config/.cache/brands/integrations/google_generative_ai_conversation/icon.png new file mode 100644 index 00000000..ceed146b Binary files /dev/null and b/config/.cache/brands/integrations/google_generative_ai_conversation/icon.png differ diff --git a/config/.cache/brands/integrations/group/icon.png b/config/.cache/brands/integrations/group/icon.png new file mode 100644 index 00000000..e33c8aae Binary files /dev/null and b/config/.cache/brands/integrations/group/icon.png differ diff --git a/config/.cache/brands/integrations/hardware/icon.png b/config/.cache/brands/integrations/hardware/icon.png new file mode 100644 index 00000000..c388aaf0 Binary files /dev/null and b/config/.cache/brands/integrations/hardware/icon.png differ diff --git a/config/.cache/brands/integrations/history/icon.png b/config/.cache/brands/integrations/history/icon.png new file mode 100644 index 00000000..7136e837 Binary files /dev/null and b/config/.cache/brands/integrations/history/icon.png differ diff --git a/config/.cache/brands/integrations/history_stats/icon.png b/config/.cache/brands/integrations/history_stats/icon.png new file mode 100644 index 00000000..09fe90f3 Binary files /dev/null and b/config/.cache/brands/integrations/history_stats/icon.png differ diff --git a/config/.cache/brands/integrations/homeassistant/icon.png b/config/.cache/brands/integrations/homeassistant/icon.png new file mode 100644 index 00000000..39f0c14e Binary files /dev/null and b/config/.cache/brands/integrations/homeassistant/icon.png differ diff --git a/config/.cache/brands/integrations/homeassistant_alerts/icon.png b/config/.cache/brands/integrations/homeassistant_alerts/icon.png new file mode 100644 index 00000000..8166b8d9 Binary files /dev/null and b/config/.cache/brands/integrations/homeassistant_alerts/icon.png differ diff --git a/config/.cache/brands/integrations/homekit/icon.png b/config/.cache/brands/integrations/homekit/icon.png new file mode 100644 index 00000000..defa5d0b Binary files /dev/null and b/config/.cache/brands/integrations/homekit/icon.png differ diff --git a/config/.cache/brands/integrations/homekit_controller/icon.png b/config/.cache/brands/integrations/homekit_controller/icon.png new file mode 100644 index 00000000..defa5d0b Binary files /dev/null and b/config/.cache/brands/integrations/homekit_controller/icon.png differ diff --git a/config/.cache/brands/integrations/http/icon.png b/config/.cache/brands/integrations/http/icon.png new file mode 100644 index 00000000..3f9ab041 Binary files /dev/null and b/config/.cache/brands/integrations/http/icon.png differ diff --git a/config/.cache/brands/integrations/hue/icon.png b/config/.cache/brands/integrations/hue/icon.png new file mode 100644 index 00000000..7826f433 Binary files /dev/null and b/config/.cache/brands/integrations/hue/icon.png differ diff --git a/config/.cache/brands/integrations/humidifier/icon.png b/config/.cache/brands/integrations/humidifier/icon.png new file mode 100644 index 00000000..03c1a638 Binary files /dev/null and b/config/.cache/brands/integrations/humidifier/icon.png differ diff --git a/config/.cache/brands/integrations/ifttt/icon.png b/config/.cache/brands/integrations/ifttt/icon.png new file mode 100644 index 00000000..decf21e0 Binary files /dev/null and b/config/.cache/brands/integrations/ifttt/icon.png differ diff --git a/config/.cache/brands/integrations/image_upload/icon.png b/config/.cache/brands/integrations/image_upload/icon.png new file mode 100644 index 00000000..c10f0943 Binary files /dev/null and b/config/.cache/brands/integrations/image_upload/icon.png differ diff --git a/config/.cache/brands/integrations/input_boolean/icon.png b/config/.cache/brands/integrations/input_boolean/icon.png new file mode 100644 index 00000000..17b61b1e Binary files /dev/null and b/config/.cache/brands/integrations/input_boolean/icon.png differ diff --git a/config/.cache/brands/integrations/input_button/icon.png b/config/.cache/brands/integrations/input_button/icon.png new file mode 100644 index 00000000..4e4db4f7 Binary files /dev/null and b/config/.cache/brands/integrations/input_button/icon.png differ diff --git a/config/.cache/brands/integrations/input_datetime/icon.png b/config/.cache/brands/integrations/input_datetime/icon.png new file mode 100644 index 00000000..f7fd095a Binary files /dev/null and b/config/.cache/brands/integrations/input_datetime/icon.png differ diff --git a/config/.cache/brands/integrations/input_number/icon.png b/config/.cache/brands/integrations/input_number/icon.png new file mode 100644 index 00000000..2db7955a Binary files /dev/null and b/config/.cache/brands/integrations/input_number/icon.png differ diff --git a/config/.cache/brands/integrations/input_select/icon.png b/config/.cache/brands/integrations/input_select/icon.png new file mode 100644 index 00000000..4e083623 Binary files /dev/null and b/config/.cache/brands/integrations/input_select/icon.png differ diff --git a/config/.cache/brands/integrations/input_text/icon.png b/config/.cache/brands/integrations/input_text/icon.png new file mode 100644 index 00000000..20c8c66b Binary files /dev/null and b/config/.cache/brands/integrations/input_text/icon.png differ diff --git a/config/.cache/brands/integrations/integration/icon.png b/config/.cache/brands/integrations/integration/icon.png new file mode 100644 index 00000000..8b369866 Binary files /dev/null and b/config/.cache/brands/integrations/integration/icon.png differ diff --git a/config/.cache/brands/integrations/intent/icon.png b/config/.cache/brands/integrations/intent/icon.png new file mode 100644 index 00000000..32ca5985 Binary files /dev/null and b/config/.cache/brands/integrations/intent/icon.png differ diff --git a/config/.cache/brands/integrations/ios/icon.png b/config/.cache/brands/integrations/ios/icon.png new file mode 100644 index 00000000..2b653636 Binary files /dev/null and b/config/.cache/brands/integrations/ios/icon.png differ diff --git a/config/.cache/brands/integrations/ipp/icon.png b/config/.cache/brands/integrations/ipp/icon.png new file mode 100644 index 00000000..27877b65 Binary files /dev/null and b/config/.cache/brands/integrations/ipp/icon.png differ diff --git a/config/.cache/brands/integrations/labs/icon.png b/config/.cache/brands/integrations/labs/icon.png new file mode 100644 index 00000000..2b864c36 Binary files /dev/null and b/config/.cache/brands/integrations/labs/icon.png differ diff --git a/config/.cache/brands/integrations/launch_library/icon.png b/config/.cache/brands/integrations/launch_library/icon.png new file mode 100644 index 00000000..3f7e912e Binary files /dev/null and b/config/.cache/brands/integrations/launch_library/icon.png differ diff --git a/config/.cache/brands/integrations/life360/icon.png b/config/.cache/brands/integrations/life360/icon.png new file mode 100644 index 00000000..5dbb9be2 Binary files /dev/null and b/config/.cache/brands/integrations/life360/icon.png differ diff --git a/config/.cache/brands/integrations/light/icon.png b/config/.cache/brands/integrations/light/icon.png new file mode 100644 index 00000000..97965b92 Binary files /dev/null and b/config/.cache/brands/integrations/light/icon.png differ diff --git a/config/.cache/brands/integrations/lock/icon.png b/config/.cache/brands/integrations/lock/icon.png new file mode 100644 index 00000000..a2eb6e87 Binary files /dev/null and b/config/.cache/brands/integrations/lock/icon.png differ diff --git a/config/.cache/brands/integrations/logbook/icon.png b/config/.cache/brands/integrations/logbook/icon.png new file mode 100644 index 00000000..6fd1bd1d Binary files /dev/null and b/config/.cache/brands/integrations/logbook/icon.png differ diff --git a/config/.cache/brands/integrations/logger/icon.png b/config/.cache/brands/integrations/logger/icon.png new file mode 100644 index 00000000..378293b3 Binary files /dev/null and b/config/.cache/brands/integrations/logger/icon.png differ diff --git a/config/.cache/brands/integrations/lovelace/icon.png b/config/.cache/brands/integrations/lovelace/icon.png new file mode 100644 index 00000000..e5267faf Binary files /dev/null and b/config/.cache/brands/integrations/lovelace/icon.png differ diff --git a/config/.cache/brands/integrations/matter/icon.png b/config/.cache/brands/integrations/matter/icon.png new file mode 100644 index 00000000..d6b04319 Binary files /dev/null and b/config/.cache/brands/integrations/matter/icon.png differ diff --git a/config/.cache/brands/integrations/mcp_server/icon.png b/config/.cache/brands/integrations/mcp_server/icon.png new file mode 100644 index 00000000..76aa2770 Binary files /dev/null and b/config/.cache/brands/integrations/mcp_server/icon.png differ diff --git a/config/.cache/brands/integrations/media_player/icon.png b/config/.cache/brands/integrations/media_player/icon.png new file mode 100644 index 00000000..702b5a79 Binary files /dev/null and b/config/.cache/brands/integrations/media_player/icon.png differ diff --git a/config/.cache/brands/integrations/media_source/icon.png b/config/.cache/brands/integrations/media_source/icon.png new file mode 100644 index 00000000..a0f3dbe2 Binary files /dev/null and b/config/.cache/brands/integrations/media_source/icon.png differ diff --git a/config/.cache/brands/integrations/mobile_app/icon.png b/config/.cache/brands/integrations/mobile_app/icon.png new file mode 100644 index 00000000..b7f29918 Binary files /dev/null and b/config/.cache/brands/integrations/mobile_app/icon.png differ diff --git a/config/.cache/brands/integrations/moon/icon.png b/config/.cache/brands/integrations/moon/icon.png new file mode 100644 index 00000000..ee1a490f Binary files /dev/null and b/config/.cache/brands/integrations/moon/icon.png differ diff --git a/config/.cache/brands/integrations/mqtt/icon.png b/config/.cache/brands/integrations/mqtt/icon.png new file mode 100644 index 00000000..fcc1ce25 Binary files /dev/null and b/config/.cache/brands/integrations/mqtt/icon.png differ diff --git a/config/.cache/brands/integrations/my/icon.png b/config/.cache/brands/integrations/my/icon.png new file mode 100644 index 00000000..961b6604 Binary files /dev/null and b/config/.cache/brands/integrations/my/icon.png differ diff --git a/config/.cache/brands/integrations/nest/icon.png b/config/.cache/brands/integrations/nest/icon.png new file mode 100644 index 00000000..3e00949b Binary files /dev/null and b/config/.cache/brands/integrations/nest/icon.png differ diff --git a/config/.cache/brands/integrations/network/icon.png b/config/.cache/brands/integrations/network/icon.png new file mode 100644 index 00000000..5176f180 Binary files /dev/null and b/config/.cache/brands/integrations/network/icon.png differ diff --git a/config/.cache/brands/integrations/notify/icon.png b/config/.cache/brands/integrations/notify/icon.png new file mode 100644 index 00000000..10f77b21 Binary files /dev/null and b/config/.cache/brands/integrations/notify/icon.png differ diff --git a/config/.cache/brands/integrations/number/icon.png b/config/.cache/brands/integrations/number/icon.png new file mode 100644 index 00000000..8f8fe6d5 Binary files /dev/null and b/config/.cache/brands/integrations/number/icon.png differ diff --git a/config/.cache/brands/integrations/nut/icon.png b/config/.cache/brands/integrations/nut/icon.png new file mode 100644 index 00000000..ec2ab02a Binary files /dev/null and b/config/.cache/brands/integrations/nut/icon.png differ diff --git a/config/.cache/brands/integrations/nws_alerts/icon.png b/config/.cache/brands/integrations/nws_alerts/icon.png new file mode 100644 index 00000000..0fc54d81 Binary files /dev/null and b/config/.cache/brands/integrations/nws_alerts/icon.png differ diff --git a/config/.cache/brands/integrations/onboarding/icon.png b/config/.cache/brands/integrations/onboarding/icon.png new file mode 100644 index 00000000..94a9af7b Binary files /dev/null and b/config/.cache/brands/integrations/onboarding/icon.png differ diff --git a/config/.cache/brands/integrations/openai_conversation/icon.png b/config/.cache/brands/integrations/openai_conversation/icon.png new file mode 100644 index 00000000..e020a2fe Binary files /dev/null and b/config/.cache/brands/integrations/openai_conversation/icon.png differ diff --git a/config/.cache/brands/integrations/persistent_notification/icon.png b/config/.cache/brands/integrations/persistent_notification/icon.png new file mode 100644 index 00000000..52d0905d Binary files /dev/null and b/config/.cache/brands/integrations/persistent_notification/icon.png differ diff --git a/config/.cache/brands/integrations/person/icon.png b/config/.cache/brands/integrations/person/icon.png new file mode 100644 index 00000000..04611f34 Binary files /dev/null and b/config/.cache/brands/integrations/person/icon.png differ diff --git a/config/.cache/brands/integrations/phyn/icon.png b/config/.cache/brands/integrations/phyn/icon.png new file mode 100644 index 00000000..384d101b Binary files /dev/null and b/config/.cache/brands/integrations/phyn/icon.png differ diff --git a/config/.cache/brands/integrations/pi_hole_v6/icon.png b/config/.cache/brands/integrations/pi_hole_v6/icon.png new file mode 100644 index 00000000..edcbfbbe Binary files /dev/null and b/config/.cache/brands/integrations/pi_hole_v6/icon.png differ diff --git a/config/.cache/brands/integrations/pirateweather/icon.png b/config/.cache/brands/integrations/pirateweather/icon.png new file mode 100644 index 00000000..0c9d6ae3 Binary files /dev/null and b/config/.cache/brands/integrations/pirateweather/icon.png differ diff --git a/config/.cache/brands/integrations/places/icon.png b/config/.cache/brands/integrations/places/icon.png new file mode 100644 index 00000000..2f7efa07 Binary files /dev/null and b/config/.cache/brands/integrations/places/icon.png differ diff --git a/config/.cache/brands/integrations/portainer/icon.png b/config/.cache/brands/integrations/portainer/icon.png new file mode 100644 index 00000000..09cc1a7f Binary files /dev/null and b/config/.cache/brands/integrations/portainer/icon.png differ diff --git a/config/.cache/brands/integrations/powerwall/icon.png b/config/.cache/brands/integrations/powerwall/icon.png new file mode 100644 index 00000000..88cca8c3 Binary files /dev/null and b/config/.cache/brands/integrations/powerwall/icon.png differ diff --git a/config/.cache/brands/integrations/proxmoxve/icon.png b/config/.cache/brands/integrations/proxmoxve/icon.png new file mode 100644 index 00000000..f03c68b0 Binary files /dev/null and b/config/.cache/brands/integrations/proxmoxve/icon.png differ diff --git a/config/.cache/brands/integrations/rachio/icon.png b/config/.cache/brands/integrations/rachio/icon.png new file mode 100644 index 00000000..620296aa Binary files /dev/null and b/config/.cache/brands/integrations/rachio/icon.png differ diff --git a/config/.cache/brands/integrations/recorder/icon.png b/config/.cache/brands/integrations/recorder/icon.png new file mode 100644 index 00000000..378293b3 Binary files /dev/null and b/config/.cache/brands/integrations/recorder/icon.png differ diff --git a/config/.cache/brands/integrations/remote/icon.png b/config/.cache/brands/integrations/remote/icon.png new file mode 100644 index 00000000..3f35ce57 Binary files /dev/null and b/config/.cache/brands/integrations/remote/icon.png differ diff --git a/config/.cache/brands/integrations/repairs/icon.png b/config/.cache/brands/integrations/repairs/icon.png new file mode 100644 index 00000000..3534ac71 Binary files /dev/null and b/config/.cache/brands/integrations/repairs/icon.png differ diff --git a/config/.cache/brands/integrations/rest/icon.png b/config/.cache/brands/integrations/rest/icon.png new file mode 100644 index 00000000..deecdb86 Binary files /dev/null and b/config/.cache/brands/integrations/rest/icon.png differ diff --git a/config/.cache/brands/integrations/rest_command/icon.png b/config/.cache/brands/integrations/rest_command/icon.png new file mode 100644 index 00000000..deecdb86 Binary files /dev/null and b/config/.cache/brands/integrations/rest_command/icon.png differ diff --git a/config/.cache/brands/integrations/roku/icon.png b/config/.cache/brands/integrations/roku/icon.png new file mode 100644 index 00000000..0107a3eb Binary files /dev/null and b/config/.cache/brands/integrations/roku/icon.png differ diff --git a/config/.cache/brands/integrations/scene/icon.png b/config/.cache/brands/integrations/scene/icon.png new file mode 100644 index 00000000..12358c4f Binary files /dev/null and b/config/.cache/brands/integrations/scene/icon.png differ diff --git a/config/.cache/brands/integrations/schedule/icon.png b/config/.cache/brands/integrations/schedule/icon.png new file mode 100644 index 00000000..944b8a44 Binary files /dev/null and b/config/.cache/brands/integrations/schedule/icon.png differ diff --git a/config/.cache/brands/integrations/script/icon.png b/config/.cache/brands/integrations/script/icon.png new file mode 100644 index 00000000..fe60b350 Binary files /dev/null and b/config/.cache/brands/integrations/script/icon.png differ diff --git a/config/.cache/brands/integrations/search/icon.png b/config/.cache/brands/integrations/search/icon.png new file mode 100644 index 00000000..e7f2fc41 Binary files /dev/null and b/config/.cache/brands/integrations/search/icon.png differ diff --git a/config/.cache/brands/integrations/season/icon.png b/config/.cache/brands/integrations/season/icon.png new file mode 100644 index 00000000..f9c8a7f7 Binary files /dev/null and b/config/.cache/brands/integrations/season/icon.png differ diff --git a/config/.cache/brands/integrations/select/icon.png b/config/.cache/brands/integrations/select/icon.png new file mode 100644 index 00000000..1b8f76c8 Binary files /dev/null and b/config/.cache/brands/integrations/select/icon.png differ diff --git a/config/.cache/brands/integrations/sensor/icon.png b/config/.cache/brands/integrations/sensor/icon.png new file mode 100644 index 00000000..ac8047c8 Binary files /dev/null and b/config/.cache/brands/integrations/sensor/icon.png differ diff --git a/config/.cache/brands/integrations/siren/icon.png b/config/.cache/brands/integrations/siren/icon.png new file mode 100644 index 00000000..8166b8d9 Binary files /dev/null and b/config/.cache/brands/integrations/siren/icon.png differ diff --git a/config/.cache/brands/integrations/sleepiq/icon.png b/config/.cache/brands/integrations/sleepiq/icon.png new file mode 100644 index 00000000..ab3d43a4 Binary files /dev/null and b/config/.cache/brands/integrations/sleepiq/icon.png differ diff --git a/config/.cache/brands/integrations/smartthinq_sensors/icon.png b/config/.cache/brands/integrations/smartthinq_sensors/icon.png new file mode 100644 index 00000000..891d7496 Binary files /dev/null and b/config/.cache/brands/integrations/smartthinq_sensors/icon.png differ diff --git a/config/.cache/brands/integrations/speedtestdotnet/icon.png b/config/.cache/brands/integrations/speedtestdotnet/icon.png new file mode 100644 index 00000000..b5365efc Binary files /dev/null and b/config/.cache/brands/integrations/speedtestdotnet/icon.png differ diff --git a/config/.cache/brands/integrations/spook/icon.png b/config/.cache/brands/integrations/spook/icon.png new file mode 100644 index 00000000..3f3193d0 Binary files /dev/null and b/config/.cache/brands/integrations/spook/icon.png differ diff --git a/config/.cache/brands/integrations/sql/icon.png b/config/.cache/brands/integrations/sql/icon.png new file mode 100644 index 00000000..378293b3 Binary files /dev/null and b/config/.cache/brands/integrations/sql/icon.png differ diff --git a/config/.cache/brands/integrations/ssdp/icon.png b/config/.cache/brands/integrations/ssdp/icon.png new file mode 100644 index 00000000..8974c5ab Binary files /dev/null and b/config/.cache/brands/integrations/ssdp/icon.png differ diff --git a/config/.cache/brands/integrations/stream/icon.png b/config/.cache/brands/integrations/stream/icon.png new file mode 100644 index 00000000..a0748c31 Binary files /dev/null and b/config/.cache/brands/integrations/stream/icon.png differ diff --git a/config/.cache/brands/integrations/stt/icon.png b/config/.cache/brands/integrations/stt/icon.png new file mode 100644 index 00000000..50d7e301 Binary files /dev/null and b/config/.cache/brands/integrations/stt/icon.png differ diff --git a/config/.cache/brands/integrations/sun/icon.png b/config/.cache/brands/integrations/sun/icon.png new file mode 100644 index 00000000..06ff4cb4 Binary files /dev/null and b/config/.cache/brands/integrations/sun/icon.png differ diff --git a/config/.cache/brands/integrations/switch/icon.png b/config/.cache/brands/integrations/switch/icon.png new file mode 100644 index 00000000..dc705641 Binary files /dev/null and b/config/.cache/brands/integrations/switch/icon.png differ diff --git a/config/.cache/brands/integrations/synology_dsm/icon.png b/config/.cache/brands/integrations/synology_dsm/icon.png new file mode 100644 index 00000000..f5867d98 Binary files /dev/null and b/config/.cache/brands/integrations/synology_dsm/icon.png differ diff --git a/config/.cache/brands/integrations/system_health/icon.png b/config/.cache/brands/integrations/system_health/icon.png new file mode 100644 index 00000000..31f51fcc Binary files /dev/null and b/config/.cache/brands/integrations/system_health/icon.png differ diff --git a/config/.cache/brands/integrations/system_log/icon.png b/config/.cache/brands/integrations/system_log/icon.png new file mode 100644 index 00000000..6fd1bd1d Binary files /dev/null and b/config/.cache/brands/integrations/system_log/icon.png differ diff --git a/config/.cache/brands/integrations/systemmonitor/icon.png b/config/.cache/brands/integrations/systemmonitor/icon.png new file mode 100644 index 00000000..34a3524f Binary files /dev/null and b/config/.cache/brands/integrations/systemmonitor/icon.png differ diff --git a/config/.cache/brands/integrations/tag/icon.png b/config/.cache/brands/integrations/tag/icon.png new file mode 100644 index 00000000..a080e91a Binary files /dev/null and b/config/.cache/brands/integrations/tag/icon.png differ diff --git a/config/.cache/brands/integrations/telegram_bot/icon.png b/config/.cache/brands/integrations/telegram_bot/icon.png new file mode 100644 index 00000000..e74bc27b Binary files /dev/null and b/config/.cache/brands/integrations/telegram_bot/icon.png differ diff --git a/config/.cache/brands/integrations/template/icon.png b/config/.cache/brands/integrations/template/icon.png new file mode 100644 index 00000000..2c5bc81b Binary files /dev/null and b/config/.cache/brands/integrations/template/icon.png differ diff --git a/config/.cache/brands/integrations/time/icon.png b/config/.cache/brands/integrations/time/icon.png new file mode 100644 index 00000000..47d1e57e Binary files /dev/null and b/config/.cache/brands/integrations/time/icon.png differ diff --git a/config/.cache/brands/integrations/time_date/icon.png b/config/.cache/brands/integrations/time_date/icon.png new file mode 100644 index 00000000..944b8a44 Binary files /dev/null and b/config/.cache/brands/integrations/time_date/icon.png differ diff --git a/config/.cache/brands/integrations/timer/icon.png b/config/.cache/brands/integrations/timer/icon.png new file mode 100644 index 00000000..d651b549 Binary files /dev/null and b/config/.cache/brands/integrations/timer/icon.png differ diff --git a/config/.cache/brands/integrations/tplink/icon.png b/config/.cache/brands/integrations/tplink/icon.png new file mode 100644 index 00000000..3a8961c5 Binary files /dev/null and b/config/.cache/brands/integrations/tplink/icon.png differ diff --git a/config/.cache/brands/integrations/trace/icon.png b/config/.cache/brands/integrations/trace/icon.png new file mode 100644 index 00000000..39f0c14e Binary files /dev/null and b/config/.cache/brands/integrations/trace/icon.png differ diff --git a/config/.cache/brands/integrations/tuya/icon.png b/config/.cache/brands/integrations/tuya/icon.png new file mode 100644 index 00000000..dc238dcc Binary files /dev/null and b/config/.cache/brands/integrations/tuya/icon.png differ diff --git a/config/.cache/brands/integrations/unifi/icon.png b/config/.cache/brands/integrations/unifi/icon.png new file mode 100644 index 00000000..4e1c9c6f Binary files /dev/null and b/config/.cache/brands/integrations/unifi/icon.png differ diff --git a/config/.cache/brands/integrations/update/icon.png b/config/.cache/brands/integrations/update/icon.png new file mode 100644 index 00000000..c9b48888 Binary files /dev/null and b/config/.cache/brands/integrations/update/icon.png differ diff --git a/config/.cache/brands/integrations/upnp/icon.png b/config/.cache/brands/integrations/upnp/icon.png new file mode 100644 index 00000000..95ba0c93 Binary files /dev/null and b/config/.cache/brands/integrations/upnp/icon.png differ diff --git a/config/.cache/brands/integrations/uptime/icon.png b/config/.cache/brands/integrations/uptime/icon.png new file mode 100644 index 00000000..d651b549 Binary files /dev/null and b/config/.cache/brands/integrations/uptime/icon.png differ diff --git a/config/.cache/brands/integrations/uptimerobot/icon.png b/config/.cache/brands/integrations/uptimerobot/icon.png new file mode 100644 index 00000000..45876ba2 Binary files /dev/null and b/config/.cache/brands/integrations/uptimerobot/icon.png differ diff --git a/config/.cache/brands/integrations/usage_prediction/icon.png b/config/.cache/brands/integrations/usage_prediction/icon.png new file mode 100644 index 00000000..7398d4d8 Binary files /dev/null and b/config/.cache/brands/integrations/usage_prediction/icon.png differ diff --git a/config/.cache/brands/integrations/usb/icon.png b/config/.cache/brands/integrations/usb/icon.png new file mode 100644 index 00000000..8974c5ab Binary files /dev/null and b/config/.cache/brands/integrations/usb/icon.png differ diff --git a/config/.cache/brands/integrations/utility_meter/icon.png b/config/.cache/brands/integrations/utility_meter/icon.png new file mode 100644 index 00000000..b37f4912 Binary files /dev/null and b/config/.cache/brands/integrations/utility_meter/icon.png differ diff --git a/config/.cache/brands/integrations/vacuum/icon.png b/config/.cache/brands/integrations/vacuum/icon.png new file mode 100644 index 00000000..48805026 Binary files /dev/null and b/config/.cache/brands/integrations/vacuum/icon.png differ diff --git a/config/.cache/brands/integrations/valve/icon.png b/config/.cache/brands/integrations/valve/icon.png new file mode 100644 index 00000000..e69de29b diff --git a/config/.cache/brands/integrations/version/icon.png b/config/.cache/brands/integrations/version/icon.png new file mode 100644 index 00000000..39f0c14e Binary files /dev/null and b/config/.cache/brands/integrations/version/icon.png differ diff --git a/config/.cache/brands/integrations/wake_word/icon.png b/config/.cache/brands/integrations/wake_word/icon.png new file mode 100644 index 00000000..acb638a3 Binary files /dev/null and b/config/.cache/brands/integrations/wake_word/icon.png differ diff --git a/config/.cache/brands/integrations/water_heater/icon.png b/config/.cache/brands/integrations/water_heater/icon.png new file mode 100644 index 00000000..9be1668b Binary files /dev/null and b/config/.cache/brands/integrations/water_heater/icon.png differ diff --git a/config/.cache/brands/integrations/weather/icon.png b/config/.cache/brands/integrations/weather/icon.png new file mode 100644 index 00000000..b2fc81be Binary files /dev/null and b/config/.cache/brands/integrations/weather/icon.png differ diff --git a/config/.cache/brands/integrations/web_rtc/icon.png b/config/.cache/brands/integrations/web_rtc/icon.png new file mode 100644 index 00000000..3527d1e2 Binary files /dev/null and b/config/.cache/brands/integrations/web_rtc/icon.png differ diff --git a/config/.cache/brands/integrations/webhook/icon.png b/config/.cache/brands/integrations/webhook/icon.png new file mode 100644 index 00000000..93a5df6e Binary files /dev/null and b/config/.cache/brands/integrations/webhook/icon.png differ diff --git a/config/.cache/brands/integrations/websocket_api/icon.png b/config/.cache/brands/integrations/websocket_api/icon.png new file mode 100644 index 00000000..226fb689 Binary files /dev/null and b/config/.cache/brands/integrations/websocket_api/icon.png differ diff --git a/config/.cache/brands/integrations/whois/icon.png b/config/.cache/brands/integrations/whois/icon.png new file mode 100644 index 00000000..a11eeaf0 Binary files /dev/null and b/config/.cache/brands/integrations/whois/icon.png differ diff --git a/config/.cache/brands/integrations/wyzeapi/icon.png b/config/.cache/brands/integrations/wyzeapi/icon.png new file mode 100644 index 00000000..b189b810 Binary files /dev/null and b/config/.cache/brands/integrations/wyzeapi/icon.png differ diff --git a/config/.cache/brands/integrations/yahoofinance/icon.png b/config/.cache/brands/integrations/yahoofinance/icon.png new file mode 100644 index 00000000..4484faad Binary files /dev/null and b/config/.cache/brands/integrations/yahoofinance/icon.png differ diff --git a/config/.cache/brands/integrations/youtube/icon.png b/config/.cache/brands/integrations/youtube/icon.png new file mode 100644 index 00000000..774fbc56 Binary files /dev/null and b/config/.cache/brands/integrations/youtube/icon.png differ diff --git a/config/.cache/brands/integrations/zeroconf/icon.png b/config/.cache/brands/integrations/zeroconf/icon.png new file mode 100644 index 00000000..d21d6279 Binary files /dev/null and b/config/.cache/brands/integrations/zeroconf/icon.png differ diff --git a/config/.cache/brands/integrations/zone/icon.png b/config/.cache/brands/integrations/zone/icon.png new file mode 100644 index 00000000..b938794e Binary files /dev/null and b/config/.cache/brands/integrations/zone/icon.png differ diff --git a/config/dashboards/overview/partials/admin_sections.yaml b/config/dashboards/overview/partials/admin_sections.yaml index 16be50ea..2905a1ba 100644 --- a/config/dashboards/overview/partials/admin_sections.yaml +++ b/config/dashboards/overview/partials/admin_sections.yaml @@ -6,7 +6,7 @@ # Overview Partial - admin sections # Reusable list extracted from a view for smaller diffs and safer edits. # ------------------------------------------------------------------- -# Notes: Extracted from config/dashboards/overview/views/07_admin.yaml key `sections`. +# Notes: Extracted from config/dashboards/overview/views/08_admin.yaml key `sections`. ###################################################################### - type: grid diff --git a/config/dashboards/overview/partials/health_sections.yaml b/config/dashboards/overview/partials/health_sections.yaml new file mode 100644 index 00000000..19943cb0 --- /dev/null +++ b/config/dashboards/overview/partials/health_sections.yaml @@ -0,0 +1,325 @@ +###################################################################### +# @CCOSTAN - Follow Me on X +# For more info visit https://www.vcloudinfo.com/click-here +# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig +# ------------------------------------------------------------------- +# Overview Partial - health sections +# SleepIQ score/recovery trends plus bed controls. +# ------------------------------------------------------------------- +# Related Issue: 1584 +# Notes: Uses direct SleepIQ integration entities (no helper template sensors). +###################################################################### + +- type: grid + column_span: 4 + columns: 2 + square: false + cards: + - type: entities + title: Carlo Bed Controls + show_header_toggle: false + entities: + - entity: number.sleepnumber_carlo_carlo_firmness + name: Firmness + - entity: number.sleepnumber_carlo_right_head_position_2 + name: Head Position + - entity: number.sleepnumber_carlo_right_foot_position_2 + name: Foot Position + - entity: select.sleepnumber_carlo_foundation_preset_right + name: Preset + - entity: binary_sensor.sleepnumber_carlo_carlo_is_in_bed + name: In Bed + - type: entities + title: Stacey Bed Controls + show_header_toggle: false + entities: + - entity: number.sleepnumber_carlo_stacey_firmness + name: Firmness + - entity: number.sleepnumber_carlo_left_head_position_2 + name: Head Position + - entity: select.sleepnumber_carlo_foundation_preset_left + name: Preset + - entity: binary_sensor.sleepnumber_carlo_stacey_is_in_bed + name: In Bed + +- type: grid + column_span: 4 + columns: 2 + square: false + cards: + - type: vertical-stack + cards: + - type: markdown + content: | + ## Carlo Health + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_carlo_sleep_score + state_not: unknown + - entity: sensor.sleepnumber_carlo_carlo_sleep_score + state_not: unavailable + - entity: sensor.sleepnumber_carlo_carlo_sleep_score + state_not: none + card: + type: custom:mini-graph-card + name: Sleep Score + icon: mdi:sleep + entities: + - entity: sensor.sleepnumber_carlo_carlo_sleep_score + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_carlo_sleep_duration + state_not: unknown + - entity: sensor.sleepnumber_carlo_carlo_sleep_duration + state_not: unavailable + - entity: sensor.sleepnumber_carlo_carlo_sleep_duration + state_not: none + card: + type: custom:mini-graph-card + name: Sleep Duration + icon: mdi:timer-sand + entities: + - entity: sensor.sleepnumber_carlo_carlo_sleep_duration + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_average + state_not: unknown + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_average + state_not: unavailable + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_average + state_not: none + card: + type: custom:mini-graph-card + name: Heart Rate Average + icon: mdi:heart-pulse + entities: + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_average + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_carlo_respiratory_rate_average + state_not: unknown + - entity: sensor.sleepnumber_carlo_carlo_respiratory_rate_average + state_not: unavailable + - entity: sensor.sleepnumber_carlo_carlo_respiratory_rate_average + state_not: none + card: + type: custom:mini-graph-card + name: Respiratory Rate Average + icon: mdi:lungs + entities: + - entity: sensor.sleepnumber_carlo_carlo_respiratory_rate_average + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_variability + state_not: unknown + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_variability + state_not: unavailable + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_variability + state_not: none + card: + type: custom:mini-graph-card + name: Heart Rate Variability + icon: mdi:chart-bell-curve-cumulative + entities: + - entity: sensor.sleepnumber_carlo_carlo_heart_rate_variability + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_carlo_pressure + state_not: unknown + - entity: sensor.sleepnumber_carlo_carlo_pressure + state_not: unavailable + - entity: sensor.sleepnumber_carlo_carlo_pressure + state_not: none + card: + type: custom:mini-graph-card + name: Pressure + icon: mdi:gauge + entities: + - entity: sensor.sleepnumber_carlo_carlo_pressure + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + + - type: vertical-stack + cards: + - type: markdown + content: | + ## Stacey Health + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_stacey_sleep_score + state_not: unknown + - entity: sensor.sleepnumber_carlo_stacey_sleep_score + state_not: unavailable + - entity: sensor.sleepnumber_carlo_stacey_sleep_score + state_not: none + card: + type: custom:mini-graph-card + name: Sleep Score + icon: mdi:sleep + entities: + - entity: sensor.sleepnumber_carlo_stacey_sleep_score + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_stacey_sleep_duration + state_not: unknown + - entity: sensor.sleepnumber_carlo_stacey_sleep_duration + state_not: unavailable + - entity: sensor.sleepnumber_carlo_stacey_sleep_duration + state_not: none + card: + type: custom:mini-graph-card + name: Sleep Duration + icon: mdi:timer-sand + entities: + - entity: sensor.sleepnumber_carlo_stacey_sleep_duration + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_average + state_not: unknown + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_average + state_not: unavailable + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_average + state_not: none + card: + type: custom:mini-graph-card + name: Heart Rate Average + icon: mdi:heart-pulse + entities: + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_average + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_stacey_respiratory_rate_average + state_not: unknown + - entity: sensor.sleepnumber_carlo_stacey_respiratory_rate_average + state_not: unavailable + - entity: sensor.sleepnumber_carlo_stacey_respiratory_rate_average + state_not: none + card: + type: custom:mini-graph-card + name: Respiratory Rate Average + icon: mdi:lungs + entities: + - entity: sensor.sleepnumber_carlo_stacey_respiratory_rate_average + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_variability + state_not: unknown + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_variability + state_not: unavailable + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_variability + state_not: none + card: + type: custom:mini-graph-card + name: Heart Rate Variability + icon: mdi:chart-bell-curve-cumulative + entities: + - entity: sensor.sleepnumber_carlo_stacey_heart_rate_variability + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + - type: conditional + conditions: + - entity: sensor.sleepnumber_carlo_stacey_pressure + state_not: unknown + - entity: sensor.sleepnumber_carlo_stacey_pressure + state_not: unavailable + - entity: sensor.sleepnumber_carlo_stacey_pressure + state_not: none + card: + type: custom:mini-graph-card + name: Pressure + icon: mdi:gauge + entities: + - entity: sensor.sleepnumber_carlo_stacey_pressure + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + show: + fill: false + points: false + extrema: true + diff --git a/config/dashboards/overview/partials/home_sections.yaml b/config/dashboards/overview/partials/home_sections.yaml index e54e34eb..8b9eb486 100644 --- a/config/dashboards/overview/partials/home_sections.yaml +++ b/config/dashboards/overview/partials/home_sections.yaml @@ -6,6 +6,7 @@ # Overview Partial - home sections # Reusable list extracted from a view for smaller diffs and safer edits. # ------------------------------------------------------------------- +# Related Issue: 1584 # Notes: Extracted from config/dashboards/overview/views/01_home.yaml key `sections`. ###################################################################### @@ -197,6 +198,42 @@ features_position: bottom - type: custom:search-card max_results: 10 + - type: custom:mini-graph-card + name: Sleep Score Trend + icon: mdi:heart-pulse + entities: + - entity: sensor.sleepnumber_carlo_carlo_sleep_score + name: Carlo + show_state: true + - entity: sensor.sleepnumber_carlo_stacey_sleep_score + name: Stacey + show_state: true + hours_to_show: 168 + points_per_hour: 1 + line_width: 3 + graph: line + smoothing: true + lower_bound: 0 + upper_bound: 100 + show: + graph: line + name: true + icon: true + state: true + fill: false + points: false + legend: false + labels: false + height: 90 + tap_action: + action: navigate + navigation_path: /lovelace/health + hold_action: + action: navigate + navigation_path: /lovelace/health + grid_options: + columns: full + rows: 3 - type: custom:bubble-card card_type: button button_type: slider diff --git a/config/dashboards/overview/partials/water_sections.yaml b/config/dashboards/overview/partials/water_sections.yaml index 9ef79e94..ec3e5dea 100644 --- a/config/dashboards/overview/partials/water_sections.yaml +++ b/config/dashboards/overview/partials/water_sections.yaml @@ -6,7 +6,7 @@ # Overview Partial - water sections # Reusable list extracted from a view for smaller diffs and safer edits. # ------------------------------------------------------------------- -# Notes: Extracted from config/dashboards/overview/views/06_water.yaml key `sections`. +# Notes: Extracted from config/dashboards/overview/views/07_water.yaml key `sections`. ###################################################################### - cards: diff --git a/config/dashboards/overview/views/06_health.yaml b/config/dashboards/overview/views/06_health.yaml new file mode 100644 index 00000000..a765cd63 --- /dev/null +++ b/config/dashboards/overview/views/06_health.yaml @@ -0,0 +1,21 @@ +###################################################################### +# @CCOSTAN - Follow Me on X +# For more info visit https://www.vcloudinfo.com/click-here +# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig +# ------------------------------------------------------------------- +# Overview View - health +# SleepIQ health metrics view for Carlo and Stacey. +# ------------------------------------------------------------------- +# Related Issue: 1584 +# Notes: Dedicated health view keeps Overview Home compact. +###################################################################### + +title: Health +path: health +type: sections +icon: mdi:heart-pulse +theme: Backend-selected +max_columns: 4 +badges: [] +sections: !include /config/dashboards/overview/partials/health_sections.yaml +cards: [] diff --git a/config/dashboards/overview/views/07_water.yaml b/config/dashboards/overview/views/07_water.yaml new file mode 100644 index 00000000..d5cf5a12 --- /dev/null +++ b/config/dashboards/overview/views/07_water.yaml @@ -0,0 +1,23 @@ +###################################################################### +# @CCOSTAN - Follow Me on X +# For more info visit https://www.vcloudinfo.com/click-here +# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig +# ------------------------------------------------------------------- +# Overview View - Utilities +# YAML-exported Lovelace dashboard (split into view files). +# ------------------------------------------------------------------- +# Notes: Exported from config/.storage/lovelace.lovelace view index 7. +###################################################################### + +title: Utilities +path: water +icon: mdi:home-lightning-bolt +type: sections +max_columns: 3 +sections: !include /config/dashboards/overview/partials/water_sections.yaml +cards: [] +visible: +- user: be280a93c9d7416e98d25d0470f414be +- user: 46a8d15eb20e4a1daf2d1d1f63180ec5 +- user: 8fc5ba22cb32430a9143beb4df70541b +- user: 19970706e7e4492c844ea2fc94a4599a diff --git a/config/dashboards/overview/views/08_admin.yaml b/config/dashboards/overview/views/08_admin.yaml new file mode 100644 index 00000000..13ca929f --- /dev/null +++ b/config/dashboards/overview/views/08_admin.yaml @@ -0,0 +1,18 @@ +###################################################################### +# @CCOSTAN - Follow Me on X +# For more info visit https://www.vcloudinfo.com/click-here +# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig +# ------------------------------------------------------------------- +# Overview View - Admin +# YAML-exported Lovelace dashboard (split into view files). +# ------------------------------------------------------------------- +# Notes: Exported from config/.storage/lovelace.lovelace view index 8. +###################################################################### + +title: Admin +icon: mdi:security +visible: +- user: be280a93c9d7416e98d25d0470f414be +cards: [] +type: sections +sections: !include /config/dashboards/overview/partials/admin_sections.yaml diff --git a/config/packages/README.md b/config/packages/README.md index e3bea090..09ebe124 100755 --- a/config/packages/README.md +++ b/config/packages/README.md @@ -45,19 +45,21 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this | [lightning.yaml](lightning.yaml) | Blitzortung lightning counter monitoring with snoozeable push actions. | `sensor.blitzortung_lightning_counter`, `input_boolean.snooze_lightning`, notify engine actions | | [logbook_activity_feed.yaml](logbook_activity_feed.yaml) | Dummy `sensor.activity_feed` + helper to write clean Activity entries (Issue #1550). | `sensor.activity_feed`, `script.send_to_logbook` | | [mariadb_monitoring.yaml](mariadb_monitoring.yaml) | MariaDB health sensors and Lovelace dashboard snippet for recorder stats. | `sensor.mariadb_status`, `sensor.database_size` | -| [docker_infrastructure.yaml](docker_infrastructure.yaml) | Docker host patching telemetry (docker_10/14/17/69) + host-side auto-reboots + container-down Repairs alerts, with degraded-telemetry guardrails when Portainer data drops. | `sensor.docker_*_apt_status`, `binary_sensor.docker_container_telemetry_degraded`, `repairs.create`, `repairs.remove` | -| [infrastructure_observability.yaml](infrastructure_observability.yaml) | Normalized WAN/DNS/backup/domain/cert health sensors used by the Infrastructure Home + Website Health dashboards. | `binary_sensor.infra_*`, `sensor.infra_*`, `script.send_to_logbook` | +| [docker_infrastructure.yaml](docker_infrastructure.yaml) | Docker host patching telemetry + container/stack Repairs automation and weekly scheduled prune actions across docker_10/14/17/69. | `sensor.docker_*_apt_status`, `binary_sensor.*_stack_status`, `sensor.docker_stacks_down_count`, `repairs.create` | +| [proxmox.yaml](proxmox.yaml) | Proxmox runtime and disk pressure monitoring with Repairs for node degradations plus nightly Frigate reboot. | `binary_sensor.proxmox*_runtime_healthy`, `sensor.proxmox*_disk_used_percentage`, `repairs.create`, `button.qemu_docker2_101_reboot` | +| [infrastructure_observability.yaml](infrastructure_observability.yaml) | Normalized WAN/DNS/backup/domain/cert health + website uptime/latency SLO signals for Infrastructure dashboards. | `binary_sensor.infra_website_uptime_slo_breach`, `binary_sensor.infra_website_latency_degraded`, `binary_sensor.infra_*` | | [onenote_indexer.yaml](onenote_indexer.yaml) | OneNote indexer health/status monitoring for Joanna, failure-repair automation, and a daily duplicate-delete maintenance request. | `sensor.onenote_indexer_last_job_status`, `binary_sensor.onenote_indexer_last_job_successful` | | [mqtt_status.yaml](mqtt_status.yaml) | Command-line MQTT broker reachability probe with Spook Repairs escalation and Joanna troubleshooting dispatch on outage. | `binary_sensor.mqtt_status_raw`, `binary_sensor.mqtt_broker_problem`, `repairs.create`, `rest_command.bearclaw_command` | | [mariadb.yaml](mariadb.yaml) | MariaDB recorder health and capacity SQL sensors. | `sensor.mariadb_status`, `sensor.database_size` | | [tugtainer_updates.yaml](tugtainer_updates.yaml) | Tugtainer container update notifications via webhook + persistent alerts. | `persistent_notification.create`, `input_datetime.tugtainer_last_update` | -| [bearclaw.yaml](bearclaw.yaml) | Joanna/BearClaw bridge automations that forward Telegram commands to codex_appliance and relay replies back, with Telegram user/chat allowlist enforcement via secrets CSV. | `rest_command.bearclaw_*`, `automation.bearclaw_*`, webhook relay | +| [bearclaw.yaml](bearclaw.yaml) | Joanna/BearClaw bridge automations that forward Telegram commands to codex_appliance, relay replies back, and write JOANNA webhook reply summaries to Activity feed. | `rest_command.bearclaw_*`, `automation.bearclaw_*`, `script.send_to_logbook`, webhook relay | | [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. | `input_datetime.water_delivery_date`, `notify.alexa_media_garage` | +| [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` | | [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` | | [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` | | [finance.yaml](finance.yaml) | Yahoo Finance sensor bundle for portfolio glances and Lovelace cards. | `sensor.tsla`, `sensor.aapl`, `sensor.amzn`, `sensor.msft` | ### Garadget automations diff --git a/config/packages/bearclaw.yaml b/config/packages/bearclaw.yaml index 020f133e..82426c8e 100644 --- a/config/packages/bearclaw.yaml +++ b/config/packages/bearclaw.yaml @@ -12,6 +12,7 @@ # Notes: Shared script helper `script.joanna_dispatch` lives in config/script/joanna_dispatch.yaml. # Notes: Telegram inline button callbacks are handled here and mapped to BearClaw commands. # Notes: Inbound Telegram handling enforces user_id + chat_id allowlists from secrets CSV values. +# Notes: Reply webhook writes JOANNA activity entries to logbook for traceability. ###################################################################### rest_command: @@ -56,17 +57,15 @@ automation: allowed_user_ids_csv: !secret bearclaw_allowed_telegram_user_ids allowed_chat_ids_csv: !secret bearclaw_allowed_telegram_chat_ids condition: - - condition: template - value_template: "{{ trigger.event.data.user_id is defined }}" - - condition: template - value_template: "{{ trigger.event.data.chat_id is defined }}" - condition: template value_template: >- + {% set has_user = trigger.event.data.user_id is defined %} + {% set has_chat = trigger.event.data.chat_id is defined %} {% set allowed_users = (allowed_user_ids_csv | default('', true) | string).split(',') | map('trim') | reject('equalto', '') | list %} {% set allowed_chats = (allowed_chat_ids_csv | default('', true) | string).split(',') | map('trim') | reject('equalto', '') | list %} {% set incoming_user = trigger.event.data.user_id | default('') | string | trim %} {% set incoming_chat = trigger.event.data.chat_id | default('') | string | trim %} - {{ allowed_users | count > 0 and allowed_chats | count > 0 and incoming_user in allowed_users and incoming_chat in allowed_chats }} + {{ has_user and has_chat and allowed_users | count > 0 and allowed_chats | count > 0 and incoming_user in allowed_users and incoming_chat in allowed_chats }} action: - variables: command_text: "{{ (trigger.event.data.args | default([])) | join(' ') | trim }}" @@ -78,7 +77,7 @@ automation: sequence: - service: telegram_bot.send_message data: - target: !secret telegram_allowed_chat_id_carlo + chat_id: !secret telegram_allowed_chat_id_carlo message: "Choose a BearClaw action or send /bear ." parse_mode: plain_text disable_web_page_preview: true @@ -102,21 +101,16 @@ automation: allowed_user_ids_csv: !secret bearclaw_allowed_telegram_user_ids allowed_chat_ids_csv: !secret bearclaw_allowed_telegram_chat_ids condition: - - condition: template - value_template: "{{ trigger.event.data.user_id is defined }}" - - condition: template - value_template: "{{ trigger.event.data.chat_id is defined }}" - condition: template value_template: >- + {% set has_user = trigger.event.data.user_id is defined %} + {% set has_chat = trigger.event.data.chat_id is defined %} {% set allowed_users = (allowed_user_ids_csv | default('', true) | string).split(',') | map('trim') | reject('equalto', '') | list %} {% set allowed_chats = (allowed_chat_ids_csv | default('', true) | string).split(',') | map('trim') | reject('equalto', '') | list %} {% set incoming_user = trigger.event.data.user_id | default('') | string | trim %} {% set incoming_chat = trigger.event.data.chat_id | default('') | string | trim %} - {{ allowed_users | count > 0 and allowed_chats | count > 0 and incoming_user in allowed_users and incoming_chat in allowed_chats }} - - condition: template - value_template: >- {% set cb = trigger.event.data.data | default('') %} - {{ cb.startswith('/bear_') or cb.startswith('/bc_') }} + {{ has_user and has_chat and allowed_users | count > 0 and allowed_chats | count > 0 and incoming_user in allowed_users and incoming_chat in allowed_chats and (cb.startswith('/bear_') or cb.startswith('/bc_')) }} action: - variables: callback_id: "{{ trigger.event.data.id | default('') }}" @@ -221,21 +215,16 @@ automation: allowed_user_ids_csv: !secret bearclaw_allowed_telegram_user_ids allowed_chat_ids_csv: !secret bearclaw_allowed_telegram_chat_ids condition: - - condition: template - value_template: "{{ trigger.event.data.user_id is defined }}" - - condition: template - value_template: "{{ trigger.event.data.chat_id is defined }}" - condition: template value_template: >- + {% set has_user = trigger.event.data.user_id is defined %} + {% set has_chat = trigger.event.data.chat_id is defined %} {% set allowed_users = (allowed_user_ids_csv | default('', true) | string).split(',') | map('trim') | reject('equalto', '') | list %} {% set allowed_chats = (allowed_chat_ids_csv | default('', true) | string).split(',') | map('trim') | reject('equalto', '') | list %} {% set incoming_user = trigger.event.data.user_id | default('') | string | trim %} {% set incoming_chat = trigger.event.data.chat_id | default('') | string | trim %} - {{ allowed_users | count > 0 and allowed_chats | count > 0 and incoming_user in allowed_users and incoming_chat in allowed_chats }} - - condition: template - value_template: "{{ (trigger.event.data.text | default('') | trim) != '' }}" - - condition: template - value_template: "{{ not (trigger.event.data.text | default('') | trim).startswith('/') }}" + {% set plain_text = trigger.event.data.text | default('') | trim %} + {{ has_user and has_chat and allowed_users | count > 0 and allowed_chats | count > 0 and incoming_user in allowed_users and incoming_chat in allowed_chats and plain_text != '' and not plain_text.startswith('/') }} action: - variables: plain_text: "{{ trigger.event.data.text | default('') | trim }}" @@ -269,6 +258,13 @@ automation: {% else %} {{ '' }} {% endif %} + logbook_message: >- + {% set compact = message | replace('\r', ' ') | replace('\n', ' ') | trim %} + {% if compact | length > 240 %} + {{ compact[:237] ~ '...' }} + {% else %} + {{ compact }} + {% endif %} - choose: - conditions: - condition: template @@ -276,7 +272,7 @@ automation: sequence: - service: telegram_bot.send_message data: - target: !secret telegram_allowed_chat_id_carlo + chat_id: !secret telegram_allowed_chat_id_carlo message: "{{ message }}" parse_mode: plain_text disable_web_page_preview: true @@ -285,6 +281,10 @@ automation: - service: script.joanna_send_telegram data: message: "{{ message }}" + - service: script.send_to_logbook + data: + topic: JOANNA + message: "{{ level | upper }}: {{ logbook_message }}" - choose: - conditions: - condition: template diff --git a/config/packages/docker_infrastructure.yaml b/config/packages/docker_infrastructure.yaml index 92b7cc6e..1e08ce2e 100644 --- a/config/packages/docker_infrastructure.yaml +++ b/config/packages/docker_infrastructure.yaml @@ -6,10 +6,12 @@ # Docker Infrastructure - Host patching and container alerts # 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. # Notes: Container monitoring is dynamic with binary_sensor status preferred over switch state. +# Notes: Includes Portainer stack status repairs and scheduled image prune. ###################################################################### input_datetime: @@ -277,6 +279,33 @@ template: {{ down_list.split(',') | map('trim') | reject('equalto', '') | list | count }} {% endif %} + - name: "Docker Stacks Down List" + unique_id: docker_stacks_down_list + icon: mdi:package-down + state: >- + {% set ns = namespace(down=[]) %} + {% for item in states.binary_sensor %} + {% if item.entity_id is search('^binary_sensor\\..*_stack_status$') %} + {% set st = item.state | lower %} + {% if st in ['off', 'unknown', 'unavailable'] %} + {% set stack = item.entity_id | replace('binary_sensor.', '') | regex_replace('_stack_status$', '') %} + {% set ns.down = ns.down + [stack] %} + {% endif %} + {% endif %} + {% endfor %} + {{ ns.down | sort | join(', ') if (ns.down | count > 0) else 'none' }} + + - name: "Docker Stacks Down Count" + unique_id: docker_stacks_down_count + icon: mdi:counter + state: >- + {% set down_list = states('sensor.docker_stacks_down_list') %} + {% if down_list in ['unknown', 'unavailable', 'none', ''] %} + 0 + {% else %} + {{ down_list.split(',') | map('trim') | reject('equalto', '') | list | count }} + {% endif %} + - binary_sensor: - name: "Docker Container Telemetry Degraded" unique_id: docker_container_telemetry_degraded @@ -389,6 +418,75 @@ script: topic: "DOCKER" message: "{{ container_name }} recovered ({{ effective_state }})." + docker_stack_repairs_sync: + alias: Docker Stack Repairs Sync + mode: parallel + fields: + entity_id: + description: Changed Portainer stack status entity (`binary_sensor.*_stack_status`) + example: "binary_sensor.vcloudinfo_stack_status" + operation: + description: "Sync operation: create or clear" + example: "create" + delay_minutes: + description: "Optional delay before evaluation (used for create path)" + example: 2 + sequence: + - variables: + down_states: ['off', 'unknown', 'unavailable'] + src_entity: "{{ entity_id | default('', true) }}" + op: "{{ operation | default('create', true) | lower }}" + wait_minutes: "{{ delay_minutes | default(0) | int(0) }}" + stack_key: "{{ src_entity | replace('binary_sensor.', '') | regex_replace('_stack_status$', '') }}" + stack_count_entity: "sensor.{{ stack_key }}_stack_containers_count" + tracked_stack: "{{ expand(stack_count_entity) | count > 0 }}" + issue_id: "docker_stack_{{ stack_key }}_offline" + - condition: template + value_template: "{{ src_entity.startswith('binary_sensor.') and src_entity.endswith('_stack_status') }}" + - condition: template + value_template: "{{ tracked_stack and op in ['create', 'clear'] }}" + - choose: + - conditions: "{{ op == 'create' }}" + sequence: + - choose: + - conditions: "{{ wait_minutes > 0 }}" + sequence: + - delay: + minutes: "{{ wait_minutes }}" + - variables: + effective_state: "{{ states(src_entity) | lower }}" + stack_name: "{{ state_attr(src_entity, 'friendly_name') | default(stack_key, true) }}" + - condition: template + value_template: "{{ effective_state in down_states }}" + - service: repairs.create + data: + issue_id: "{{ issue_id }}" + title: "Stack offline: {{ stack_name }}" + description: >- + {{ stack_name }} has been {{ effective_state }} for over 2 minutes. + Effective entity: {{ src_entity }}. + severity: warning + persistent: true + - service: script.send_to_logbook + data: + topic: "DOCKER" + message: "{{ stack_name }} stack is {{ effective_state }} for over 2 minutes." + - conditions: "{{ op == 'clear' }}" + sequence: + - variables: + effective_state: "{{ states(src_entity) | lower }}" + stack_name: "{{ state_attr(src_entity, 'friendly_name') | default(stack_key, true) }}" + - condition: template + value_template: "{{ effective_state not in down_states }}" + - service: repairs.remove + continue_on_error: true + data: + issue_id: "{{ issue_id }}" + - service: script.send_to_logbook + data: + topic: "DOCKER" + message: "{{ stack_name }} stack recovered ({{ effective_state }})." + automation: - alias: "APT Update Report - Docker Hosts" id: apt_update_report_docker_hosts @@ -525,6 +623,47 @@ automation: entity_id: "{{ entity_id }}" operation: "clear" + - alias: "Docker Stack State Sync - Repairs (Dynamic)" + id: docker_stack_state_sync_repairs_dynamic + description: "Detect Portainer stack status transitions and delegate Repairs sync." + mode: parallel + trigger: + - platform: event + event_type: state_changed + condition: + - condition: template + value_template: >- + {% set ent = trigger.event.data.entity_id | default('') %} + {{ ent.startswith('binary_sensor.') and ent.endswith('_stack_status') }} + - condition: template + value_template: "{{ trigger.event.data.old_state is not none and trigger.event.data.new_state is not none }}" + - condition: template + value_template: "{{ trigger.event.data.old_state.state != trigger.event.data.new_state.state }}" + - condition: template + value_template: >- + {% set stack_key = trigger.event.data.entity_id | replace('binary_sensor.', '') | regex_replace('_stack_status$', '') %} + {{ expand('sensor.' ~ stack_key ~ '_stack_containers_count') | count > 0 }} + action: + - variables: + down_states: ['off', 'unknown', 'unavailable'] + entity_id: "{{ trigger.event.data.entity_id }}" + old_state: "{{ trigger.event.data.old_state.state | lower }}" + new_state: "{{ trigger.event.data.new_state.state | lower }}" + - choose: + - conditions: "{{ new_state in down_states and old_state not in down_states }}" + sequence: + - service: script.docker_stack_repairs_sync + data: + entity_id: "{{ entity_id }}" + operation: "create" + delay_minutes: 2 + - conditions: "{{ old_state in down_states and new_state not in down_states }}" + sequence: + - service: script.docker_stack_repairs_sync + data: + entity_id: "{{ entity_id }}" + operation: "clear" + - alias: "Docker Containers Maintenance Prompt" id: docker_containers_maintenance_prompt description: "Prompt Carlo to snooze container alerts for maintenance when more than 3 containers are down." @@ -596,3 +735,27 @@ automation: message: >- Maintenance snooze declined with {{ states('sensor.docker_containers_down_count') }} containers down ({{ states('sensor.docker_containers_down_list') }}). + + - alias: "Docker Weekly Prune Unused Images" + id: docker_weekly_prune_unused_images + description: "Run weekly unguarded prune actions across Docker hosts." + mode: single + trigger: + - platform: time + at: "03:15:00" + condition: + - condition: time + weekday: + - sun + action: + - service: button.press + target: + entity_id: + - button.carlo_hass_prune_unused_images + - button.docker17_prune_unused_images + - button.docker69_prune_unused_images + - button.docker2_prune_unused_images + - service: script.send_to_logbook + data: + topic: "DOCKER" + message: "Weekly scheduled prune triggered on docker_10/17/69/14." diff --git a/config/packages/infrastructure_observability.yaml b/config/packages/infrastructure_observability.yaml index 088e3837..a85605c6 100644 --- a/config/packages/infrastructure_observability.yaml +++ b/config/packages/infrastructure_observability.yaml @@ -6,6 +6,7 @@ # Infrastructure Observability - Normalized infra monitoring signals # WAN/DNS/backup/website/domain/cert state normalized for dashboards. # ------------------------------------------------------------------- +# Related Issue: 1584 # Notes: Home dashboard consumes `infra_*` entities for exceptions-only alerts. # Notes: Domain warning threshold is <30 days; critical threshold is <14 days. ###################################################################### @@ -198,6 +199,40 @@ template: state: >- {{ states('sensor.infra_website_down_count') | int(0) > 0 }} + - name: "Infra Website Uptime SLO Breach" + unique_id: infra_website_uptime_slo_breach + device_class: problem + state: >- + {% set ns = namespace(seen=false, breach=false) %} + {% for item in states.sensor %} + {% if item.entity_id is search('sensor\\.(vcloudinfo_com|kingcrafthomes_com|www_kingcrafthomes_com).*uptime_1d$') %} + {% if item.state not in ['unknown', 'unavailable', 'none', ''] %} + {% set ns.seen = true %} + {% if (item.state | float(100)) < 99 %} + {% set ns.breach = true %} + {% endif %} + {% endif %} + {% endif %} + {% endfor %} + {{ ns.seen and ns.breach }} + + - name: "Infra Website Latency Degraded" + unique_id: infra_website_latency_degraded + device_class: problem + state: >- + {% set ns = namespace(seen=false, breach=false) %} + {% for item in states.sensor %} + {% if item.entity_id is search('sensor\\.(vcloudinfo_com|kingcrafthomes_com|www_kingcrafthomes_com).*avg_response_time_1d$') %} + {% if item.state not in ['unknown', 'unavailable', 'none', ''] %} + {% set ns.seen = true %} + {% if (item.state | float(0)) > 1.2 %} + {% set ns.breach = true %} + {% endif %} + {% endif %} + {% endif %} + {% endfor %} + {{ ns.seen and ns.breach }} + - name: "Infra Domain Expiry Critical" unique_id: infra_domain_expiry_critical device_class: problem @@ -266,3 +301,55 @@ automation: topic: "NETWORK" message: >- External IP changed from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}. + + - alias: "Infrastructure - Website Uptime SLO Repair" + id: infra_website_uptime_slo_repair + description: "Create/clear Repairs issue when website 1-day uptime breaches SLO." + mode: queued + trigger: + - platform: state + entity_id: binary_sensor.infra_website_uptime_slo_breach + action: + - choose: + - conditions: "{{ trigger.to_state.state == 'on' }}" + sequence: + - service: repairs.create + data: + issue_id: infra_website_uptime_slo_breach + title: "Website uptime SLO breached" + description: > + At least one monitored website has uptime_1d below 99%. + Review Uptime Kuma entities on the Website Health dashboard. + severity: warning + persistent: true + default: + - service: repairs.remove + continue_on_error: true + data: + issue_id: infra_website_uptime_slo_breach + + - alias: "Infrastructure - Website Latency Repair" + id: infra_website_latency_repair + description: "Create/clear Repairs issue when website response times degrade." + mode: queued + trigger: + - platform: state + entity_id: binary_sensor.infra_website_latency_degraded + action: + - choose: + - conditions: "{{ trigger.to_state.state == 'on' }}" + sequence: + - service: repairs.create + data: + issue_id: infra_website_latency_degraded + title: "Website latency degraded" + description: > + At least one monitored website reports avg_response_time_1d above 1.2s. + Review Uptime Kuma response-time entities on Website Health. + severity: warning + persistent: true + default: + - service: repairs.remove + continue_on_error: true + data: + issue_id: infra_website_latency_degraded diff --git a/config/packages/proxmox.yaml b/config/packages/proxmox.yaml index eb91ad1e..dc8a57f1 100644 --- a/config/packages/proxmox.yaml +++ b/config/packages/proxmox.yaml @@ -6,8 +6,73 @@ # Proxmox Host Automations - reboots and update alerts # Nightly Frigate host reboot plus update repair issues. # ------------------------------------------------------------------- +# Related Issue: 1584 # Notes: Creates HA repair issues when proxmox nodes report updates. +# Notes: Adds normalized runtime + disk health signals for dashboard/alerts. ###################################################################### +template: + - sensor: + - name: "Proxmox1 Disk Used Percentage" + unique_id: proxmox1_disk_used_percentage + unit_of_measurement: "%" + icon: mdi:harddisk + state: >- + {% set preferred = states('sensor.node_proxmox1_disk_used_percentage') %} + {% if preferred not in ['unknown', 'unavailable', 'none', ''] %} + {{ preferred | float(0) | round(1) }} + {% else %} + {% set used = states('sensor.node_proxmox1_disk') | float(0) %} + {% set total = states('sensor.node_proxmox1_max_disk') | float(0) %} + {% if total > 0 %} + {{ ((used / total) * 100) | round(1) }} + {% else %} + {{ none }} + {% endif %} + {% endif %} + + - name: "Proxmox02 Disk Used Percentage" + unique_id: proxmox02_disk_used_percentage + unit_of_measurement: "%" + icon: mdi:harddisk + state: >- + {% set preferred = states('sensor.node_proxmox02_disk_used_percentage') %} + {% if preferred not in ['unknown', 'unavailable', 'none', ''] %} + {{ preferred | float(0) | round(1) }} + {% else %} + {% set used = states('sensor.node_proxmox02_disk') | float(0) %} + {% set total = states('sensor.node_proxmox02_max_disk') | float(0) %} + {% if total > 0 %} + {{ ((used / total) * 100) | round(1) }} + {% else %} + {{ none }} + {% endif %} + {% endif %} + + - binary_sensor: + - name: "Proxmox1 Runtime Healthy" + unique_id: proxmox1_runtime_healthy + device_class: running + state: >- + {% set state_value = states('binary_sensor.node_proxmox1_status') %} + {% if state_value in ['on', 'off'] %} + {{ state_value == 'on' }} + {% else %} + {% set status = states('sensor.node_proxmox1_status') | lower %} + {{ status in ['online', 'running', 'on'] }} + {% endif %} + + - name: "Proxmox02 Runtime Healthy" + unique_id: proxmox02_runtime_healthy + device_class: running + state: >- + {% set state_value = states('binary_sensor.node_proxmox02_status') %} + {% if state_value in ['on', 'off'] %} + {{ state_value == 'on' }} + {% else %} + {% set status = states('sensor.node_proxmox02_status') | lower %} + {{ status in ['online', 'running', 'on'] }} + {% endif %} + automation: - alias: "Nightly Frigate Server Reboot" id: nightly_frigate_reboot @@ -64,3 +129,114 @@ automation: data: topic: "PROXMOX" message: "{{ node_name }} has been Patched" + + - alias: "Proxmox Runtime Repair Issues" + id: proxmox_runtime_repairs + description: "Create and clear Repairs when Proxmox node runtime becomes unhealthy." + mode: restart + trigger: + - platform: state + entity_id: + - binary_sensor.proxmox1_runtime_healthy + - binary_sensor.proxmox02_runtime_healthy + variables: + node_name: >- + {% if 'proxmox1' in trigger.entity_id %}Proxmox1{% else %}Proxmox02{% endif %} + issue_id: >- + {% if 'proxmox1' in trigger.entity_id %} + proxmox1_runtime_unhealthy + {% else %} + proxmox02_runtime_unhealthy + {% endif %} + action: + - choose: + - conditions: "{{ trigger.to_state.state == 'off' }}" + sequence: + - delay: "00:02:00" + - condition: template + value_template: "{{ is_state(trigger.entity_id, 'off') }}" + - service: repairs.create + data: + issue_id: "{{ issue_id }}" + severity: error + persistent: true + title: "{{ node_name }} runtime degraded" + description: > + {{ node_name }} has remained offline for over 2 minutes. + Check node status in Proxmox and restore runtime. + - service: script.send_to_logbook + data: + topic: "PROXMOX" + message: "{{ node_name }} runtime is degraded." + default: + - service: repairs.remove + continue_on_error: true + data: + issue_id: "{{ issue_id }}" + - service: script.send_to_logbook + data: + topic: "PROXMOX" + message: "{{ node_name }} runtime recovered." + + - alias: "Proxmox Disk Pressure Repair Issues" + id: proxmox_disk_pressure_repairs + description: "Create and clear Repairs when Proxmox node disk usage stays elevated." + mode: restart + trigger: + - platform: numeric_state + entity_id: + - sensor.proxmox1_disk_used_percentage + - sensor.proxmox02_disk_used_percentage + above: 85 + for: "00:15:00" + - platform: state + entity_id: + - sensor.proxmox1_disk_used_percentage + - sensor.proxmox02_disk_used_percentage + variables: + node_name: >- + {% if 'proxmox1' in trigger.entity_id %}Proxmox1{% else %}Proxmox02{% endif %} + issue_id: >- + {% if 'proxmox1' in trigger.entity_id %} + proxmox1_disk_pressure + {% else %} + proxmox02_disk_pressure + {% endif %} + disk_pct: "{{ states(trigger.entity_id) | float(0) }}" + action: + - choose: + - conditions: "{{ disk_pct >= 92 }}" + sequence: + - service: repairs.create + data: + issue_id: "{{ issue_id }}" + severity: error + persistent: true + title: "{{ node_name }} disk pressure critical ({{ disk_pct | round(1) }}%)" + description: > + {{ node_name }} disk usage is critically high. + Free disk space or expand storage allocation. + - service: script.send_to_logbook + data: + topic: "PROXMOX" + message: "{{ node_name }} disk usage is critical at {{ disk_pct | round(1) }}%." + - conditions: "{{ disk_pct >= 85 }}" + sequence: + - service: repairs.create + data: + issue_id: "{{ issue_id }}" + severity: warning + persistent: true + title: "{{ node_name }} disk pressure warning ({{ disk_pct | round(1) }}%)" + description: > + {{ node_name }} disk usage has stayed above 85% for 15 minutes. + Plan cleanup before capacity reaches critical levels. + - service: script.send_to_logbook + data: + topic: "PROXMOX" + message: "{{ node_name }} disk usage warning at {{ disk_pct | round(1) }}%." + default: + - service: repairs.remove + continue_on_error: true + data: + issue_id: "{{ issue_id }}" diff --git a/config/packages/sleepiq.yaml b/config/packages/sleepiq.yaml index f70181b0..c259dd67 100755 --- a/config/packages/sleepiq.yaml +++ b/config/packages/sleepiq.yaml @@ -6,7 +6,8 @@ # SleepIQ - Bed presence and Sleep Number metrics # SleepIQ sensors, helpers, and bed-related automations. # ------------------------------------------------------------------- -# Related Issue: 1568 +# Related Issue: 1568, 1584 +# - Blog: https://www.vcloudinfo.com/2026/03/sleep-number-health-dashboard-home-assistant.html # Notes: "Carlo Snore Mode" (input_boolean) can be voice-controlled via Alexa. # Preset option strings may differ per bed; adjust "Snore"/"Flat" # below if needed to match your select entity's options. diff --git a/config/packages/telegram_bot.yaml b/config/packages/telegram_bot.yaml index e294eb21..240497bb 100644 --- a/config/packages/telegram_bot.yaml +++ b/config/packages/telegram_bot.yaml @@ -58,7 +58,7 @@ script: - action: telegram_bot.send_message continue_on_error: true data: - target: !secret telegram_allowed_chat_id_carlo + chat_id: !secret telegram_allowed_chat_id_carlo message: "{{ chunk_message }}" parse_mode: plain_text disable_web_page_preview: true @@ -74,7 +74,7 @@ script: - action: telegram_bot.send_message continue_on_error: true data: - target: !secret telegram_allowed_chat_id_carlo + 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 diff --git a/config/packages/water_delivery.yaml b/config/packages/water_delivery.yaml index 65ca0ec9..2c8502fc 100644 --- a/config/packages/water_delivery.yaml +++ b/config/packages/water_delivery.yaml @@ -10,6 +10,8 @@ # Notes: Set input_datetime.water_delivery_date on /lovelace/water (date only). # Notes: Night-before reminder fires at 5:30 PM; garage reminders on door open. # Notes: Clear button sets delivery date to yesterday to disable reminders. +# Notes: Date helper changes are logged to Activity feed with source context. +# Notes: Active (today/future) date changes also send a Telegram confirmation. ###################################################################### input_datetime: @@ -146,3 +148,55 @@ automation: entity_id: input_datetime.water_delivery_date date: >- {{ (now() - timedelta(days=1)).date().isoformat() }} + + - alias: "Water Delivery - Date Change Audit" + id: 6fc9705d-890b-4d35-8e11-f7d5b6ec8f31 + mode: queued + + trigger: + - platform: state + entity_id: input_datetime.water_delivery_date + + condition: + - condition: template + value_template: >- + {% set old = trigger.from_state.state if trigger.from_state is not none else '' %} + {% set new = trigger.to_state.state if trigger.to_state is not none else '' %} + {% set user_ctx = trigger.to_state.context.user_id | default('', true) | string | trim %} + {% set parent_ctx = trigger.to_state.context.parent_id | default('', true) | string | trim %} + {% set has_context = user_ctx != '' or parent_ctx != '' %} + {{ new not in ['unknown', 'unavailable', 'none', ''] and old != new and has_context }} + + action: + - variables: + previous_date: >- + {% set old = trigger.from_state.state if trigger.from_state is not none else '' %} + {% if old in ['unknown', 'unavailable', 'none', ''] %} + not set + {% else %} + {{ as_datetime(old).strftime('%a %b %d, %Y') | replace(' 0', ' ') }} + {% endif %} + updated_date: >- + {% set new = trigger.to_state.state if trigger.to_state is not none else '' %} + {{ as_datetime(new).strftime('%a %b %d, %Y') | replace(' 0', ' ') }} + actor_id: "{{ trigger.to_state.context.user_id | default('system', true) }}" + parent_context: "{{ trigger.to_state.context.parent_id | default('none', true) }}" + + - service: script.send_to_logbook + data: + topic: WATER DELIVERY + message: >- + Date updated from {{ previous_date }} to {{ updated_date }}. + context_user={{ actor_id }}, context_parent={{ parent_context }} + + - choose: + - conditions: + - condition: template + value_template: >- + {{ as_datetime(trigger.to_state.state).date() >= now().date() }} + sequence: + - service: script.joanna_send_telegram + data: + message: >- + Home Assistant update: water delivery date is now {{ updated_date }} + (was {{ previous_date }}).