Enhance Home Assistant configuration and dashboards

- Updated configuration.yaml to include trusted users for network authentication.
- Added BearClaw status telemetry sensor and related KPI sensors in bearclaw.yaml for improved monitoring.
- Enhanced infrastructure dashboard with a new Joanna Dispatch button card for telemetry display.
- Updated README.md to reflect new BearClaw telemetry features and sensor integrations.
feature/powerwall-live-activity-1598
Carlo Costanzo 2 weeks ago
parent e1528c3bbb
commit 7908ee7b49

@ -15,12 +15,15 @@ homeassistant:
initial_state: 'on' initial_state: 'on'
packages: !include_dir_named packages packages: !include_dir_named packages
auth_providers: auth_providers:
- type: homeassistant
- type: trusted_networks - type: trusted_networks
trusted_networks: trusted_networks:
- 192.168.10.0/24 - 192.168.10.0/24
# - !secret external_ip # - !secret external_ip
trusted_users:
192.168.10.17: be280a93c9d7416e98d25d0470f414be
192.168.10.88: be280a93c9d7416e98d25d0470f414be
allow_bypass_login: true allow_bypass_login: true
- type: homeassistant
default_config: default_config:

@ -7,6 +7,7 @@
# YAML-exported Lovelace dashboard (split into view files). # YAML-exported Lovelace dashboard (split into view files).
# ------------------------------------------------------------------- # -------------------------------------------------------------------
# Notes: Entry point for dashboard key `dashboard-infrastructure`. Views are loaded from /config/dashboards/infrastructure/views. # Notes: Entry point for dashboard key `dashboard-infrastructure`. Views are loaded from /config/dashboards/infrastructure/views.
# Notes: Joanna dispatch telemetry view is available at `/dashboard-infrastructure/joanna`.
###################################################################### ######################################################################
button_card_templates: !include /config/dashboards/infrastructure/templates/button_card_templates.yaml button_card_templates: !include /config/dashboards/infrastructure/templates/button_card_templates.yaml

