Update recorder configuration and enhance dashboard sections

- Increased database retention period from 30 to 180 days in recorder.yaml.
- Added additional exclusions for telemetry data in recorder.yaml to reduce noise.
- Updated health_sections.yaml for improved formatting consistency.
- Revised water_sections.yaml notes to clarify included telemetry.
- Changed overview view title from "Utilities" to "Home Maintenance" in 07_water.yaml for better context.
feature/powerwall-live-activity-1598
Carlo Costanzo 3 weeks ago
parent 41cb72e478
commit 220c8c453b

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

@ -318,8 +318,8 @@
points_per_hour: 1
line_width: 3
graph: line
show:
fill: false
points: false
extrema: true
show:
fill: false
points: false
extrema: true

@ -7,6 +7,7 @@
# Reusable list extracted from a view for smaller diffs and safer edits.
# -------------------------------------------------------------------
# Notes: Extracted from config/dashboards/overview/views/07_water.yaml key `sections`.
# Notes: Includes water and home utility telemetry (filters, power, hot water).
######################################################################
- cards:

@ -3,13 +3,14 @@
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Overview View - Utilities
# Overview View - Home Maintenance
# YAML-exported Lovelace dashboard (split into view files).
# -------------------------------------------------------------------
# Notes: Exported from config/.storage/lovelace.lovelace view index 7.
# Notes: Keep path as `water` to preserve existing links and automations.
######################################################################
title: Utilities
title: Home Maintenance
path: water
icon: mdi:home-lightning-bolt
type: sections

