From a9f1314026781a2bddd4374f82c849bc8c6230bb Mon Sep 17 00:00:00 2001 From: Carlo Costanzo Date: Sun, 8 Feb 2026 16:50:26 -0500 Subject: [PATCH] Enhance dashboard configurations by updating card styles to use `var(--divider-color)` for borders, improving consistency across various YAML files. Remove deprecated Pi-hole card section and streamline infrastructure views by including top chip sections for better organization. Update README to clarify Lovelace resource loading and migration notes. --- .../homeassistant/motion_light.yaml | 58 ++ .../homeassistant/notify_leaving_zone.yaml | 50 ++ .../confirmable_notification.yaml | 86 +++ config/dashboards/README.md | 3 + .../infrastructure/card_mod/infra_card.yaml | 2 +- .../infrastructure/card_mod/infra_panel.yaml | 2 +- .../partials/activity_sections.yaml | 31 + .../partials/docker_containers_sections.yaml | 86 +-- .../partials/home_sections.yaml | 339 +++++---- .../partials/infra_top_chips_section.yaml | 41 ++ .../partials/mariadb_sections.yaml | 59 +- .../partials/proxmox_sections.yaml | 76 +- .../partials/vacuum_sections.yaml | 683 +++++++++--------- .../templates/button_card_templates.yaml | 124 +++- .../infrastructure/views/01_home.yaml | 1 + .../infrastructure/views/02_proxmox.yaml | 1 + .../infrastructure/views/04_vacuum.yaml | 3 +- .../views/05_activity_feed.yaml | 8 +- .../infrastructure/views/06_mariadb.yaml | 4 +- .../views/07_docker_containers.yaml | 1 + config/dashboards/overview/dashboard.yaml | 2 +- config/dashboards/resources.yaml | 1 + .../resources.yaml} | 12 +- .../03_pi_hole.yaml => ui-lovelace.yaml} | 14 +- tools/ha_ui_smoke.ps1 | 69 ++ 25 files changed, 1129 insertions(+), 627 deletions(-) create mode 100644 config/blueprints/automation/homeassistant/motion_light.yaml create mode 100644 config/blueprints/automation/homeassistant/notify_leaving_zone.yaml create mode 100644 config/blueprints/script/homeassistant/confirmable_notification.yaml create mode 100644 config/dashboards/infrastructure/partials/activity_sections.yaml create mode 100644 config/dashboards/infrastructure/partials/infra_top_chips_section.yaml rename config/{dashboards/infrastructure/partials/pi_hole_cards.yaml => lovelace/resources.yaml} (58%) rename config/{dashboards/infrastructure/views/03_pi_hole.yaml => ui-lovelace.yaml} (54%) create mode 100644 tools/ha_ui_smoke.ps1 diff --git a/config/blueprints/automation/homeassistant/motion_light.yaml b/config/blueprints/automation/homeassistant/motion_light.yaml new file mode 100644 index 00000000..11900708 --- /dev/null +++ b/config/blueprints/automation/homeassistant/motion_light.yaml @@ -0,0 +1,58 @@ +blueprint: + name: Motion-activated Light + description: Turn on a light when motion is detected. + domain: automation + source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml + author: Home Assistant + input: + motion_entity: + name: Motion Sensor + selector: + entity: + filter: + - device_class: occupancy + domain: binary_sensor + - device_class: motion + domain: binary_sensor + light_target: + name: Light + selector: + target: + entity: + domain: light + no_motion_wait: + name: Wait time + description: Time to leave the light on after last motion is detected. + default: 120 + selector: + number: + min: 0 + max: 3600 + unit_of_measurement: seconds + +# If motion is detected within the delay, +# we restart the script. +mode: restart +max_exceeded: silent + +triggers: + trigger: state + entity_id: !input motion_entity + from: "off" + to: "on" + +actions: + - alias: "Turn on the light" + action: light.turn_on + target: !input light_target + - alias: "Wait until there is no motion from device" + wait_for_trigger: + trigger: state + entity_id: !input motion_entity + from: "on" + to: "off" + - alias: "Wait the number of seconds that has been set" + delay: !input no_motion_wait + - alias: "Turn off the light" + action: light.turn_off + target: !input light_target diff --git a/config/blueprints/automation/homeassistant/notify_leaving_zone.yaml b/config/blueprints/automation/homeassistant/notify_leaving_zone.yaml new file mode 100644 index 00000000..e072aad2 --- /dev/null +++ b/config/blueprints/automation/homeassistant/notify_leaving_zone.yaml @@ -0,0 +1,50 @@ +blueprint: + name: Zone Notification + description: Send a notification to a device when a person leaves a specific zone. + domain: automation + source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/notify_leaving_zone.yaml + author: Home Assistant + input: + person_entity: + name: Person + selector: + entity: + filter: + domain: person + zone_entity: + name: Zone + selector: + entity: + filter: + domain: zone + notify_device: + name: Device to notify + description: Device needs to run the official Home Assistant app to receive notifications. + selector: + device: + filter: + integration: mobile_app + +triggers: + trigger: state + entity_id: !input person_entity + +variables: + zone_entity: !input zone_entity + # This is the state of the person when it's in this zone. + zone_state: "{{ states[zone_entity].name }}" + person_entity: !input person_entity + person_name: "{{ states[person_entity].name }}" + +conditions: + condition: template + # The first case handles leaving the Home zone which has a special state when zoning called 'home'. + # The second case handles leaving all other zones. + value_template: "{{ zone_entity == 'zone.home' and trigger.from_state.state == 'home' and trigger.to_state.state != 'home' or trigger.from_state.state == zone_state and trigger.to_state.state != zone_state }}" + +actions: + - alias: "Notify that a person has left the zone" + domain: mobile_app + type: notify + device_id: !input notify_device + message: "{{ person_name }} has left {{ zone_state }}" diff --git a/config/blueprints/script/homeassistant/confirmable_notification.yaml b/config/blueprints/script/homeassistant/confirmable_notification.yaml new file mode 100644 index 00000000..0106a4e1 --- /dev/null +++ b/config/blueprints/script/homeassistant/confirmable_notification.yaml @@ -0,0 +1,86 @@ +blueprint: + name: Confirmable Notification + description: >- + A script that sends an actionable notification with a confirmation before + running the specified action. + domain: script + source_url: https://github.com/home-assistant/core/blob/master/homeassistant/components/script/blueprints/confirmable_notification.yaml + author: Home Assistant + input: + notify_device: + name: Device to notify + description: Device needs to run the official Home Assistant app to receive notifications. + selector: + device: + filter: + integration: mobile_app + title: + name: "Title" + description: "The title of the button shown in the notification." + default: "" + selector: + text: + message: + name: "Message" + description: "The message body" + selector: + text: + confirm_text: + name: "Confirmation Text" + description: "Text to show on the confirmation button" + default: "Confirm" + selector: + text: + confirm_action: + name: "Confirmation Action" + description: "Action to run when notification is confirmed" + default: [] + selector: + action: + dismiss_text: + name: "Dismiss Text" + description: "Text to show on the dismiss button" + default: "Dismiss" + selector: + text: + dismiss_action: + name: "Dismiss Action" + description: "Action to run when notification is dismissed" + default: [] + selector: + action: + +mode: restart + +sequence: + - alias: "Set up variables" + variables: + action_confirm: "{{ 'CONFIRM_' ~ context.id }}" + action_dismiss: "{{ 'DISMISS_' ~ context.id }}" + - alias: "Send notification" + domain: mobile_app + type: notify + device_id: !input notify_device + title: !input title + message: !input message + data: + actions: + - action: "{{ action_confirm }}" + title: !input confirm_text + - action: "{{ action_dismiss }}" + title: !input dismiss_text + - alias: "Awaiting response" + wait_for_trigger: + - trigger: event + event_type: mobile_app_notification_action + event_data: + action: "{{ action_confirm }}" + - trigger: event + event_type: mobile_app_notification_action + event_data: + action: "{{ action_dismiss }}" + - choose: + - conditions: "{{ wait.trigger.event.data.action == action_confirm }}" + sequence: !input confirm_action + - conditions: "{{ wait.trigger.event.data.action == action_dismiss }}" + sequence: !input dismiss_action diff --git a/config/dashboards/README.md b/config/dashboards/README.md index 208ecc1c..19b964b1 100644 --- a/config/dashboards/README.md +++ b/config/dashboards/README.md @@ -48,6 +48,9 @@ This folder is referenced from `config/configuration.yaml` via: - `lovelace.resources: !include dashboards/resources.yaml` - `lovelace.dashboards: ... filename: dashboards//dashboard.yaml` +Lovelace resources are loaded from: +- `config/dashboards/resources.yaml` (referenced by `lovelace.resources`) + ### Migration / Cutover Notes - During migration you may have both storage dashboards (from the UI) and YAML dashboards (from this folder) at the same time. - Do not try to create YAML dashboards with the same dashboard ID/key as an existing storage dashboard; remove/disable the storage version first in the UI. diff --git a/config/dashboards/infrastructure/card_mod/infra_card.yaml b/config/dashboards/infrastructure/card_mod/infra_card.yaml index 66beb975..dc5407b6 100644 --- a/config/dashboards/infrastructure/card_mod/infra_card.yaml +++ b/config/dashboards/infrastructure/card_mod/infra_card.yaml @@ -12,6 +12,6 @@ | ha-card { border-radius: 18px; - border: 1px solid rgba(0,0,0,0.06); + border: 1px solid var(--divider-color); box-shadow: none; } diff --git a/config/dashboards/infrastructure/card_mod/infra_panel.yaml b/config/dashboards/infrastructure/card_mod/infra_panel.yaml index f779b063..f0f6bfcb 100644 --- a/config/dashboards/infrastructure/card_mod/infra_panel.yaml +++ b/config/dashboards/infrastructure/card_mod/infra_panel.yaml @@ -12,7 +12,7 @@ | ha-card { border-radius: 18px; - border: 1px solid rgba(0,0,0,0.06); + border: 1px solid var(--divider-color); box-shadow: none; padding: 12px; } diff --git a/config/dashboards/infrastructure/partials/activity_sections.yaml b/config/dashboards/infrastructure/partials/activity_sections.yaml new file mode 100644 index 00000000..c61bf413 --- /dev/null +++ b/config/dashboards/infrastructure/partials/activity_sections.yaml @@ -0,0 +1,31 @@ +###################################################################### +# @CCOSTAN - Follow Me on X +# For more info visit https://www.vcloudinfo.com/click-here +# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig +# ------------------------------------------------------------------- +# Infrastructure Partial - Activity sections +# Activity feed wrapped in the standard Infrastructure layout. +# ------------------------------------------------------------------- +# Notes: Uses Logbook card targeted at `sensor.activity_feed`. +###################################################################### + +- !include /config/dashboards/infrastructure/partials/infra_top_chips_section.yaml + +- type: grid + column_span: 4 + columns: 1 + square: false + cards: + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml + cards: + - type: custom:button-card + template: bearstone_infra_panel_header + name: Activity Feed + - type: logbook + target: + entity_id: + - sensor.activity_feed + grid_options: + columns: full diff --git a/config/dashboards/infrastructure/partials/docker_containers_sections.yaml b/config/dashboards/infrastructure/partials/docker_containers_sections.yaml index 7d4b4b8c..f53196f4 100644 --- a/config/dashboards/infrastructure/partials/docker_containers_sections.yaml +++ b/config/dashboards/infrastructure/partials/docker_containers_sections.yaml @@ -9,74 +9,32 @@ # Notes: Uses Portainer entities (`binary_sensor.*_status`, `button.*_restart_container`). ###################################################################### -- type: grid - column_span: 4 - columns: 4 - square: false - cards: - - type: custom:button-card - template: bearstone_infra_chip - entity: binary_sensor.node_proxmox1_updates_packages - name: Proxmox01 - icon: mdi:server - state_display: > - [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] - - type: custom:button-card - template: bearstone_infra_chip - entity: binary_sensor.node_proxmox02_updates_packages - name: Proxmox02 - icon: mdi:server - state_display: > - [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] - - type: custom:button-card - template: bearstone_infra_chip - entity: sensor.garage_ups_status - name: Garage UPS - icon: mdi:transmission-tower - - type: custom:button-card - template: bearstone_infra_chip - entity: sensor.vcloudinfo_com - name: vCloudinfo - icon: mdi:microsoft-internet-explorer - -- type: grid - column_span: 4 - columns: 1 - square: false - cards: - - type: custom:auto-entities - show_empty: true - grid_options: - columns: full - card: - type: grid - title: Docker Containers - columns: 4 - square: false - card_param: cards - filter: - include: !include /config/dashboards/infrastructure/partials/docker_container_rows_include.yaml - exclude: - - state: unavailable - sort: - method: name +- !include /config/dashboards/infrastructure/partials/infra_top_chips_section.yaml - type: grid column_span: 4 columns: 1 square: false cards: - - type: markdown - grid_options: - columns: full - content: |- - **Tip:** Hold a container row to restart it (confirmation required). + - type: custom:vertical-stack-in-card card_mod: - style: | - ha-card { - background: transparent; - border: none; - box-shadow: none; - text-align: center; - color: var(--secondary-text-color); - } + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml + cards: + - type: custom:button-card + template: bearstone_infra_panel_header + name: Docker Containers + - type: custom:auto-entities + show_empty: true + grid_options: + columns: full + card: + type: grid + columns: 4 + square: false + card_param: cards + filter: + include: !include /config/dashboards/infrastructure/partials/docker_container_rows_include.yaml + exclude: + - state: unavailable + sort: + method: name diff --git a/config/dashboards/infrastructure/partials/home_sections.yaml b/config/dashboards/infrastructure/partials/home_sections.yaml index 09b7402f..cc2aec81 100644 --- a/config/dashboards/infrastructure/partials/home_sections.yaml +++ b/config/dashboards/infrastructure/partials/home_sections.yaml @@ -9,45 +9,48 @@ # Notes: Standardized on `custom:button-card` + `custom:mini-graph-card` with `card_mod` polish. ###################################################################### +- !include /config/dashboards/infrastructure/partials/infra_top_chips_section.yaml + - type: grid column_span: 4 columns: 4 square: false cards: - type: custom:button-card - template: bearstone_infra_chip - entity: binary_sensor.node_proxmox1_updates_packages - name: Proxmox01 - icon: mdi:server - state_display: > - [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] + template: bearstone_infra_kpi + entity: sensor.total_wifi_clients + name: Wi-Fi Clients + icon: mdi:wifi - type: custom:button-card - template: bearstone_infra_chip - entity: binary_sensor.node_proxmox02_updates_packages - name: Proxmox02 - icon: mdi:server - state_display: > - [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] + template: bearstone_infra_kpi + entity: sensor.garage_ups_load + name: UPS Load + icon: mdi:battery-charging-60 - type: custom:button-card - template: bearstone_infra_chip - entity: sensor.garage_ups_status - name: Garage UPS - icon: mdi:transmission-tower + template: bearstone_infra_kpi + entity: sensor.carlo_nvr_volume_1_volume_used + name: NVR Used + icon: mdi:harddisk - type: custom:button-card - template: bearstone_infra_chip - entity: sensor.vcloudinfo_com - name: vCloudinfo - icon: mdi:microsoft-internet-explorer + template: bearstone_infra_kpi + entity: sensor.carlo_nas01_volume_1_volume_used + name: NAS Used + icon: mdi:nas - type: grid column_span: 3 - columns: 2 + columns: 3 square: false cards: - - type: vertical-stack + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml cards: - - type: custom:mini-graph-card + - type: custom:button-card + template: bearstone_infra_panel_header name: Proxmox01 + - type: custom:mini-graph-card + name: CPU / Memory icon: mdi:server hours_to_show: 24 points_per_hour: 2 @@ -55,7 +58,7 @@ animate: true show: fill: true - legend: true + legend: false icon: true name: true state: true @@ -64,8 +67,6 @@ name: CPU - entity: sensor.node_proxmox1_memory_used_percentage name: Memory - card_mod: - style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - type: grid columns: 3 square: false @@ -101,10 +102,15 @@ button_entity: button.qemu_wireguard_104_reboot name: WireGuard - - type: vertical-stack + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml cards: - - type: custom:mini-graph-card + - type: custom:button-card + template: bearstone_infra_panel_header name: Proxmox02 + - type: custom:mini-graph-card + name: CPU / Memory icon: mdi:server hours_to_show: 24 points_per_hour: 2 @@ -112,7 +118,7 @@ animate: true show: fill: true - legend: true + legend: false icon: true name: true state: true @@ -121,10 +127,8 @@ name: CPU - entity: sensor.node_proxmox02_memory_used_percentage name: Memory - card_mod: - style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - type: grid - columns: 3 + columns: 1 square: false cards: - type: custom:button-card @@ -138,9 +142,21 @@ button_entity: button.qemu_docker2_101_reboot name: Frigate + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml + cards: + - type: custom:button-card + template: bearstone_infra_panel_header + name: Pi-hole + - type: custom:pi-hole + device_id: d69637da16f7d7f3626070582be59808 + grid_options: + columns: full + - type: grid - column_span: 1 - columns: 1 + column_span: 4 + columns: 4 square: false cards: - type: custom:mini-graph-card @@ -186,22 +202,37 @@ graph: line card_mod: style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - -- type: grid - column_span: 2 - columns: 2 - square: true - cards: - type: custom:flex-horseshoe-card entities: - entity: sensor.carlo_nvr_volume_1_volume_used - name: NVR Video + name: NVR Used decimals: 1 unit: '%' - entity: sensor.carlo_nvr_volume_1_total_size name: Total decimals: 2 unit: TiB + layout: + names: + - entity_index: 0 + xpos: 50 + ypos: 22 + styles: + - font-size: 0.9em; + - opacity: 0.75; + states: + - entity_index: 0 + xpos: 50 + ypos: 54 + styles: + - font-size: 2.2em; + - font-weight: 800; + - entity_index: 1 + xpos: 50 + ypos: 76 + styles: + - font-size: 0.95em; + - opacity: 0.75; show: horseshoe_style: colorstopgradient horseshoe_scale: @@ -216,13 +247,34 @@ - type: custom:flex-horseshoe-card entities: - entity: sensor.carlo_nas01_volume_1_volume_used - name: NAS Storage + name: NAS Used decimals: 1 unit: '%' - entity: sensor.carlo_nas01_volume_1_total_size name: Total decimals: 2 unit: TiB + layout: + names: + - entity_index: 0 + xpos: 50 + ypos: 22 + styles: + - font-size: 0.9em; + - opacity: 0.75; + states: + - entity_index: 0 + xpos: 50 + ypos: 54 + styles: + - font-size: 2.2em; + - font-weight: 800; + - entity_index: 1 + xpos: 50 + ypos: 76 + styles: + - font-size: 0.95em; + - opacity: 0.75; show: horseshoe_style: colorstopgradient horseshoe_scale: @@ -235,105 +287,114 @@ card_mod: style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml -- type: grid - column_span: 2 - columns: 1 - square: false - cards: - - type: custom:mini-graph-card - name: Wi-Fi Overview - icon: mdi:wifi - hours_to_show: 24 - line_width: 2 - points_per_hour: 1 - smoothing: true - show: - graph: line - legend: true - labels: false - name: true - icon: true - state: true - entities: - - entity: sensor.total_wifi_clients - name: Total - show_state: true - show_graph: false - show_line: false - show_points: false - show_fill: false - show_legend: false - - entity: sensor.unifi_ap_office_clients - name: Office AP - show_state: true - - entity: sensor.unifi_ap_study_clients - name: Study AP - show_state: true - - entity: sensor.unifi_ap_garage_clients - name: Garage AP - show_state: true - card_mod: - style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - - type: grid column_span: 4 - columns: 3 + columns: 2 square: false cards: - - type: custom:button-card - template: bearstone_infra_device_tile - name: Garage AP - icon: mdi:access-point - entity: sensor.unifi_ap_garage_clients - label: > - [[[ return "Uptime: " + (states['sensor.unifi_ap_garage_uptime']?.state ?? 'unknown'); ]]] - variables: - button_entity: button.unifi_ap_garage_restart - name: Garage AP - - type: custom:button-card - template: bearstone_infra_device_tile - name: Office AP - icon: mdi:access-point - entity: sensor.unifi_ap_office_clients - label: > - [[[ return "Uptime: " + (states['sensor.unifi_ap_office_uptime']?.state ?? 'unknown'); ]]] - variables: - button_entity: button.unifi_ap_office_restart - name: Office AP - - type: custom:button-card - template: bearstone_infra_device_tile - name: Study AP - icon: mdi:access-point - entity: sensor.unifi_ap_study_clients - label: > - [[[ return "Uptime: " + (states['sensor.unifi_ap_study_uptime']?.state ?? 'unknown'); ]]] - variables: - button_entity: button.unifi_ap_study_restart - name: Study AP + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml + cards: + - type: custom:button-card + template: bearstone_infra_panel_header + name: Wi-Fi Overview + - type: custom:mini-graph-card + name: Clients + icon: mdi:wifi + hours_to_show: 24 + line_width: 2 + points_per_hour: 1 + smoothing: true + show: + graph: line + legend: false + labels: false + name: true + icon: true + state: true + entities: + - entity: sensor.total_wifi_clients + name: Total + show_state: true + show_graph: false + show_line: false + show_points: false + show_fill: false + show_legend: false + - entity: sensor.unifi_ap_office_clients + name: Office AP + show_state: true + - entity: sensor.unifi_ap_study_clients + name: Study AP + show_state: true + - entity: sensor.unifi_ap_garage_clients + name: Garage AP + show_state: true + - type: grid + columns: 3 + square: false + cards: + - type: custom:button-card + template: bearstone_infra_device_tile + name: Garage AP + icon: mdi:access-point + entity: sensor.unifi_ap_garage_clients + label: > + [[[ return "Uptime: " + (states['sensor.unifi_ap_garage_uptime']?.state ?? 'unknown'); ]]] + variables: + button_entity: button.unifi_ap_garage_restart + name: Garage AP + - type: custom:button-card + template: bearstone_infra_device_tile + name: Office AP + icon: mdi:access-point + entity: sensor.unifi_ap_office_clients + label: > + [[[ return "Uptime: " + (states['sensor.unifi_ap_office_uptime']?.state ?? 'unknown'); ]]] + variables: + button_entity: button.unifi_ap_office_restart + name: Office AP + - type: custom:button-card + template: bearstone_infra_device_tile + name: Study AP + icon: mdi:access-point + entity: sensor.unifi_ap_study_clients + label: > + [[[ return "Uptime: " + (states['sensor.unifi_ap_study_uptime']?.state ?? 'unknown'); ]]] + variables: + button_entity: button.unifi_ap_study_restart + name: Study AP -- type: grid - column_span: 4 - columns: 3 - square: false - cards: - - type: custom:button-card - template: bearstone_infra_tile - name: docker_10 - icon: mdi:server - entity: sensor.docker_10_apt_status - label: > - [[[ return "Last update: " + (states['sensor.docker_10_apt_last_update']?.state ?? 'unknown') + " | " + (states['sensor.docker_10_apt_reboot_status']?.state ?? ''); ]]] - - type: custom:button-card - template: bearstone_infra_tile - name: docker_69 - icon: mdi:server - entity: sensor.docker_69_apt_status - label: > - [[[ return "Last update: " + (states['sensor.docker_69_apt_last_update']?.state ?? 'unknown') + " | " + (states['sensor.docker_69_apt_reboot_status']?.state ?? ''); ]]] - - type: custom:button-card - template: bearstone_infra_tile - name: docker_14 - icon: mdi:server - entity: sensor.docker_14_apt_status - label: > - [[[ return "Last update: " + (states['sensor.docker_14_apt_last_update']?.state ?? 'unknown') + " | " + (states['sensor.docker_14_apt_reboot_status']?.state ?? ''); ]]] + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml + cards: + - type: custom:button-card + template: bearstone_infra_panel_header + name: APT Status + - type: grid + columns: 3 + square: false + cards: + - type: custom:button-card + template: bearstone_infra_tile + name: docker_10 + icon: mdi:server + entity: sensor.docker_10_apt_status + label: > + [[[ return "Last update: " + (states['sensor.docker_10_apt_last_update']?.state ?? 'unknown') + " | " + (states['sensor.docker_10_apt_reboot_status']?.state ?? ''); ]]] + - type: custom:button-card + template: bearstone_infra_tile + name: docker_69 + icon: mdi:server + entity: sensor.docker_69_apt_status + label: > + [[[ return "Last update: " + (states['sensor.docker_69_apt_last_update']?.state ?? 'unknown') + " | " + (states['sensor.docker_69_apt_reboot_status']?.state ?? ''); ]]] + - type: custom:button-card + template: bearstone_infra_tile + name: docker_14 + icon: mdi:server + entity: sensor.docker_14_apt_status + label: > + [[[ return "Last update: " + (states['sensor.docker_14_apt_last_update']?.state ?? 'unknown') + " | " + (states['sensor.docker_14_apt_reboot_status']?.state ?? ''); ]]] diff --git a/config/dashboards/infrastructure/partials/infra_top_chips_section.yaml b/config/dashboards/infrastructure/partials/infra_top_chips_section.yaml new file mode 100644 index 00000000..a3175442 --- /dev/null +++ b/config/dashboards/infrastructure/partials/infra_top_chips_section.yaml @@ -0,0 +1,41 @@ +###################################################################### +# @CCOSTAN - Follow Me on X +# For more info visit https://www.vcloudinfo.com/click-here +# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig +# ------------------------------------------------------------------- +# Infrastructure Partial - Top status chips (shared) +# Common "chips row" used across Infrastructure views. +# ------------------------------------------------------------------- +# Notes: Keep this lightweight; it should render fast on every view. +###################################################################### + +type: grid +column_span: 4 +columns: 4 +square: false +cards: +- type: custom:button-card + template: bearstone_infra_chip + entity: binary_sensor.node_proxmox1_updates_packages + name: Proxmox01 + icon: mdi:server + state_display: > + [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] +- type: custom:button-card + template: bearstone_infra_chip + entity: binary_sensor.node_proxmox02_updates_packages + name: Proxmox02 + icon: mdi:server + state_display: > + [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] +- type: custom:button-card + template: bearstone_infra_chip + entity: sensor.garage_ups_status + name: Garage UPS + icon: mdi:transmission-tower +- type: custom:button-card + template: bearstone_infra_chip + entity: sensor.vcloudinfo_com + name: vCloudinfo + icon: mdi:microsoft-internet-explorer + diff --git a/config/dashboards/infrastructure/partials/mariadb_sections.yaml b/config/dashboards/infrastructure/partials/mariadb_sections.yaml index d749f138..f7cf94a2 100644 --- a/config/dashboards/infrastructure/partials/mariadb_sections.yaml +++ b/config/dashboards/infrastructure/partials/mariadb_sections.yaml @@ -6,10 +6,41 @@ # Infrastructure Partial - mariadb sections # Reusable list extracted from a view for smaller diffs and safer edits. # ------------------------------------------------------------------- -# Notes: Stitch-inspired MariaDB layout (3 panel columns). +# Notes: Stitch-inspired MariaDB layout (KPI strip + 3 panel columns). ###################################################################### -- column_span: 1 +- !include /config/dashboards/infrastructure/partials/infra_top_chips_section.yaml + +- type: grid + column_span: 4 + columns: 4 + square: false + cards: + - type: custom:button-card + template: bearstone_infra_kpi + entity: sensor.database_size + name: DB Size + icon: mdi:database + - type: custom:button-card + template: bearstone_infra_kpi + entity: sensor.database_tables_count + name: Tables + icon: mdi:table + - type: custom:button-card + template: bearstone_infra_kpi + entity: sensor.mariadb_connections + name: Conn. + icon: mdi:lan-connect + - type: custom:button-card + template: bearstone_infra_kpi + entity: sensor.mariadb_uptime + name: Uptime + icon: mdi:timer-outline + +- type: grid + column_span: 4 + columns: 3 + square: false cards: - type: custom:vertical-stack-in-card card_mod: @@ -18,16 +49,6 @@ - type: custom:button-card template: bearstone_infra_panel_header name: Database Statistics - - type: custom:button-card - template: bearstone_infra_list_row - entity: sensor.database_size - name: Database Size - icon: mdi:database - - type: custom:button-card - template: bearstone_infra_list_row - entity: sensor.database_tables_count - name: Number of Tables - icon: mdi:table - type: custom:button-card template: bearstone_infra_list_row entity: sensor.database_total_records @@ -44,8 +65,6 @@ name: Oldest Record icon: mdi:clock-start -- column_span: 1 - cards: - type: custom:vertical-stack-in-card card_mod: style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml @@ -73,24 +92,12 @@ entity: sensor.mariadb_performance name: Performance icon: mdi:chart-line - - type: custom:button-card - template: bearstone_infra_list_row - entity: sensor.mariadb_uptime - name: Uptime - icon: mdi:timer-outline - - type: custom:button-card - template: bearstone_infra_list_row - entity: sensor.mariadb_connections - name: Active Connections - icon: mdi:lan-connect - type: custom:button-card template: bearstone_infra_list_row entity: sensor.mariadb_questions name: Total Queries icon: mdi:database-search -- column_span: 1 - cards: - type: custom:vertical-stack-in-card card_mod: style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml diff --git a/config/dashboards/infrastructure/partials/proxmox_sections.yaml b/config/dashboards/infrastructure/partials/proxmox_sections.yaml index ae4a2fc5..a3d098b8 100644 --- a/config/dashboards/infrastructure/partials/proxmox_sections.yaml +++ b/config/dashboards/infrastructure/partials/proxmox_sections.yaml @@ -9,45 +9,48 @@ # Notes: Standardized on `custom:button-card` + `custom:mini-graph-card` with `card_mod` polish. ###################################################################### +- !include /config/dashboards/infrastructure/partials/infra_top_chips_section.yaml + - type: grid column_span: 4 columns: 4 square: false cards: - type: custom:button-card - template: bearstone_infra_chip - entity: binary_sensor.node_proxmox1_updates_packages - name: Proxmox01 - icon: mdi:server - state_display: > - [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] + template: bearstone_infra_kpi + entity: sensor.node_proxmox1_cpu_used + name: P1 CPU + icon: mdi:cpu-64-bit - type: custom:button-card - template: bearstone_infra_chip - entity: binary_sensor.node_proxmox02_updates_packages - name: Proxmox02 - icon: mdi:server - state_display: > - [[[ return entity.state === 'on' ? 'Updates pending' : 'Up to date'; ]]] + template: bearstone_infra_kpi + entity: sensor.node_proxmox1_memory_used_percentage + name: P1 MEM + icon: mdi:memory - type: custom:button-card - template: bearstone_infra_chip - entity: sensor.garage_ups_status - name: Garage UPS - icon: mdi:transmission-tower + template: bearstone_infra_kpi + entity: sensor.node_proxmox02_cpu_used + name: P2 CPU + icon: mdi:cpu-64-bit - type: custom:button-card - template: bearstone_infra_chip - entity: sensor.vcloudinfo_com - name: vCloudinfo - icon: mdi:microsoft-internet-explorer + template: bearstone_infra_kpi + entity: sensor.node_proxmox02_memory_used_percentage + name: P2 MEM + icon: mdi:memory - type: grid column_span: 4 columns: 2 square: false cards: - - type: vertical-stack + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml cards: - - type: custom:mini-graph-card + - type: custom:button-card + template: bearstone_infra_panel_header name: Proxmox01 + - type: custom:mini-graph-card + name: Host CPU / Memory icon: mdi:server hours_to_show: 24 points_per_hour: 2 @@ -55,7 +58,7 @@ animate: true show: fill: true - legend: true + legend: false icon: true name: true state: true @@ -64,10 +67,8 @@ name: CPU - entity: sensor.node_proxmox1_memory_used_percentage name: Memory - card_mod: - style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - type: custom:mini-graph-card - name: Proxmox01 VMs (CPU / MEM) + name: VMs CPU / Memory icon: mdi:chart-line hours_to_show: 24 points_per_hour: 2 @@ -75,7 +76,7 @@ animate: true show: fill: false - legend: true + legend: false icon: true name: true state: false @@ -92,8 +93,6 @@ name: WireGuard CPU - entity: sensor.qemu_wireguard_104_memory_used_percentage name: WireGuard MEM - card_mod: - style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - type: grid columns: 3 square: false @@ -129,10 +128,15 @@ button_entity: button.qemu_wireguard_104_reboot name: WireGuard - - type: vertical-stack + - type: custom:vertical-stack-in-card + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml cards: - - type: custom:mini-graph-card + - type: custom:button-card + template: bearstone_infra_panel_header name: Proxmox02 + - type: custom:mini-graph-card + name: Host CPU / Memory icon: mdi:server hours_to_show: 24 points_per_hour: 2 @@ -140,7 +144,7 @@ animate: true show: fill: true - legend: true + legend: false icon: true name: true state: true @@ -149,10 +153,8 @@ name: CPU - entity: sensor.node_proxmox02_memory_used_percentage name: Memory - card_mod: - style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - type: custom:mini-graph-card - name: Frigate VM (CPU / MEM) + name: Frigate VM CPU / Memory icon: mdi:video hours_to_show: 24 points_per_hour: 2 @@ -160,7 +162,7 @@ animate: true show: fill: false - legend: true + legend: false icon: true name: true state: false @@ -169,8 +171,6 @@ name: CPU - entity: sensor.qemu_docker2_101_memory_used_percentage name: MEM - card_mod: - style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml - type: grid columns: 3 square: false diff --git a/config/dashboards/infrastructure/partials/vacuum_sections.yaml b/config/dashboards/infrastructure/partials/vacuum_sections.yaml index eda04a2d..36e48c2a 100644 --- a/config/dashboards/infrastructure/partials/vacuum_sections.yaml +++ b/config/dashboards/infrastructure/partials/vacuum_sections.yaml @@ -6,339 +6,362 @@ # Infrastructure Partial - vacuum sections # Reusable list extracted from a view for smaller diffs and safer edits. # ------------------------------------------------------------------- -# Notes: Extracted from config/dashboards/infrastructure/views/03_vacuum.yaml key `sections`. +# Notes: Extracted from config/dashboards/infrastructure/views/04_vacuum.yaml key `sections`. ###################################################################### +- !include /config/dashboards/infrastructure/partials/infra_top_chips_section.yaml + - type: grid + column_span: 4 + columns: 4 + square: false cards: - - type: tile - entity: input_text.l10s_vacuum_room_catalog - vertical: false - features_position: bottom - grid_options: - columns: full - - type: tile - entity: input_text.l10s_vacuum_room_queue - vertical: false - features_position: bottom - grid_options: - columns: full - - type: tile - entity: input_text.l10s_vacuum_rooms_cleaned_today - vertical: false - features_position: bottom + - type: custom:vertical-stack-in-card grid_options: - columns: full - - type: tile + columns: 2 + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml + cards: + - type: custom:button-card + template: bearstone_infra_panel_header + name: Vacuum + - type: custom:button-card + template: bearstone_infra_list_row + entity: vacuum.l10s_vacuum + name: L10s + icon: mdi:robot-vacuum + state_display: > + [[[ return String(entity.state || 'unknown').toUpperCase(); ]]] + - type: tile + entity: input_select.l10s_vacuum_phase + vertical: false + features_position: bottom + - type: custom:button-card + template: bearstone_infra_list_row + entity: sensor.l10s_vacuum_current_room + name: Current Room + icon: mdi:map-marker + - type: custom:button-card + template: bearstone_infra_list_row + entity: input_text.l10s_vacuum_rooms_cleaned_today + name: Rooms Cleaned (Today) + icon: mdi:check-circle-outline + - type: custom:button-card + template: bearstone_infra_list_row + entity: input_text.l10s_vacuum_room_queue + name: Room Queue + icon: mdi:format-list-bulleted + - type: custom:button-card + template: bearstone_infra_list_row + entity: input_text.l10s_vacuum_room_catalog + name: Room Catalog + icon: mdi:book-open-variant + + - type: custom:vertical-stack-in-card grid_options: - columns: full - entity: sensor.l10s_vacuum_current_room - state_content: - - state - - room_id - - last_changed - vertical: false - features_position: bottom - - type: tile - entity: input_select.l10s_vacuum_phase -- type: grid - cards: - - type: custom:xiaomi-vacuum-map-card - map_source: - camera: camera.l10s_vacuum_map - calibration_source: - camera: true - entity: vacuum.l10s_vacuum - vacuum_platform: Tasshack/dreame-vacuum - map_modes: - - template: vacuum_clean_zone - - template: vacuum_clean_point - - template: vacuum_clean_segment - predefined_selections: - - id: '1' - icon: - name: mdi:home-outline - x: -8100 - y: 12400 - label: - text: Pool-Bath - x: -8100 - y: 12400 - offset_y: 35 - outline: - - - -9950 - - 11350 - - - -6650 - - 11350 - - - -6650 - - 12900 - - - -9950 - - 12900 - - id: '2' - icon: - name: mdi:monitor-shimmer - x: -4650 - y: 10900 - label: - text: Office - x: -4650 - y: 10900 - offset_y: 35 - outline: - - - -6650 - - 7400 - - - -2800 - - 7400 - - - -2800 - - 12850 - - - -6650 - - 12850 - - id: '3' - icon: - name: mdi:home-outline - x: -5600 - y: 5250 - label: - text: Kids-Bathroom - x: -5600 - y: 5250 - offset_y: 35 - outline: - - - -6450 - - 4250 - - - -4750 - - 4250 - - - -4750 - - 6150 - - - -6450 - - 6150 - - id: '4' - icon: - name: mdi:home-outline - x: 7300 - y: 4100 - label: - text: Master-Bathroom - x: 7300 - y: 4100 - offset_y: 35 - outline: - - - 5450 - - 250 - - - 9400 - - 250 - - - 9400 - - 7850 - - - 5450 - - 7850 - - id: '6' - icon: - name: mdi:home-outline - x: -8450 - y: 4200 - label: - text: Paige-Bedroom - x: -8450 - y: 4200 - offset_y: 35 - outline: - - - -9900 - - 1600 - - - -6600 - - 1600 - - - -6600 - - 6100 - - - -9900 - - 6100 - - id: '7' - icon: - name: mdi:home-outline - x: 6450 - y: 10400 - label: - text: Master-Bedroom - x: 6450 - y: 10400 - offset_y: 35 - outline: - - - 3450 - - 7850 - - - 9550 - - 7850 - - - 9550 - - 12850 - - - 3450 - - 12850 - - id: '8' - icon: - name: mdi:home-outline - x: -8300 - y: 9300 - label: - text: Justin-Bedroom - x: -8300 - y: 9300 - offset_y: 35 - outline: - - - -9950 - - 6250 - - - -6650 - - 6250 - - - -6650 - - 11150 - - - -9950 - - 11150 - - id: '9' - icon: - name: mdi:home-outline - x: 7250 - y: -2200 - label: - text: Stacey-Office - x: 7250 - y: -2200 - offset_y: 35 - outline: - - - 5450 - - -4700 - - - 9450 - - -4700 - - - 9450 - - 350 - - - 5450 - - 350 - - id: '10' - icon: - name: mdi:sofa-outline - x: 2500 - y: 4800 - label: - text: Living Room - x: 2500 - y: 4800 - offset_y: 35 - outline: - - - -650 - - 750 - - - 5300 - - 750 - - - 5300 - - 8800 - - - -650 - - 8800 - - id: '11' - icon: - name: mdi:home-outline - x: -5350 - y: 2600 - label: - text: Garage-Hallway - x: -5350 - y: 2600 - offset_y: 35 - outline: - - - -6600 - - 1100 - - - -4050 - - 1100 - - - -4050 - - 4200 - - - -6600 - - 4200 - - id: '12' - icon: - name: mdi:home-outline - x: 700 - y: 8900 - label: - text: Dining-Room - x: 700 - y: 8900 - offset_y: 35 - outline: - - - -4350 - - 6000 - - - 2650 - - 6000 - - - 2650 - - 12650 - - - -4350 - - 12650 - - id: '13' - icon: - name: mdi:home-outline - x: -6200 - y: 6800 - label: - text: Hallway - x: -6200 - y: 6800 - offset_y: 35 - outline: - - - -7550 - - 6100 - - - -4350 - - 6100 - - - -4350 - - 7700 - - - -7550 - - 7700 - - id: '14' - icon: - name: mdi:chef-hat - x: -1700 - y: 3350 - label: - text: Kitchen - x: -1700 - y: 3350 - offset_y: 35 - outline: - - - -4200 - - 950 - - - -300 - - 950 - - - -300 - - 6100 - - - -4200 - - 6100 - - id: '15' - icon: - name: mdi:home-outline - x: 4050 - y: -1350 - label: - text: Foyer - x: 4050 - y: -1350 - offset_y: 35 - outline: - - - 2850 - - -3500 - - - 5450 - - -3500 - - - 5450 - - 800 - - - 2850 - - 800 - - id: '17' - icon: - name: mdi:home-outline - x: 750 - y: -1250 - label: - text: Formal-Dining - x: 750 - y: -1250 - offset_y: 35 - outline: - - - -1500 - - -3500 - - - 2950 - - -3500 - - - 2950 - - 950 - - - -1500 - - 950 - map_locked: true - two_finger_pan: true + columns: 2 + card_mod: + style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml + cards: + - type: custom:button-card + template: bearstone_infra_panel_header + name: Map + - type: custom:xiaomi-vacuum-map-card + map_source: + camera: camera.l10s_vacuum_map + calibration_source: + camera: true + entity: vacuum.l10s_vacuum + vacuum_platform: Tasshack/dreame-vacuum + map_modes: + - template: vacuum_clean_zone + - template: vacuum_clean_point + - template: vacuum_clean_segment + predefined_selections: + - id: '1' + icon: + name: mdi:home-outline + x: -8100 + y: 12400 + label: + text: Pool-Bath + x: -8100 + y: 12400 + offset_y: 35 + outline: + - - -9950 + - 11350 + - - -6650 + - 11350 + - - -6650 + - 12900 + - - -9950 + - 12900 + - id: '2' + icon: + name: mdi:monitor-shimmer + x: -4650 + y: 10900 + label: + text: Office + x: -4650 + y: 10900 + offset_y: 35 + outline: + - - -6650 + - 7400 + - - -2800 + - 7400 + - - -2800 + - 12850 + - - -6650 + - 12850 + - id: '3' + icon: + name: mdi:home-outline + x: -5600 + y: 5250 + label: + text: Kids-Bathroom + x: -5600 + y: 5250 + offset_y: 35 + outline: + - - -6450 + - 4250 + - - -4750 + - 4250 + - - -4750 + - 6150 + - - -6450 + - 6150 + - id: '4' + icon: + name: mdi:home-outline + x: 7300 + y: 4100 + label: + text: Master-Bathroom + x: 7300 + y: 4100 + offset_y: 35 + outline: + - - 5450 + - 250 + - - 9400 + - 250 + - - 9400 + - 7850 + - - 5450 + - 7850 + - id: '6' + icon: + name: mdi:home-outline + x: -8450 + y: 4200 + label: + text: Paige-Bedroom + x: -8450 + y: 4200 + offset_y: 35 + outline: + - - -9900 + - 1600 + - - -6600 + - 1600 + - - -6600 + - 6100 + - - -9900 + - 6100 + - id: '7' + icon: + name: mdi:home-outline + x: 6450 + y: 10400 + label: + text: Master-Bedroom + x: 6450 + y: 10400 + offset_y: 35 + outline: + - - 3450 + - 7850 + - - 9550 + - 7850 + - - 9550 + - 12850 + - - 3450 + - 12850 + - id: '8' + icon: + name: mdi:home-outline + x: -8300 + y: 9300 + label: + text: Justin-Bedroom + x: -8300 + y: 9300 + offset_y: 35 + outline: + - - -9950 + - 6250 + - - -6650 + - 6250 + - - -6650 + - 11150 + - - -9950 + - 11150 + - id: '9' + icon: + name: mdi:home-outline + x: 7250 + y: -2200 + label: + text: Stacey-Office + x: 7250 + y: -2200 + offset_y: 35 + outline: + - - 5450 + - -4700 + - - 9450 + - -4700 + - - 9450 + - 350 + - - 5450 + - 350 + - id: '10' + icon: + name: mdi:sofa-outline + x: 2500 + y: 4800 + label: + text: Living Room + x: 2500 + y: 4800 + offset_y: 35 + outline: + - - -650 + - 750 + - - 5300 + - 750 + - - 5300 + - 8800 + - - -650 + - 8800 + - id: '11' + icon: + name: mdi:home-outline + x: -5350 + y: 2600 + label: + text: Garage-Hallway + x: -5350 + y: 2600 + offset_y: 35 + outline: + - - -6600 + - 1100 + - - -4050 + - 1100 + - - -4050 + - 4200 + - - -6600 + - 4200 + - id: '12' + icon: + name: mdi:home-outline + x: 700 + y: 8900 + label: + text: Dining-Room + x: 700 + y: 8900 + offset_y: 35 + outline: + - - -4350 + - 6000 + - - 2650 + - 6000 + - - 2650 + - 12650 + - - -4350 + - 12650 + - id: '13' + icon: + name: mdi:home-outline + x: -6200 + y: 6800 + label: + text: Hallway + x: -6200 + y: 6800 + offset_y: 35 + outline: + - - -7550 + - 6100 + - - -4350 + - 6100 + - - -4350 + - 7700 + - - -7550 + - 7700 + - id: '14' + icon: + name: mdi:chef-hat + x: -1700 + y: 3350 + label: + text: Kitchen + x: -1700 + y: 3350 + offset_y: 35 + outline: + - - -4200 + - 950 + - - -300 + - 950 + - - -300 + - 6100 + - - -4200 + - 6100 + - id: '15' + icon: + name: mdi:home-outline + x: 4050 + y: -1350 + label: + text: Foyer + x: 4050 + y: -1350 + offset_y: 35 + outline: + - - 2850 + - -3500 + - - 5450 + - -3500 + - - 5450 + - 800 + - - 2850 + - 800 + - id: '17' + icon: + name: mdi:home-outline + x: 750 + y: -1250 + label: + text: Formal-Dining + x: 750 + y: -1250 + offset_y: 35 + outline: + - - -1500 + - -3500 + - - 2950 + - -3500 + - - 2950 + - 950 + - - -1500 + - 950 + map_locked: true + two_finger_pan: true diff --git a/config/dashboards/infrastructure/templates/button_card_templates.yaml b/config/dashboards/infrastructure/templates/button_card_templates.yaml index 3a2dc973..f9f59c4d 100644 --- a/config/dashboards/infrastructure/templates/button_card_templates.yaml +++ b/config/dashboards/infrastructure/templates/button_card_templates.yaml @@ -21,7 +21,7 @@ bearstone_infra_base: - padding: 14px - box-shadow: none - background: var(--ha-card-background, var(--card-background-color)) - - border: 1px solid rgba(0,0,0,0.06) + - border: 1px solid var(--divider-color) - overflow: hidden grid: - grid-template-areas: "\"i n\" \"i s\"" @@ -47,10 +47,8 @@ bearstone_infra_chip: card: - border-radius: 999px - padding: 10px 12px - - border: 1px solid rgba(0,0,0,0.06) - - background: rgba(255,255,255,0.75) - - backdrop-filter: blur(6px) - - -webkit-backdrop-filter: blur(6px) + - border: 1px solid var(--divider-color) + - background: var(--ha-card-background, var(--card-background-color)) grid: - grid-template-areas: "\"i n\" \"i s\"" - grid-template-columns: 28px 1fr @@ -139,8 +137,9 @@ bearstone_infra_device_tile: - font-weight: 700 bearstone_infra_container_row: - template: bearstone_infra_list_row_running + template: bearstone_infra_list_row show_label: false + show_state: false tap_action: action: none hold_action: @@ -151,6 +150,117 @@ bearstone_infra_container_row: confirmation: text: '[[[ return "Restart container " + entity.attributes.friendly_name + "?" ]]]' icon: mdi:docker + custom_fields: + status: > + [[[ + const s = String(entity.state || '').toLowerCase(); + if (s === 'on' || s === 'running') return 'RUNNING'; + if (s === 'off' || s === 'stopped') return 'STOPPED'; + if (s === 'unavailable') return 'OFFLINE'; + if (s === 'unknown' || s === '') return 'UNKNOWN'; + return String(entity.state).toUpperCase(); + ]]] + styles: + grid: + - grid-template-areas: "\"i n status\"" + - grid-template-columns: 24px 1fr auto + - align-items: center + - column-gap: 12px + name: + - min-width: 0 + - overflow: hidden + - text-overflow: ellipsis + - white-space: nowrap + custom_fields: + status: + - justify-self: end + - align-self: center + - font-weight: 900 + - font-size: 12px + - letter-spacing: 0.04em + - padding: 4px 10px + - border-radius: 999px + - background: rgba(0,0,0,0.06) + - color: var(--secondary-text-color) + - line-height: 1.1 + state: + - value: 'on' + styles: + card: + - border-color: rgba(67,160,71,0.45) + - background: rgba(232,245,233,0.85) + icon: + - color: rgba(46,125,50,1) + custom_fields: + status: + - background: rgba(46,125,50,0.12) + - color: rgba(46,125,50,1) + - value: 'off' + styles: + card: + - border-color: rgba(229,57,53,0.35) + - background: rgba(255,235,238,0.85) + icon: + - color: rgba(198,40,40,1) + custom_fields: + status: + - background: rgba(198,40,40,0.10) + - color: rgba(198,40,40,1) + - value: Running + styles: + card: + - border-color: rgba(67,160,71,0.45) + - background: rgba(232,245,233,0.85) + icon: + - color: rgba(46,125,50,1) + custom_fields: + status: + - background: rgba(46,125,50,0.12) + - color: rgba(46,125,50,1) + - value: running + styles: + card: + - border-color: rgba(67,160,71,0.45) + - background: rgba(232,245,233,0.85) + icon: + - color: rgba(46,125,50,1) + custom_fields: + status: + - background: rgba(46,125,50,0.12) + - color: rgba(46,125,50,1) + - value: Stopped + styles: + card: + - border-color: rgba(229,57,53,0.35) + - background: rgba(255,235,238,0.85) + icon: + - color: rgba(198,40,40,1) + custom_fields: + status: + - background: rgba(198,40,40,0.10) + - color: rgba(198,40,40,1) + - value: stopped + styles: + card: + - border-color: rgba(229,57,53,0.35) + - background: rgba(255,235,238,0.85) + icon: + - color: rgba(198,40,40,1) + custom_fields: + status: + - background: rgba(198,40,40,0.10) + - color: rgba(198,40,40,1) + - value: unavailable + styles: + card: + - border-color: rgba(229,57,53,0.35) + - background: rgba(255,235,238,0.85) + icon: + - color: rgba(198,40,40,1) + custom_fields: + status: + - background: rgba(198,40,40,0.10) + - color: rgba(198,40,40,1) bearstone_infra_panel_header: show_icon: false @@ -167,6 +277,8 @@ bearstone_infra_panel_header: name: - font-size: 18px - font-weight: 800 + - letter-spacing: 0.04em + - text-transform: uppercase - justify-self: start bearstone_infra_list_row: diff --git a/config/dashboards/infrastructure/views/01_home.yaml b/config/dashboards/infrastructure/views/01_home.yaml index d5ea1d7d..7c22b5a0 100644 --- a/config/dashboards/infrastructure/views/01_home.yaml +++ b/config/dashboards/infrastructure/views/01_home.yaml @@ -13,6 +13,7 @@ title: Infrastructure path: home type: sections icon: mdi:view-dashboard-variant +theme: default max_columns: 4 badges: [] sections: !include /config/dashboards/infrastructure/partials/home_sections.yaml diff --git a/config/dashboards/infrastructure/views/02_proxmox.yaml b/config/dashboards/infrastructure/views/02_proxmox.yaml index 90ff8120..e8fd3fe5 100644 --- a/config/dashboards/infrastructure/views/02_proxmox.yaml +++ b/config/dashboards/infrastructure/views/02_proxmox.yaml @@ -14,6 +14,7 @@ path: proxmox cards: [] type: sections icon: mdi:server +theme: default badges: [] sections: !include /config/dashboards/infrastructure/partials/proxmox_sections.yaml max_columns: 4 diff --git a/config/dashboards/infrastructure/views/04_vacuum.yaml b/config/dashboards/infrastructure/views/04_vacuum.yaml index bae82707..5f567369 100644 --- a/config/dashboards/infrastructure/views/04_vacuum.yaml +++ b/config/dashboards/infrastructure/views/04_vacuum.yaml @@ -11,6 +11,7 @@ title: Vacuum icon: mdi:robot-vacuum +theme: default type: sections cards: [] visible: @@ -19,5 +20,5 @@ visible: - user: 8fc5ba22cb32430a9143beb4df70541b - user: 19970706e7e4492c844ea2fc94a4599a sections: !include /config/dashboards/infrastructure/partials/vacuum_sections.yaml -max_columns: 2 +max_columns: 4 badges: !include /config/dashboards/infrastructure/partials/vacuum_badges.yaml diff --git a/config/dashboards/infrastructure/views/05_activity_feed.yaml b/config/dashboards/infrastructure/views/05_activity_feed.yaml index ec4b5286..046ae0de 100644 --- a/config/dashboards/infrastructure/views/05_activity_feed.yaml +++ b/config/dashboards/infrastructure/views/05_activity_feed.yaml @@ -9,8 +9,12 @@ # Notes: Exported from config/.storage/lovelace.dashboard_infrastructure view index 4. ###################################################################### -type: panel icon: mdi:clipboard-text-outline title: Activity path: activity -cards: !include /config/dashboards/infrastructure/partials/view_cards.yaml +type: sections +theme: default +max_columns: 4 +badges: [] +cards: [] +sections: !include /config/dashboards/infrastructure/partials/activity_sections.yaml diff --git a/config/dashboards/infrastructure/views/06_mariadb.yaml b/config/dashboards/infrastructure/views/06_mariadb.yaml index 84e79f06..f53bbe6c 100644 --- a/config/dashboards/infrastructure/views/06_mariadb.yaml +++ b/config/dashboards/infrastructure/views/06_mariadb.yaml @@ -12,7 +12,9 @@ type: sections title: MariaDB path: mariadb -max_columns: 3 +max_columns: 4 icon: mdi:database +theme: default +badges: [] sections: !include /config/dashboards/infrastructure/partials/mariadb_sections.yaml cards: [] diff --git a/config/dashboards/infrastructure/views/07_docker_containers.yaml b/config/dashboards/infrastructure/views/07_docker_containers.yaml index 4e0cac14..e68a78cb 100644 --- a/config/dashboards/infrastructure/views/07_docker_containers.yaml +++ b/config/dashboards/infrastructure/views/07_docker_containers.yaml @@ -13,6 +13,7 @@ title: Docker path: docker type: sections icon: mdi:docker +theme: default badges: [] sections: !include /config/dashboards/infrastructure/partials/docker_containers_sections.yaml max_columns: 4 diff --git a/config/dashboards/overview/dashboard.yaml b/config/dashboards/overview/dashboard.yaml index fb5ca1b2..6bb4a8a0 100644 --- a/config/dashboards/overview/dashboard.yaml +++ b/config/dashboards/overview/dashboard.yaml @@ -6,7 +6,7 @@ # Overview Dashboard - YAML entrypoint # YAML-exported Lovelace dashboard (split into view files). # ------------------------------------------------------------------- -# Notes: Entry point for dashboard key `lovelace`. Views are loaded from /config/dashboards/overview/views. +# Notes: Used by `/config/ui-lovelace.yaml` (main Lovelace UI). Views are loaded from /config/dashboards/overview/views. ###################################################################### title: Bear Stone diff --git a/config/dashboards/resources.yaml b/config/dashboards/resources.yaml index c9fed94a..46ae47be 100644 --- a/config/dashboards/resources.yaml +++ b/config/dashboards/resources.yaml @@ -7,6 +7,7 @@ # YAML-managed Lovelace resources (resource_mode: yaml). # ------------------------------------------------------------------- # Notes: Generated from config/.storage/lovelace_resources. Edit here after migration; do not edit .storage. +# Loaded by Home Assistant via `config/lovelace/resources.yaml`. ###################################################################### - type: module diff --git a/config/dashboards/infrastructure/partials/pi_hole_cards.yaml b/config/lovelace/resources.yaml similarity index 58% rename from config/dashboards/infrastructure/partials/pi_hole_cards.yaml rename to config/lovelace/resources.yaml index b74a17eb..e345720b 100644 --- a/config/dashboards/infrastructure/partials/pi_hole_cards.yaml +++ b/config/lovelace/resources.yaml @@ -3,13 +3,11 @@ # For more info visit https://www.vcloudinfo.com/click-here # Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig # ------------------------------------------------------------------- -# Infrastructure Partial - pi_hole cards -# Reusable list extracted from a view for smaller diffs and safer edits. +# Lovelace Resources - Custom card JS resources +# YAML-managed Lovelace resources (resource_mode: yaml). # ------------------------------------------------------------------- -# Notes: Extracted from config/dashboards/infrastructure/views/02_pi_hole.yaml key `cards`. +# Notes: This file is NOT used in this repo's wiring. +# Resources are loaded via `lovelace.resources: !include dashboards/resources.yaml` in `configuration.yaml`. ###################################################################### -- type: custom:pi-hole - device_id: d69637da16f7d7f3626070582be59808 - grid_options: - columns: full +# (Intentionally empty) diff --git a/config/dashboards/infrastructure/views/03_pi_hole.yaml b/config/ui-lovelace.yaml similarity index 54% rename from config/dashboards/infrastructure/views/03_pi_hole.yaml rename to config/ui-lovelace.yaml index 14cf420c..cfd5a351 100644 --- a/config/dashboards/infrastructure/views/03_pi_hole.yaml +++ b/config/ui-lovelace.yaml @@ -3,16 +3,10 @@ # For more info visit https://www.vcloudinfo.com/click-here # Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig # ------------------------------------------------------------------- -# Infrastructure View - Pi-Hole -# YAML-exported Lovelace dashboard (split into view files). +# Lovelace UI - Overview dashboard (YAML mode) +# Main Lovelace UI entrypoint (defined as a YAML dashboard in `configuration.yaml`). # ------------------------------------------------------------------- -# Notes: Exported from config/.storage/lovelace.dashboard_infrastructure view index 2. +# Notes: Delegates to `/config/dashboards/overview/dashboard.yaml`. ###################################################################### -type: panel -path: pi-hole -title: Pi-Hole -icon: mdi:pi-hole -visible: -- user: be280a93c9d7416e98d25d0470f414be -cards: !include /config/dashboards/infrastructure/partials/pi_hole_cards.yaml +!include /config/dashboards/overview/dashboard.yaml diff --git a/tools/ha_ui_smoke.ps1 b/tools/ha_ui_smoke.ps1 new file mode 100644 index 00000000..b1a11505 --- /dev/null +++ b/tools/ha_ui_smoke.ps1 @@ -0,0 +1,69 @@ +param( + [string]$BaseUrl = $env:HASS_PLAYWRIGHT_BASE_URL +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +if ([string]::IsNullOrWhiteSpace($BaseUrl)) { + # Canonical LAN URL for agent automation (trusted_networks bypass). + $BaseUrl = 'http://192.168.10.10:8123' +} + +$BaseUrl = $BaseUrl.TrimEnd('/') + +function Get-EffectiveUrlAndStatus { + param( + [Parameter(Mandatory = $true)] + [string]$Url + ) + + # Use curl.exe (not Invoke-WebRequest alias) so we can reliably see redirects. + $curl = (Get-Command curl.exe -ErrorAction Stop).Source + + # Follow redirects; return final URL + status code. + $out = & $curl -sS -L -o NUL -w "%{url_effective} %{http_code}" $Url 2>$null + if (-not $out) { throw "curl produced no output for $Url" } + $parts = $out -split ' ' + if ($parts.Count -lt 2) { throw "Unexpected curl output: $out" } + + [pscustomobject]@{ + EffectiveUrl = $parts[0] + StatusCode = [int]$parts[1] + } +} + +$targets = @( + '/', + '/profile', + '/dashboard-infrastructure', + '/dashboard-infrastructure/docker', + '/dashboard-infrastructure/mariadb', + '/dashboard-kiosk' +) + +$failed = $false +foreach ($path in $targets) { + $url = "$BaseUrl$path" + $r = Get-EffectiveUrlAndStatus -Url $url + + $isLogin = $r.EffectiveUrl -match '/(login|auth/authorize)\b' + $statusOk = $r.StatusCode -ge 200 -and $r.StatusCode -lt 400 + + if ($isLogin -or -not $statusOk) { + $failed = $true + Write-Host ("FAIL {0} -> {1} ({2})" -f $url, $r.EffectiveUrl, $r.StatusCode) + } else { + Write-Host ("OK {0} -> {1} ({2})" -f $url, $r.EffectiveUrl, $r.StatusCode) + } +} + +if ($failed) { + Write-Host '' + Write-Host 'Likely causes:' + Write-Host '- Base URL is external (Cloudflared/Nabu Casa) instead of LAN.' + Write-Host '- Home Assistant does not see the request IP as trusted; check `homeassistant.auth_providers.trusted_networks`.' + exit 1 +} + +exit 0