@ -40,7 +40,22 @@
cards: cards:
- type: custom:button-card - type: custom:button-card
template: bearstone_infra_panel_header template: bearstone_infra_panel_header
name: Alerts name: Infrastructure Status
- type: custom:button-card
template: bearstone_infra_list_row
entity: sensor.joanna_ha_dispatches_24h
name: Joanna Dispatch
icon: mdi:robot
tap_action:
action: navigate
navigation_path: /dashboard-infrastructure/joanna
state_display: >
[[[
const ha24 = states['sensor.joanna_ha_dispatches_24h']?.state ?? '0';
const all24 = states['sensor.joanna_all_dispatches_24h']?.state ?? '0';
const queue = states['sensor.joanna_queue_pending']?.state ?? '0';
return `HA ${ha24} | All ${all24} | Q ${queue}`;
]]]
- type: custom:button-card - type: custom:button-card
template: bearstone_infra_list_row template: bearstone_infra_list_row
@ -503,7 +518,7 @@
name: UPS Battery name: UPS Battery
icon: mdi:battery-70 icon: mdi:battery-70
state_display: > state_display: >
[[[ [[[
const v = Number(entity?.state); const v = Number(entity?.state);
return Number.isFinite(v) ? `${v.toFixed(0)}%` : (entity?.state ?? 'unknown'); return Number.isFinite(v) ? `${v.toFixed(0)}%` : (entity?.state ?? 'unknown');
]]] ]]]
@ -514,7 +529,7 @@
name: Runtime Remaining name: Runtime Remaining
icon: mdi:timer-outline icon: mdi:timer-outline
state_display: > state_display: >
[[[ [[[
const secs = parseInt(entity?.state, 10); const secs = parseInt(entity?.state, 10);
if (!Number.isFinite(secs)) return entity?.state ?? 'unknown'; if (!Number.isFinite(secs)) return entity?.state ?? 'unknown';
const hours = Math.floor(secs / 3600); const hours = Math.floor(secs / 3600);
@ -528,7 +543,7 @@
name: On Battery name: On Battery
icon: mdi:battery-alert-variant-outline icon: mdi:battery-alert-variant-outline
state_display: > state_display: >
[[[ [[[
const s = String(entity?.state || '').toUpperCase(); const s = String(entity?.state || '').toUpperCase();
return s.includes('OB') ? 'Yes' : 'No'; return s.includes('OB') ? 'Yes' : 'No';
]]] ]]]

@ -0,0 +1,172 @@
######################################################################
# @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 - Joanna sections
# Joanna/BearClaw dispatch KPI, trend, latest-state, and filtered activity panels.
# -------------------------------------------------------------------
# Notes: Reuses shared bearstone_infra_* templates and standard infra card_mod snippets.
######################################################################
- type: grid
column_span: 4
columns: 6
square: false
cards:
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_ha_dispatches_24h
name: HA 24H
icon: mdi:calendar-clock
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_ha_dispatches_7d
name: HA 7D
icon: mdi:calendar-range
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_ha_dispatches_30d
name: HA 30D
icon: mdi:calendar-month
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_ha_errors_24h
name: HA Errors 24H
icon: mdi:alert-circle-outline
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_all_dispatches_24h
name: All 24H
icon: mdi:calendar-clock
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_all_dispatches_7d
name: All 7D
icon: mdi:calendar-range
- type: custom:button-card
template: bearstone_infra_kpi
entity: sensor.joanna_all_dispatches_30d
name: All 30D
icon: mdi:calendar-month
- type: grid
column_span: 4
columns: 2
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: HA Dispatch Trend
- type: custom:mini-graph-card
name: HA Dispatches (24h Window)
icon: mdi:chart-timeline-variant
hours_to_show: 168
points_per_hour: 1
line_width: 2
smoothing: true
show:
legend: false
labels: false
name: true
icon: true
state: true
entities:
- entity: sensor.joanna_ha_dispatches_24h
name: HA 24h
card_mod:
style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml
- 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: Latest Snapshot
- type: custom:button-card
template: bearstone_infra_list_row
entity: sensor.bearclaw_status_telemetry
name: Latest HA Dispatch
icon: mdi:robot
state_display: >
[[[
const stats = states['sensor.bearclaw_status_telemetry']?.attributes?.dispatchStats || {};
const latest = stats?.latest?.haAutomation || {};
const source = latest?.source || 'none';
const when = latest?.dispatchedAt || 'n/a';
return `${source} | ${when}`;
]]]
- type: custom:button-card
template: bearstone_infra_list_row
entity: sensor.bearclaw_status_telemetry
name: Latest HA Completion
icon: mdi:check-circle-outline
state_display: >
[[[
const stats = states['sensor.bearclaw_status_telemetry']?.attributes?.dispatchStats || {};
const latest = stats?.latest?.haAutomation || {};
const state = latest?.state || 'none';
const when = latest?.completedAt || 'n/a';
return `${state} | ${when}`;
]]]
- type: custom:button-card
template: bearstone_infra_list_row
entity: sensor.bearclaw_status_telemetry
name: Latest Any Dispatch
icon: mdi:robot-excited
state_display: >
[[[
const stats = states['sensor.bearclaw_status_telemetry']?.attributes?.dispatchStats || {};
const latest = stats?.latest?.all || {};
const source = latest?.source || 'none';
const when = latest?.dispatchedAt || 'n/a';
return `${source} | ${when}`;
]]]
- type: custom:button-card
template: bearstone_infra_list_row
entity: sensor.bearclaw_status_telemetry
name: HA Success (24h)
icon: mdi:percent-circle
state_display: >
[[[
const v = states['sensor.joanna_ha_success_rate_24h']?.state ?? '0';
return `${v}%`;
]]]
- type: grid
column_span: 4
columns: 1
square: false
cards:
- type: custom:layout-card
grid_options:
columns: full
layout_type: custom:grid-layout
layout:
grid-template-columns: repeat(1, minmax(0, 1fr))
grid-auto-flow: row
grid-auto-rows: min-content
grid-gap: 12px
margin: 0
cards:
- type: custom:vertical-stack-in-card
grid_options:
columns: full
card_mod:
style: !include /config/dashboards/infrastructure/card_mod/infra_panel.yaml
cards:
- type: custom:button-card
template: bearstone_infra_panel_header
name: Joanna Activity
# Fallback card: Lovelace logbook card is required to show filtered activity history.
- type: logbook
hours_to_show: 72
entities:
- automation.bearclaw_reply_webhook
- automation.tugtainer_dispatch_joanna_for_available_updates
- script.joanna_dispatch

@ -0,0 +1,20 @@
######################################################################
# @CCOSTAN - Follow Me on X
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Infrastructure View - Joanna
# Dispatch and activity telemetry for BearClaw/Joanna.
# -------------------------------------------------------------------
# Notes: Uses telemetry from /api/bearclaw/status ingested by bearclaw.yaml.
######################################################################
type: sections
title: Joanna
path: joanna
max_columns: 4
icon: mdi:robot
theme: default
badges: []
sections: !include /config/dashboards/infrastructure/partials/joanna_sections.yaml
cards: []

@ -52,7 +52,7 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this
| [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` | | [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` | | [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, plus event-based Joanna dispatch when reports include `### Available:` (24h cooldown via `mode: single` + delay, no new helpers). | `persistent_notification.create`, `event: tugtainer_available_detected`, `script.joanna_dispatch`, `input_datetime.tugtainer_last_update` | | [tugtainer_updates.yaml](tugtainer_updates.yaml) | Tugtainer container update notifications via webhook + persistent alerts, plus event-based Joanna dispatch when reports include `### Available:` (24h cooldown via `mode: single` + delay, no new helpers). | `persistent_notification.create`, `event: tugtainer_available_detected`, `script.joanna_dispatch`, `input_datetime.tugtainer_last_update` |
| [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 | | [bearclaw.yaml](bearclaw.yaml) | Joanna/BearClaw bridge automations that forward Telegram commands to codex_appliance, relay replies back, ingest `/api/bearclaw/status` telemetry, and expose dispatch KPI sensors for Infrastructure dashboards. | `rest_command.bearclaw_*`, `sensor.bearclaw_status_telemetry`, `sensor.joanna_*`, `automation.bearclaw_*`, `script.send_to_logbook` |
| [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` | | [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` | | [phynplus.yaml](phynplus.yaml) | Phyn shutoff automations with push + Activity feed + Repairs issues for leak events. | `valve.phyn_shutoff_valve`, `binary_sensor.phyn_leak_test_running`, `repairs.create` |
| [water_delivery.yaml](water_delivery.yaml) | ReadyRefresh delivery date helper with night-before + garage door Alexa reminders, plus helper-change audit logging and Telegram confirmations. | `input_datetime.water_delivery_date`, `script.send_to_logbook`, `script.joanna_send_telegram`, `notify.alexa_media_garage` | | [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` |

@ -13,6 +13,8 @@
# Notes: Telegram inline button callbacks are handled here and mapped to BearClaw commands. # 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: Inbound Telegram handling enforces user_id + chat_id allowlists from secrets CSV values.
# Notes: Reply webhook writes JOANNA activity entries to logbook for traceability. # Notes: Reply webhook writes JOANNA activity entries to logbook for traceability.
# Notes: Status telemetry polling expects !secret bearclaw_status_url (token header stays !secret bearclaw_token).
# Notes: Blog: https://www.vcloudinfo.com/2026/03/joanna-dispatch-telemetry-home-assistant-infrastructure-dashboard/
###################################################################### ######################################################################
rest_command: rest_command:
@ -43,6 +45,139 @@ rest_command:
"wake": {{ wake | default(false) | tojson }}, "wake": {{ wake | default(false) | tojson }},
"source": "home_assistant" "source": "home_assistant"
} }
sensor:
- platform: rest
name: BearClaw Status Telemetry
unique_id: bearclaw_status_telemetry
resource: !secret bearclaw_status_url
method: GET
scan_interval: 60
timeout: 30
headers:
x-codex-token: !secret bearclaw_token
value_template: "{{ 'ok' if value_json.ok | default(false) else 'error' }}"
json_attributes:
- dispatchStats
- queue
- active
template:
- sensor:
- name: Joanna HA Dispatches 24h
unique_id: joanna_ha_dispatches_24h
icon: mdi:calendar-clock
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('h24', {}).get('haAutomation', {}).get('dispatched', 0) | int(0) }}
- name: Joanna HA Dispatches 7d
unique_id: joanna_ha_dispatches_7d
icon: mdi:calendar-range
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('d7', {}).get('haAutomation', {}).get('dispatched', 0) | int(0) }}
- name: Joanna HA Dispatches 30d
unique_id: joanna_ha_dispatches_30d
icon: mdi:calendar-month
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('d30', {}).get('haAutomation', {}).get('dispatched', 0) | int(0) }}
- name: Joanna HA Completed 24h
unique_id: joanna_ha_completed_24h
icon: mdi:check-decagram
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('h24', {}).get('haAutomation', {}).get('completed', 0) | int(0) }}
- name: Joanna HA Success Rate 24h
unique_id: joanna_ha_success_rate_24h
icon: mdi:percent-circle
unit_of_measurement: '%'
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('h24', {}).get('haAutomation', {}).get('successRatePct', 0) | float(0) }}
- name: Joanna HA Errors 24h
unique_id: joanna_ha_errors_24h
icon: mdi:alert-circle-outline
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{% set outcomes = stats.get('windows', {}).get('h24', {}).get('haAutomation', {}).get('outcomes', {}) %}
{{ (outcomes.get('error', 0) | int(0)) + (outcomes.get('notify_error', 0) | int(0)) }}
- name: Joanna All Dispatches 24h
unique_id: joanna_all_dispatches_24h
icon: mdi:calendar-clock
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('h24', {}).get('all', {}).get('dispatched', 0) | int(0) }}
- name: Joanna All Dispatches 7d
unique_id: joanna_all_dispatches_7d
icon: mdi:calendar-range
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('d7', {}).get('all', {}).get('dispatched', 0) | int(0) }}
- name: Joanna All Dispatches 30d
unique_id: joanna_all_dispatches_30d
icon: mdi:calendar-month
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{{ stats.get('windows', {}).get('d30', {}).get('all', {}).get('dispatched', 0) | int(0) }}
- name: Joanna Queue Pending
unique_id: joanna_queue_pending
icon: mdi:playlist-clock
unit_of_measurement: jobs
state_class: measurement
state: >-
{% set queue = state_attr('sensor.bearclaw_status_telemetry', 'queue') | default({}, true) %}
{{ queue.get('pending', 0) | int(0) }}
- name: Joanna Active Job Minutes
unique_id: joanna_active_job_minutes
icon: mdi:timer-outline
unit_of_measurement: min
state_class: measurement
state: >-
{% set active = state_attr('sensor.bearclaw_status_telemetry', 'active') | default({}, true) %}
{% set elapsed_ms = active.get('elapsedMs', 0) | int(0) %}
{{ (elapsed_ms / 60000) | round(1) }}
- name: Joanna Minutes Since HA Dispatch
unique_id: joanna_minutes_since_ha_dispatch
icon: mdi:clock-fast
unit_of_measurement: min
state_class: measurement
state: >-
{% set stats = state_attr('sensor.bearclaw_status_telemetry', 'dispatchStats') | default({}, true) %}
{% set dispatched_at = stats.get('latest', {}).get('haAutomation', {}).get('dispatchedAt') %}
{% set dispatched_ts = as_timestamp(dispatched_at, 0) %}
{% if dispatched_ts > 0 %}
{{ ((as_timestamp(now()) - dispatched_ts) / 60) | round(1) }}
{% else %}
0
{% endif %}
automation: automation:
- id: bearclaw_telegram_bear_command - id: bearclaw_telegram_bear_command
alias: BearClaw Telegram Bear Command alias: BearClaw Telegram Bear Command

@ -86,3 +86,4 @@ wolframalpha_chanukkah_api: https://api.wolframalpha.com/v2/result?appid=JIUY8U-
wolframalpha_labor_api: https://api.wolframalpha.com/v2/result?appid=JIUY8U-4V8KY45VT1&i=How%20many%20days%20until%labor%20day wolframalpha_labor_api: https://api.wolframalpha.com/v2/result?appid=JIUY8U-4V8KY45VT1&i=How%20many%20days%20until%labor%20day
wolframalpha_memorial_api: https://api.wolframalpha.com/v2/result?appid=JIUY8U-4V8KY45VT1&i=How%20many%20days%20until%20memorial wolframalpha_memorial_api: https://api.wolframalpha.com/v2/result?appid=JIUY8U-4V8KY45VT1&i=How%20many%20days%20until%20memorial
wolframalpha_thanksgiving_api: https://api.wolframalpha.com/v2/result?appid=JIUY8U-4V8KY45VT1&i=How%20many%20days%20until%20thanksgiving wolframalpha_thanksgiving_api: https://api.wolframalpha.com/v2/result?appid=JIUY8U-4V8KY45VT1&i=How%20many%20days%20until%20thanksgiving
bearclaw_status_url: http://docker17.local:8124/api/bearclaw/status

@ -40,6 +40,7 @@ $targets = @(
'/profile', '/profile',
'/dashboard-infrastructure', '/dashboard-infrastructure',
'/dashboard-infrastructure/home', '/dashboard-infrastructure/home',
'/dashboard-infrastructure/joanna',
'/dashboard-infrastructure/docker', '/dashboard-infrastructure/docker',
'/dashboard-kiosk' '/dashboard-kiosk'
) )

Loading…
Cancel
Save

Powered by TurnKey Linux.