You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
11 KiB
293 lines
11 KiB
######################################################################
|
|
# @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
|
|
# Focused dispatch health, latest activity, rolling volume, and diagnostics.
|
|
# -------------------------------------------------------------------
|
|
# Notes: The activity drill-down reads the same rolling 24-hour runtime job history as the dispatch counters.
|
|
# Notes: This view changes HA presentation only; BearClaw runtime behavior is untouched.
|
|
######################################################################
|
|
|
|
# -------------------------------------------------------------------
|
|
# Dispatch health strip (mandatory first full-width wrapper)
|
|
# -------------------------------------------------------------------
|
|
- 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(4, minmax(0, 1fr))
|
|
grid-auto-flow: row
|
|
grid-auto-rows: min-content
|
|
grid-gap: 12px
|
|
margin: 0
|
|
mediaquery:
|
|
"(max-width: 900px)":
|
|
grid-template-columns: repeat(2, minmax(0, 1fr))
|
|
cards:
|
|
- type: custom:button-card
|
|
template: bearstone_infra_kpi
|
|
entity: sensor.joanna_ha_dispatches_24h
|
|
name: HA 24H
|
|
icon: mdi:home-automation
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_kpi
|
|
entity: sensor.joanna_all_dispatches_24h
|
|
name: All 24H
|
|
icon: mdi:robot
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_kpi
|
|
entity: sensor.joanna_ha_success_rate_24h
|
|
name: HA Success
|
|
icon: mdi:percent-circle
|
|
state_display: '[[[ return `${entity.state}%`; ]]]'
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_status_kpi
|
|
entity: sensor.joanna_ha_errors_24h
|
|
name: HA Errors 24H
|
|
icon: mdi:alert-circle-outline
|
|
variables:
|
|
ok_state: '0'
|
|
healthy_text: NONE
|
|
raw_suffix: ERRORS
|
|
|
|
# -------------------------------------------------------------------
|
|
# Trend, latest state, and reset summary
|
|
# -------------------------------------------------------------------
|
|
- type: grid
|
|
column_span: 4
|
|
columns: 3
|
|
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: Dispatch Trend
|
|
|
|
- type: custom:mini-graph-card
|
|
name: HA Dispatches (24h Rolling)
|
|
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 Dispatches
|
|
card_mod:
|
|
style: !include /config/dashboards/infrastructure/card_mod/infra_card.yaml
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.joanna_ha_dispatches_7d
|
|
name: HA Dispatches 7D
|
|
icon: mdi:calendar-range
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.joanna_ha_dispatches_30d
|
|
name: HA Dispatches 30D
|
|
icon: mdi:calendar-month
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.joanna_all_dispatches_24h
|
|
name: Open Joanna Activity
|
|
icon: mdi:timeline-text-outline
|
|
state_display: '[[[ return `${entity.state} dispatches in 24h`; ]]]'
|
|
tap_action:
|
|
action: navigate
|
|
navigation_path: /dashboard-infrastructure/joanna-activity
|
|
|
|
- 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 Activity
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.bearclaw_status_telemetry
|
|
name: Latest HA Dispatch
|
|
icon: mdi:robot
|
|
state_display: >
|
|
[[[
|
|
const latest = states['sensor.bearclaw_status_telemetry']?.attributes?.dispatchStats?.latest?.haAutomation || {};
|
|
const source = latest.source || 'none';
|
|
const when = latest.dispatchedAt ? String(latest.dispatchedAt).replace('T', ' ').slice(0, 16) : '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 latest = states['sensor.bearclaw_status_telemetry']?.attributes?.dispatchStats?.latest?.haAutomation || {};
|
|
const state = latest.state || 'none';
|
|
const when = latest.completedAt ? String(latest.completedAt).replace('T', ' ').slice(0, 16) : 'n/a';
|
|
return `${state} | ${when}`;
|
|
]]]
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.joanna_all_dispatches_7d
|
|
name: All Dispatches 7D
|
|
icon: mdi:calendar-range
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.joanna_all_dispatches_30d
|
|
name: All Dispatches 30D
|
|
icon: mdi:calendar-month
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_status_kpi
|
|
entity: binary_sensor.joanna_qmd_healthy
|
|
name: QMD Health
|
|
icon: mdi:heart-pulse
|
|
variables:
|
|
ok_state: 'on'
|
|
healthy_text: HEALTHY
|
|
alert_text: DEGRADED
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.joanna_memory_docs
|
|
name: Memory Index
|
|
icon: mdi:database-search
|
|
state_display: >
|
|
[[[
|
|
const docs = entity?.state ?? '0';
|
|
const chunks = states['sensor.joanna_memory_chunks']?.state ?? '0';
|
|
const stale = states['binary_sensor.joanna_memory_index_stale']?.state === 'on';
|
|
return `${docs} docs | ${chunks} chunks${stale ? ' | STALE' : ''}`;
|
|
]]]
|
|
|
|
- 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: Codex Reset Credits
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.codex_reset_credit_status
|
|
name: Collector Status
|
|
icon: mdi:clipboard-pulse-outline
|
|
state_display: >
|
|
[[[
|
|
const usage = states['sensor.bearclaw_status_telemetry']?.attributes?.codexUsage || {};
|
|
const last = usage.lastCheckAt ? String(usage.lastCheckAt).replace('T', ' ').slice(0, 16) : 'not checked';
|
|
return `${usage.ok === true ? 'ok' : (usage.status || 'unknown')} | ${last}`;
|
|
]]]
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_status_kpi
|
|
entity: binary_sensor.codex_reset_credit_expiring_soon
|
|
name: Next Expiration
|
|
icon: mdi:calendar-alert
|
|
variables:
|
|
ok_state: 'off'
|
|
state_display: >
|
|
[[[
|
|
const raw = states['sensor.codex_reset_credit_next_expiration']?.state;
|
|
const days = Number(states['sensor.codex_reset_credit_min_days_remaining']?.state);
|
|
if (!raw || raw === 'unknown' || raw === 'unavailable') return 'NO DATA';
|
|
const when = new Date(raw).toLocaleString('en-US', {
|
|
month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit'
|
|
});
|
|
return `${when} | ${Number.isFinite(days) ? days.toFixed(1) + ' DAYS' : ''}`;
|
|
]]]
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.codex_reset_credit_status
|
|
name: Reset Slot 1
|
|
icon: mdi:numeric-1-box-outline
|
|
state_display: >
|
|
[[[
|
|
const credit = (entity?.attributes?.credits || []).find(item => Number(item.index) === 1);
|
|
if (!credit?.expires_at) return 'NO DATA';
|
|
const when = new Date(credit.expires_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
|
|
const days = Number(credit.days_remaining);
|
|
return `${when} | ${Number.isFinite(days) ? days.toFixed(1) + ' DAYS' : String(credit.status || '').toUpperCase()}`;
|
|
]]]
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.codex_reset_credit_status
|
|
name: Reset Slot 2
|
|
icon: mdi:numeric-2-box-outline
|
|
state_display: >
|
|
[[[
|
|
const credit = (entity?.attributes?.credits || []).find(item => Number(item.index) === 2);
|
|
if (!credit?.expires_at) return 'NO DATA';
|
|
const when = new Date(credit.expires_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
|
|
const days = Number(credit.days_remaining);
|
|
return `${when} | ${Number.isFinite(days) ? days.toFixed(1) + ' DAYS' : String(credit.status || '').toUpperCase()}`;
|
|
]]]
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.codex_reset_credit_status
|
|
name: Reset Slot 3
|
|
icon: mdi:numeric-3-box-outline
|
|
state_display: >
|
|
[[[
|
|
const credit = (entity?.attributes?.credits || []).find(item => Number(item.index) === 3);
|
|
if (!credit?.expires_at) return 'NO DATA';
|
|
const when = new Date(credit.expires_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
|
|
const days = Number(credit.days_remaining);
|
|
return `${when} | ${Number.isFinite(days) ? days.toFixed(1) + ' DAYS' : String(credit.status || '').toUpperCase()}`;
|
|
]]]
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_list_row
|
|
entity: sensor.codex_reset_credit_status
|
|
name: Reset Slot 4
|
|
icon: mdi:numeric-4-box-outline
|
|
state_display: >
|
|
[[[
|
|
const credit = (entity?.attributes?.credits || []).find(item => Number(item.index) === 4);
|
|
if (!credit?.expires_at) return 'NO DATA';
|
|
const when = new Date(credit.expires_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
|
|
const days = Number(credit.days_remaining);
|
|
return `${when} | ${Number.isFinite(days) ? days.toFixed(1) + ' DAYS' : String(credit.status || '').toUpperCase()}`;
|
|
]]]
|
|
|
|
- type: custom:button-card
|
|
template: bearstone_infra_status_kpi
|
|
entity: binary_sensor.joanna_session_source_indexed
|
|
name: Transcript Indexing
|
|
icon: mdi:message-text-clock-outline
|
|
variables:
|
|
ok_state: 'on'
|
|
healthy_text: ENABLED
|
|
alert_text: DISABLED
|