Files
HomeAssistantVS/custom_components/maintenance_supporter/helpers/signatures/heating.py
T

322 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Boilers, heating & water treatment.
Data module of the suggested-setups signature catalog — see
``helpers/signatures/_model.py`` for the direction semantics and the
method contract (every entry cites and is verified against the
integration's source; drift-probed weekly)."""
from __future__ import annotations
from ._model import ConsumableSignature, IntegrationSignature
from ._shared import HEATING_WATER_PRESSURE_LOW, SOFTENER_SALT_LEVEL
SIGNATURES: dict[str, IntegrationSignature] = {
"vicare": IntegrationSignature(
name="Viessmann ViCare",
verified="2026-07-17 (filter) / 2026-07-18 (burner) @ home-assistant/core dev + openviess/PyViCare master",
source=(
"home-assistant/core homeassistant/components/vicare/sensor.py "
"(GLOBAL_SENSORS translation_key 'filter_remaining_hours', UnitOfTime.HOURS, "
"disabled-by-default; PyViCare ventilation.filter.runtime.remainingHours; "
"BURNER_SENSORS/COMPRESSOR_SENSORS 'burner_hours'/'compressor_hours', "
"UnitOfTime.HOURS, TOTAL_INCREASING lifetime → usage_delta)."
),
tasks=(
ConsumableSignature(("filter_remaining_hours",), "Replace Filter", "duration_left"),
# Boiler/heat-pump service by accumulated operating hours since the
# last service — the counters are lifetime (no reset), which is
# exactly what the delta-baseline trigger models.
ConsumableSignature(
("burner_hours", "compressor_hours"),
"Annual Inspection",
"usage_delta",
delta_units=2000,
),
),
),
"bosch": IntegrationSignature(
name="Bosch/Buderus heating",
verified="2026-07-18 @ bosch-thermostat/home-assistant-bosch-custom-component master + live RC300 registry",
source=(
"bosch-thermostat custom component: sensors are DYNAMIC (named "
"from the device's XMPP data, sensor/base.py builds names without "
"a device prefix → entity ids like sensor.system_pressure; no "
"translation_keys). Key verified against a live Buderus RC300 "
"registry; matched via the exact-object-id pattern."
),
tasks=(
# Heating-loop pressure: refill water when it drops below 1 bar;
# topping up raises the value back (auto-resolve).
ConsumableSignature(("system_pressure",), "Refill Heating Water", "value_below", delta_units=1),
),
),
# ─── Research round 4 (2026-07-19): boiler pressure, HRV filters, ───
# ─── purifiers, espresso, pet tech, Klipper ─────────────────────────
"opentherm_gw": IntegrationSignature(
name="OpenTherm Gateway",
verified="2026-07-19 @ core/dev opentherm_gw/sensor.py",
source=(
"core opentherm_gw: tk 'central_heating_pressure', BAR, MEASUREMENT — generic for EVERY OpenTherm-connected boiler."
),
tasks=(ConsumableSignature(("central_heating_pressure",), "Refill Heating Water", "value_below", delta_units=1),),
),
"plugwise": IntegrationSignature(
name="Plugwise (Anna/Adam)",
verified="2026-07-19 @ core/dev plugwise/sensor.py",
source="core plugwise: tk 'water_pressure', BAR, MEASUREMENT (boiler loop).",
tasks=(HEATING_WATER_PRESSURE_LOW,),
),
"incomfort": IntegrationSignature(
name="Intergas InComfort",
verified="2026-07-19 @ core/dev incomfort/sensor.py",
source=(
"core incomfort: key 'cv_pressure', BAR, MEASUREMENT. NOTE: "
"entity_registry_enabled_default=False — the suggestion appears "
"once the user enables the sensor."
),
tasks=(ConsumableSignature(("cv_pressure",), "Refill Heating Water", "value_below", delta_units=1),),
),
"atag": IntegrationSignature(
name="ATAG One",
verified="2026-07-19 @ core/dev atag/sensor.py",
source=(
"core atag: legacy name-based sensors ('CH Water Pressure' → "
"object id ch_water_pressure), BAR — matched via suffix or the "
"exact-object-id pattern."
),
tasks=(ConsumableSignature(("ch_water_pressure",), "Refill Heating Water", "value_below", delta_units=1),),
),
"bwt_perla": IntegrationSignature(
name="BWT Perla",
verified="2026-07-19 @ dkarv/ha-bwt-perla main sensor.py (HACS default)",
source=(
"HACS bwt_perla (dkarv): tk 'regenerativ_level' (salt reserve, "
"PERCENTAGE) and tk 'regenerativ_days' (days of salt left, "
"UnitOfTime.DAYS) — refilling raises both (auto-resolve)."
),
tasks=(
ConsumableSignature(("regenerativ_level",), "Refill Softener Salt", "percent_left"),
ConsumableSignature(("regenerativ_days",), "Refill Softener Salt", "duration_left", below_hours=168),
),
),
"ecowater_softener": IntegrationSignature(
name="EcoWater softener",
verified="2026-07-19 @ barleybobs/homeassistant-ecowater-softener master (HACS default)",
source=(
"HACS ecowater_softener (barleybobs): key 'salt_level_percentage' "
"(PERCENTAGE) and key 'out_of_salt_days' (days) — name-style "
"entities, suffix-matched."
),
tasks=(
ConsumableSignature(("salt_level_percentage",), "Refill Softener Salt", "percent_left"),
ConsumableSignature(("out_of_salt_days",), "Refill Softener Salt", "duration_left", below_hours=168),
),
),
"wolflink": IntegrationSignature(
name="Wolf SmartSet",
verified="2026-07-19 @ core/dev wolflink/sensor.py",
source="core wolflink: key 'pressure', BAR (heating loop).",
tasks=(ConsumableSignature(("pressure",), "Refill Heating Water", "value_below", delta_units=1),),
),
"palazzetti": IntegrationSignature(
name="Palazzetti pellet stove",
verified="2026-07-19 @ core/dev palazzetti/sensor.py",
source=(
"core palazzetti: tk 'pellet_quantity' (KILOGRAMS consumed, "
"cumulative) -> usage_delta; ash-pan cadence ~100 kg of pellets "
"(editorial: roughly weekly in season; manuals prescribe "
"calendar-based cleaning). 'pellet_level' is a CM tank gauge — "
"inventory, not wear; skipped."
),
tasks=(ConsumableSignature(("pellet_quantity",), "Empty Ash Pan", "usage_delta", delta_units=100),),
),
"mypyllant": IntegrationSignature(
name="Vaillant (myVAILLANT)",
verified="2026-07-19 @ signalkraft/mypyllant-component main sensor.py",
source=(
"HACS mypyllant: SystemWaterPressureSensor (name '... System "
"Water Pressure' -> suffix system_water_pressure) and the "
"device-level operational-data variant (suffix water_pressure), "
"both BAR — matched any-low."
),
tasks=(
ConsumableSignature(
("system_water_pressure", "water_pressure"),
"Refill Heating Water",
"value_below",
delta_units=1,
),
),
),
"grohe_smarthome": IntegrationSignature(
name="Grohe Blue",
verified="2026-07-19 @ flo-schilli/ha-grohe_smarthome main (HACS default)",
source=(
"HACS grohe_smarthome, yaml-driven name-derived entities "
"(config/config.yaml, GroheBlueHome/GroheBlueProf): 'Remaining "
"Filter' (%) and 'Remaining CO2' (%) — reset by the device's own "
"filter/CO2 reset commands. The sibling 'Remaining Filter (App)' "
"slugs to _remaining_filter_app and cannot clash with the exact "
"_remaining_filter suffix."
),
tasks=(
ConsumableSignature(("remaining_filter",), "Replace Water Filter", "percent_left"),
ConsumableSignature(("remaining_co2",), "Replace CO2 Bottle", "percent_left"),
),
),
"iqua_softener": IntegrationSignature(
name="iQua softener",
verified="2026-07-20 @ mutilator/homeassistant-iqua-softener master sensor.py (HACS default)",
source=(
"HACS iqua_softener: 'Salt level' (PERCENTAGE, name-style -> "
"suffix _salt_level). 'Out of salt estimated day' is a DATE "
"sensor - parked for the date direction."
),
tasks=(SOFTENER_SALT_LEVEL,),
),
"fumis": IntegrationSignature(
name="Fumis (pellet stoves)",
verified="2026-07-20 @ home-assistant/core dev",
source=(
"core fumis: tk 'time_to_service' (DURATION, HOURS remaining) — "
"the controller's own service countdown for Fumis-driven pellet "
"stoves/boilers."
),
tasks=(ConsumableSignature(("time_to_service",), "Annual Service", "duration_left"),),
),
"rehlko": IntegrationSignature(
name="Rehlko / Kohler generators",
verified="2026-07-20 @ home-assistant/core dev",
source=(
"core rehlko: tk 'runtime_since_last_maintenance' (HOURS since "
"the last maintenance, resets when maintenance is recorded) → "
"usage_above at 100 h — Kohler's oil-change interval (every "
"100 run-hours or annually). An 'oil_pressure' problem binary "
"also exists (adoption path)."
),
tasks=(ConsumableSignature(("runtime_since_last_maintenance",), "Oil Service", "usage_above", above_hours=100),),
),
"aquacell": IntegrationSignature(
name="AquaCell softener",
verified="2026-07-20 @ home-assistant/core dev",
source=(
"core aquacell: tk 'salt_left_side_percentage' and "
"'salt_right_side_percentage' (PERCENTAGE) — dual salt tanks, "
"matched any-low."
),
tasks=(
ConsumableSignature(
("salt_left_side_percentage", "salt_right_side_percentage"),
"Refill Softener Salt",
"percent_left",
),
),
),
# ─── Round 14 (2026-09-25): boiler pressure, softener salt, ─────────
# ─── generator engine hours ──────────────────────────────────────────
"de_dietrich": IntegrationSignature(
name="De Dietrich (Diematic)",
verified="2026-09-25 @ home-assistant/core dev",
source=(
"core de_dietrich (new on dev = 2026.10, Diematic Modbus): tk "
"'water_pressure', UnitOfPressure.BAR, MEASUREMENT (boiler loop)."
),
tasks=(HEATING_WATER_PRESSURE_LOW,),
),
"remeha_home": IntegrationSignature(
name="Remeha Home",
verified="2026-09-25 @ msvisser/remeha_home main",
source=(
"HACS remeha_home const.py APPLIANCE_SENSOR_TYPES: key "
"'waterPressure', name 'Water Pressure' (BAR, MEASUREMENT; "
"has_entity_name without translation_key → suffix "
"_water_pressure)."
),
tasks=(HEATING_WATER_PRESSURE_LOW,),
),
"syr_connect": IntegrationSignature(
name="SYR Connect (softeners)",
verified="2026-09-25 @ alexhass/syr_connect main",
source=(
"HACS syr_connect sensor.py sets _attr_translation_key = "
"sensor_key.lower() → tk 'getss1' ('Salt container stock 1'; "
"const.py: getSS1 = salt supply of container 1 in "
"UnitOfTime.WEEKS, MEASUREMENT, no device class). Weeks are not a "
"unit the duration conversion knows, so the duty is a "
"value_below in the entity's own unit: below 2 weeks (= 336 h). "
"getSS2/getSS3 (extra containers, disabled by default, absent on "
"most devices) are left out."
),
tasks=(ConsumableSignature(("getss1",), "Refill Softener Salt", "value_below", delta_units=2),),
),
"salt_sentry": IntegrationSignature(
name="Salt Sentry",
verified="2026-09-25 @ Lemcke-solutions/Salt-sentry-ha-integration main",
source=(
"HACS salt_sentry sensor.py SaltPercentageSensor: tk "
"'salt_level', '%' = (empty − distance) / (empty − full) × 100 — "
"the salt REMAINING in the brine tank (ultrasonic level sensor)."
),
tasks=(SOFTENER_SALT_LEVEL,),
),
"unique_waterontharder": IntegrationSignature(
name="Unique Waterontharder",
verified="2026-09-25 @ mirkin-pixel/ha-unique-waterontharders main",
source=(
"HACS unique_waterontharder sensor.py: tk 'salt_level', "
"PERCENTAGE, MEASUREMENT — the cloud API's 'zout_niveau' (salt "
"level)."
),
tasks=(SOFTENER_SALT_LEVEL,),
),
"bwt_aqa_perla_ble": IntegrationSignature(
name="BWT AQA Perla (BLE)",
verified="2026-09-25 @ Micka41/bwt-aqa-perla-ble main",
source=(
"HACS bwt_aqa_perla_ble sensor.py: tk 'salt_pct', PERCENTAGE, "
"MEASUREMENT — coordinator.py decodes it as remaining salt × 100 "
"// tank capacity ('qte_sel_restant'). A 'salt_alarm' problem "
"binary also exists (adoption path)."
),
tasks=(ConsumableSignature(("salt_pct",), "Refill Softener Salt", "percent_left"),),
),
"generac": IntegrationSignature(
name="Generac (Mobile Link)",
verified="2026-09-25 @ binarydev/ha-generac main",
source=(
"HACS generac sensor.py RunTimeSensor: name sensor_name(self, "
"'run_time') = 'generac_<device_id>_run_time' → suffix _run_time, "
"DURATION, 'h'; value = apparatus property type 71, which the "
"Mobile Link API labels 'Engine Hours' (payload quoted in issue "
"#202) — the LIFETIME engine-hours counter → usage_delta every "
"200 h (Generac air-cooled home-standby schedule: oil and filter "
"every 200 h or 2 years). The pjordanandrsn fork shares the "
"domain and the same property-71 sensor."
),
tasks=(ConsumableSignature(("run_time",), "Oil Service", "usage_delta", delta_units=200),),
),
"energytrak": IntegrationSignature(
name="EnergyTrak (generators)",
verified="2026-09-25 @ brentb2529/ha-energytrak main",
source=(
"HACS energytrak sensor.py: tk 'engine_hours' (DURATION, HOURS, "
"TOTAL_INCREASING; normalize.py: 'a monotonic counter that is "
"always > 0 on an installed unit') — LIFETIME → usage_delta every "
"200 h (standby-generator oil cadence, as for Generac)."
),
tasks=(ConsumableSignature(("engine_hours",), "Oil Service", "usage_delta", delta_units=200),),
),
"himoinsa_c4lan": IntegrationSignature(
name="Himoinsa C4LAN generators",
verified="2026-09-25 @ spiri439/himoinsa-c4lan main",
source=(
"HACS himoinsa_c4lan sensor.py: key 'engine_hours', name 'Engine "
"hours' (Modbus input register 42 = total engine hours per "
"const.py; HOURS, DURATION, TOTAL_INCREASING; has_entity_name "
"without translation_key → suffix _engine_hours) — LIFETIME → "
"usage_delta every 250 h (typical diesel-genset oil interval)."
),
tasks=(ConsumableSignature(("engine_hours",), "Oil Service", "usage_delta", delta_units=250),),
),
}