@ -56,6 +56,7 @@ Live collection of plug-and-play Home Assistant packages. Each YAML file in this
| [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, 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` |
| [maintenance_log.yaml](maintenance_log.yaml) | Joanna maintenance webhook ingest for water softener salt with idempotent event handling, Activity feed logging, and recorder-backed helper history for long-term graphing. | `automation.maintenance_log_joanna_webhook_ingest`, `input_number.water_softener_salt_total_added_lb`, `counter.water_softener_salt_event_count`, `sensor.water_softener_salt_days_since_last_add` |
| [powerwall.yaml](powerwall.yaml) | Track Tesla Powerwall grid status and shed loads automatically when off-grid (alerts include Activity feed + Repairs). | `binary_sensor.powerwall_grid_status`, `sensor.powerwall_*`, `repairs.create` |
| [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` |

@ -0,0 +1,315 @@
######################################################################
# @CCOSTAN - Follow Me on X
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# Maintenance Logging - Joanna webhook ingest + graphable HA history
# Stores water softener salt maintenance events in recorder-backed helpers.
# -------------------------------------------------------------------
# Notes: Webhook id is bearclaw_maintenance_log_v1 (Joanna -> HA contract).
# Notes: Duplicate event_id values are ignored to prevent double-count totals.
# Notes: Recent event history string format is "when|amount|note||...".
######################################################################
input_number:
water_softener_salt_last_amount_lb:
name: "Softener salt last amount"
min: 0
max: 1000
step: 0.1
mode: box
unit_of_measurement: lb
icon: mdi:shaker
water_softener_salt_total_added_lb:
name: "Softener salt total added"
min: 0
max: 100000
step: 0.1
mode: box
unit_of_measurement: lb
icon: mdi:chart-line
counter:
water_softener_salt_event_count:
name: "Softener salt event count"
step: 1
icon: mdi:counter
input_datetime:
water_softener_salt_last_occurred_at:
name: "Softener salt last occurred at"
has_date: true
has_time: true
icon: mdi:calendar-clock
input_text:
water_softener_salt_last_note:
name: "Softener salt last note"
max: 255
icon: mdi:text-box-outline
water_softener_salt_recent_event_ids:
name: "Softener salt recent event ids"
max: 255
icon: mdi:identifier
water_softener_salt_recent_events:
name: "Softener salt recent events"
max: 255
icon: mdi:history
template:
- sensor:
- name: "Water Softener Salt Days Since Last Add"
unique_id: water_softener_salt_days_since_last_add
unit_of_measurement: d
state: >-
{% set raw = states('input_datetime.water_softener_salt_last_occurred_at') %}
{% if raw in ['unknown', 'unavailable', 'none', ''] %}
unknown
{% else %}
{% set event_ts = as_timestamp(as_local(as_datetime(raw)), default=none) %}
{% if event_ts is none %}
unknown
{% else %}
{{ [((as_timestamp(now()) - event_ts) / 86400), 0] | max | round(1) }}
{% endif %}
{% endif %}
- name: "Water Softener Salt Last Summary"
unique_id: water_softener_salt_last_summary
icon: mdi:clipboard-text-clock-outline
state: >-
{% set raw = states('input_datetime.water_softener_salt_last_occurred_at') %}
{% set amount = states('input_number.water_softener_salt_last_amount_lb') | float(0) %}
{% set note = states('input_text.water_softener_salt_last_note') %}
{% if raw in ['unknown', 'unavailable', 'none', ''] %}
No salt events logged yet.
{% else %}
{% set when = as_datetime(raw).astimezone().strftime('%a %b %d, %Y %I:%M %p') | replace(' 0', ' ') %}
{% if note in ['unknown', 'unavailable', 'none', ''] %}
{{ amount | round(1) }} lb on {{ when }}
{% else %}
{{ amount | round(1) }} lb on {{ when }} - {{ note }}
{% endif %}
{% endif %}
- name: "Water Softener Salt Average Days Between Refills"
unique_id: water_softener_salt_average_days_between_refills
unit_of_measurement: d
state: >-
{% set raw = states('input_text.water_softener_salt_recent_events') %}
{% if raw in ['unknown', 'unavailable', 'none', ''] %}
150
{% else %}
{% set entries = raw.split('||') %}
{% set ns = namespace(previous_ts=none, total_days=0, sample_count=0) %}
{% for entry in entries %}
{% set parts = entry.split('|') %}
{% set dt = as_datetime(parts[0] | default('', true) | trim, default=none) %}
{% if dt is not none %}
{% set ts = as_timestamp(dt, default=none) %}
{% if ts is not none %}
{% if ns.previous_ts is not none and ns.previous_ts > ts %}
{% set ns.total_days = ns.total_days + ((ns.previous_ts - ts) / 86400) %}
{% set ns.sample_count = ns.sample_count + 1 %}
{% endif %}
{% set ns.previous_ts = ts %}
{% endif %}
{% endif %}
{% endfor %}
{% if ns.sample_count > 0 %}
{{ (ns.total_days / ns.sample_count) | round(1) }}
{% else %}
150
{% endif %}
{% endif %}
automation:
- alias: "Maintenance Log - Joanna Webhook Ingest"
id: 1c9fba4f-fef5-4da9-82d4-4049deff17cf
mode: queued
max: 30
trigger:
- platform: webhook
webhook_id: bearclaw_maintenance_log_v1
allowed_methods:
- POST
- PUT
local_only: false
variables:
payload: "{{ trigger.json if trigger.json is mapping else dict() }}"
source_item: "{{ payload.item_key | default('', true) | string | trim | lower }}"
item_key: >-
{% set aliases = {
'water_softener_salt': 'water_softener_salt',
'softener_salt': 'water_softener_salt',
'water_softener': 'water_softener_salt',
'softener': 'water_softener_salt',
'water softener salt': 'water_softener_salt',
'salt': 'water_softener_salt',
'softner': 'water_softener_salt'
} %}
{{ aliases.get(source_item, source_item) }}
action: "{{ payload.action | default('add', true) | string | trim | lower }}"
source_unit: "{{ payload.amount_unit | default('lb', true) | string | trim | lower }}"
unit: >-
{% set units = {
'lb': 'lb',
'lbs': 'lb',
'pound': 'lb',
'pounds': 'lb'
} %}
{{ units.get(source_unit, source_unit) }}
amount_value: "{{ payload.amount_value | default(0, true) | float(0) }}"
amount_lb: >-
{% if unit == 'lb' %}
{{ amount_value | round(2) }}
{% else %}
0
{% endif %}
event_id: >-
{% set raw_id = payload.event_id | default('', true) | string | trim %}
{% if raw_id %}
{{ raw_id }}
{% else %}
maint_{{ now().timestamp() | int }}
{% endif %}
occurred_at_raw: "{{ payload.occurred_at | default(now().isoformat(), true) }}"
occurred_at: >-
{% set parsed = as_datetime(occurred_at_raw, default=none) %}
{% if parsed is none %}
{{ now().isoformat() }}
{% else %}
{{ parsed.isoformat() }}
{% endif %}
occurred_local_datetime: >-
{% set dt = as_local(as_datetime(occurred_at, default=now())) %}
{{ dt.strftime('%Y-%m-%d %H:%M:%S') }}
occurred_display: >-
{% set dt = as_datetime(occurred_local_datetime, default=now()) %}
{{ dt.strftime('%Y-%m-%d %I:%M %p') | replace(' 0', ' ') }}
actor: "{{ payload.actor | default('unknown', true) | string | trim }}"
raw_text: "{{ payload.raw_text | default('', true) | string | replace('|', '/') | trim }}"
parse_confidence: "{{ payload.parse_confidence | default('unknown', true) | string | trim }}"
is_duplicate: >-
{% set existing = (states('input_text.water_softener_salt_recent_event_ids')
| default('', true) | string).split('|') %}
{{ event_id in existing }}
is_supported_item: "{{ item_key == 'water_softener_salt' }}"
is_add_action: "{{ action in ['add', 'top_off', 'refill'] }}"
effective_amount_lb: >-
{% if item_key == 'water_softener_salt' and action in ['add', 'top_off', 'refill'] %}
80
{% else %}
{{ amount_lb }}
{% endif %}
note_value: >-
{% set text = raw_text if raw_text else 'Logged by Joanna webhook.' %}
{{ text | truncate(255, true, '') }}
recent_event_line: "{{ occurred_display }}|{{ effective_amount_lb | round(1) }} lb|{{ note_value }}"
next_recent_events: >-
{% set current = (states('input_text.water_softener_salt_recent_events')
| default('', true) | string).split('||') %}
{% set ns = namespace(items=[recent_event_line]) %}
{% for raw in current %}
{% set value = raw | trim %}
{% if value and value not in ['unknown', 'unavailable', 'none'] and value != recent_event_line and (ns.items | count) < 10 %}
{% set ns.items = ns.items + [value] %}
{% endif %}
{% endfor %}
{{ ns.items | join('||') }}
next_recent_ids: >-
{% set current = (states('input_text.water_softener_salt_recent_event_ids')
| default('', true) | string).split('|') %}
{% set ns = namespace(items=[event_id]) %}
{% for raw in current %}
{% set value = raw | trim %}
{% if value and value not in ['unknown', 'unavailable', 'none'] and value != event_id and (ns.items | count) < 8 %}
{% set ns.items = ns.items + [value] %}
{% endif %}
{% endfor %}
{{ ns.items | join('|') }}
current_total_lb: "{{ states('input_number.water_softener_salt_total_added_lb') | float(0) }}"
next_total_lb: >-
{% if is_add_action %}
{{ (current_total_lb + effective_amount_lb) | round(2) }}
{% else %}
{{ current_total_lb | round(2) }}
{% endif %}
action:
- choose:
- conditions:
- condition: template
value_template: "{{ not is_supported_item }}"
sequence:
- service: script.send_to_logbook
data:
topic: MAINTENANCE
message: >-
Ignored unsupported maintenance item "{{ item_key }}" (event_id={{ event_id }}).
- conditions:
- condition: template
value_template: "{{ effective_amount_lb <= 0 }}"
sequence:
- service: script.send_to_logbook
data:
topic: MAINTENANCE
message: >-
Ignored maintenance payload with invalid amount (event_id={{ event_id }}, raw_amount={{ amount_value }} {{ unit }}).
- conditions:
- condition: template
value_template: "{{ is_duplicate }}"
sequence:
- service: script.send_to_logbook
data:
topic: MAINTENANCE
message: >-
Duplicate maintenance event ignored for softener salt (event_id={{ event_id }}).
default:
- service: input_number.set_value
data:
entity_id: input_number.water_softener_salt_last_amount_lb
value: "{{ effective_amount_lb }}"
- service: input_number.set_value
data:
entity_id: input_number.water_softener_salt_total_added_lb
value: "{{ next_total_lb }}"
- service: counter.increment
data:
entity_id: counter.water_softener_salt_event_count
- service: input_datetime.set_datetime
data:
entity_id: input_datetime.water_softener_salt_last_occurred_at
datetime: "{{ occurred_local_datetime }}"
- service: input_text.set_value
data:
entity_id: input_text.water_softener_salt_last_note
value: "{{ note_value }}"
- service: input_text.set_value
data:
entity_id: input_text.water_softener_salt_recent_event_ids
value: "{{ next_recent_ids | truncate(255, true, '') }}"
- service: input_text.set_value
data:
entity_id: input_text.water_softener_salt_recent_events
value: "{{ next_recent_events | truncate(255, true, '') }}"
- service: script.send_to_logbook
data:
topic: MAINTENANCE
message: >-
Softener salt logged: {{ effective_amount_lb | round(1) }} lb at {{ occurred_display }}.
total={{ next_total_lb | round(1) }} lb, count={{ states('counter.water_softener_salt_event_count') | int(0) + 1 }},
actor={{ actor }}, confidence={{ parse_confidence }}, event_id={{ event_id }},
raw="{{ raw_text | truncate(110, true, '...') }}".

@ -6,10 +6,10 @@
# Recorder Configuration - database retention and exclusions
# Stores HA history while purging noise and controlling DB size.
# -------------------------------------------------------------------
# Notes: Keeps 30 days; excludes vcloudinfo pings and other high-churn entities; MariaDB via recorder_db_url.
# Notes: Keeps 180 days (1/2 year); excludes vcloudinfo pings, noisy connectivity telemetry, and other high-churn entities; MariaDB via recorder_db_url.
######################################################################
db_url: !secret recorder_db_url
purge_keep_days: 30
purge_keep_days: 180
auto_purge: true
commit_interval: 30
exclude:
@ -47,7 +47,18 @@ exclude:
- sensor.*uptime*
- sensor.sun_next_*
- sensor.vpn_client_*
- sensor.*_linkquality
- sensor.*_link_quality
- sensor.*_lqi
- sensor.*_rssi
- sensor.*_signal
- sensor.*_signal_strength
- sensor.*_wi_fi_signal
- sensor.*_wifi_signal
- sensor.*_wifi_signal_strength
- sensor.*_temperature_state
- sensor.*_humidity_state
- sensor.*_last_seen*
- switch.*_do_not_disturb_*
- switch.*_repeat_switch
- input_text.l10s_vacuum_*

Loading…
Cancel
Save

Powered by TurnKey Linux.