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

601 lines
31 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_SYSTEM_PRESSURE_LOW, 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). "
"Re-checked 2026-10-03 @ core 2026.10.0b0: 'filter_hours' "
"(operatingHours) and 'filter_overdue_hours' (overdueHours) read the "
"same ventilation.filter.runtime as the countdown — one duty per "
"filter, not signed; 'compressor_hours_loadclass1'-'5', "
"'heating_rod_hours' and 'supply_fan_hours' are statistics, not "
"duties. No filter-reset button (button.py: one-time DHW charge "
"only)."
),
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; "
"re-verified 2026-09-30 after the coordinator refactor (21d1924): names unchanged"
),
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). Shared with
# bosch_homecom and nefiteasy (round 16).
HEATING_SYSTEM_PRESSURE_LOW,
),
),
# ─── 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. "
"Re-checked 2026-10-03 @ core 2026.10.0b0: every sensor and "
"binary sensor is registered TWICE, on the 'boiler' and on the "
"'thermostat' device (BOILER_/THERMOSTAT_DEVICE_DESCRIPTION, "
"identical translation_keys, neither device has a model string), "
"so no gate keeps a duty off the thermostat device — the "
"burner/pump running-time counters ('total_burner_hours', "
"'central_heating_pump_hours', 'hot_water_burner_hours', "
"'hot_water_pump_hours'; HOURS, TOTAL) are not signed for that "
"reason. 'service_required' is a problem-class binary (adoption "
"path)."
),
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 / 2026-09-27 (days key fixed) @ barleybobs/homeassistant-ecowater-softener master (HACS default)",
source=(
"HACS ecowater_softener (barleybobs) sensor.py: EcowaterSensor "
"has_entity_name, no translation_key, so the entity id comes from "
"the NAME: 'Salt Level Percentage' (PERCENTAGE) → suffix "
"_salt_level_percentage and 'Days Until Out of Salt' "
"(UnitOfTime.DAYS) → suffix _days_until_out_of_salt. (Until "
"2026-09-27 the catalog used the description key "
"'out_of_salt_days', which no entity id carries — the days duty "
"never matched; verified @ 6403e5c.)"
),
tasks=(
ConsumableSignature(("salt_level_percentage",), "Refill Softener Salt", "percent_left"),
ConsumableSignature(("days_until_out_of_salt",), "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 / 2026-09-27 (resets) @ Flo-Schilli/ha-grohe_smarthome main (HACS default)",
source=(
"HACS grohe_smarthome (owner now 'Flo-Schilli'), yaml-driven "
"name-derived entities (config/config.yaml, "
"GroheBlueHome/GroheBlueProf): 'Remaining Filter' (%) and "
"'Remaining CO2' (%). The sibling 'Remaining Filter (App)' slugs "
"to _remaining_filter_app and cannot clash with the exact "
"_remaining_filter suffix. The same yaml declares the buttons "
"'Reset Filter' (command.filter_status_reset) and 'Reset CO2' "
"(command.co2_status_reset) — has_entity_name, no "
"translation_key → suffixes _reset_filter / _reset_co2 (verified "
"@ 806abcd)."
),
tasks=(
ConsumableSignature(
("remaining_filter",),
"Replace Water Filter",
"percent_left",
resets=(("remaining_filter", "reset_filter"),),
),
ConsumableSignature(
("remaining_co2",),
"Replace CO2 Bottle",
"percent_left",
resets=(("remaining_co2", "reset_co2"),),
),
),
),
"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). Re-checked 2026-10-03 @ core "
"2026.10.0b0: the sensor is disabled by default (the suggestion "
"appears once it is enabled); 'total_runtime' (lifetime HOURS) and "
"'next_maintainance' (TIMESTAMP), both disabled by default too, "
"describe the same service — one duty, not signed twice."
),
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. 2026-09-27 @ core 2026.9: also tk "
"'salt_left_side_time_remaining' / 'salt_right_side_time_remaining' "
"(DURATION, DAYS) — the softener's own days-of-salt forecast, a "
"week's lead like the BWT/EcoWater days duties (adopting takes one "
"'Refill Softener Salt' task per object, whichever is ticked "
"first)."
),
tasks=(
ConsumableSignature(
("salt_left_side_percentage", "salt_right_side_percentage"),
"Refill Softener Salt",
"percent_left",
),
ConsumableSignature(
("salt_left_side_time_remaining", "salt_right_side_time_remaining"),
"Refill Softener Salt",
"duration_left",
below_hours=168,
),
),
),
# ─── Round 14 (2026-09-25): boiler pressure, softener salt, ─────────
# ─── generator engine hours ──────────────────────────────────────────
# (De Dietrich left again on 2026-09-30: core removed the integration
# from dev before any release, #183545 — it returns as a joint Remeha /
# De Dietrich Modbus integration.)
"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),),
),
# ─── Round 15 (2026-09-27): water-treatment cartridges and salt, ────
# ─── generator service countdown ─────────────────────────────────────
"drop_connect": IntegrationSignature(
name="DROP (water treatment)",
verified="2026-09-27 @ home-assistant/core 2026.9 + dev",
source=(
"core drop_connect (one config entry per DROP device, "
"DEVICE_SENSORS / DEVICE_BINARY_SENSORS by device type). RO filter "
"('ro'): sensor.py tk 'cart1'/'cart2'/'cart3' ('Cartridge N life "
"remaining', PERCENTAGE, MEASUREMENT, DIAGNOSTIC) — three "
"cartridges replaced one at a time → per-entity 'Replace Water "
"Filter'. Salt sensor ('salt'): binary_sensor.py tk 'salt' ('Salt "
"low', NO device class, so problem-sensor adoption does not see "
"it) → state latch on 'on', cleared by the refill. Skipped: the "
"softener's 'capacity_remaining' (GALLONS of softening capacity "
"until the next regeneration) / 'reserve_in_use' — the "
"regeneration cycle, operational, not salt."
),
tasks=(
ConsumableSignature(("cart1", "cart2", "cart3"), "Replace Water Filter", "percent_left", per_entity=True),
ConsumableSignature(
("salt",),
"Refill Softener Salt",
"event_present",
entity_domain="binary_sensor",
on_states=("on",),
),
),
),
"victron_gx": IntegrationSignature(
name="Victron GX (generator)",
verified="2026-09-27 @ home-assistant/core 2026.9 + dev, victron-mqtt 2026.8.4 + main",
source=(
"core victron_gx entity.py sets translation_key = the metric's "
"generic_short_id; victron_mqtt _victron_topics.py "
"'generator_service_counter' (N/…/generator/<id>/ServiceCounter, "
"'Service counter', DURATION, h; core strings.json 'Service "
"counter'). Venus OS dbus_generator startstop.py computes it as "
"(lastservicereset + serviceinterval) − accumulated runtime, i.e. "
"run-hours LEFT until the service the user configured (None while "
"no interval is set; negative when overdue) → duration_left, "
"task at 24 run-hours left. The counter reset "
"(ServiceCounterReset) is a library SERVICE topic, not an HA "
"button — nothing to wire. Re-checked 2026-10-03 @ core "
"2026.10.0b0: 'generator_total_runtime' (AccumulatedRuntime, "
"lifetime h) is the same service seen from the other side — not "
"signed twice."
),
tasks=(ConsumableSignature(("generator_service_counter",), "Oil Service", "duration_left"),),
),
# ─── Round 15 part 2 (2026-09-27): HACS heat pumps and stoves ────────
"stiebel_eltron_isg": IntegrationSignature(
name="Stiebel Eltron ISG (LWZ)",
verified="2026-09-27 @ pail23/stiebel_eltron_isg_component main (f47bcf8)",
source=(
"HACS stiebel_eltron_isg binary_sensor.py LWZ_BINARY_SENSOR_TYPES "
"(LWZ ventilation heat pumps only — WPM controllers get other "
"lists): tk 'filter' (operating_status bit 8), "
"'filter_extract_air' (bit 12) and 'filter_ventilation_air' (bit "
"13) — the controller's filter-change requests; plain binaries "
"with NO device class, so problem-sensor adoption does not see "
"them → one latch on 'on' over the three (one filter change "
"clears them together). The 'service' bit (6) has no documented "
"meaning and is left out. Every entity description sets a "
"translation_key."
),
translation_keys_authoritative=True,
tasks=(
ConsumableSignature(
("filter", "filter_extract_air", "filter_ventilation_air"),
"Replace Ventilation Filter",
"event_present",
entity_domain="binary_sensor",
on_states=("on",),
),
),
),
"aguaiot": IntegrationSignature(
name="Micronova Agua IOT (hydro stoves)",
verified="2026-09-27 @ vincentwolsink/home_assistant_micronova_agua_iot master (4d1883f)",
source=(
"HACS aguaiot const.py SENSORS (has_entity_name, name from the "
"description, no translation_key; created only when the stove "
"exposes the register): 'Water Pressure' (pres_h2o_get, BAR, "
"hydro stoves) → suffix _water_pressure. 'Service Hours' "
"(ore_service_get, h, TOTAL_INCREASING, hours since the last "
"service) is NOT signed: its limit sibling 'Threshold Service "
"Hours' also ends in _service_hours, and the suffix match cannot "
"exclude it (no translation_key to tell them apart)."
),
tasks=(HEATING_WATER_PRESSURE_LOW,),
),
# ─── Round 16 (2026-10-03): pellet-stove service by burn hours ──────
# (hr_energy_qube 'alarm_working_hours' is a problem-class binary →
# problem-sensor adoption.)
"ecoforest": IntegrationSignature(
name="Ecoforest pellet stoves",
verified="2026-10-03 @ home-assistant/core 2026.10.0b0 (sensor.py identical in 2026.9.0b0 and dev) + pyecoforest 0.4.0",
source=(
"core ecoforest sensor.py: tk 'working_hours' ('Working time', "
"DURATION, HOURS, no state class, entity_registry_enabled_default="
"False) = pyecoforest Device.working_hours, the stove's stats "
"field 'Nh' — the TOTAL working hours of the stove (HA docs: 'total "
"number of working hours of the device'), never reset → "
"usage_delta. Every 1,500 h — editorial: about one heating season "
"of a stove used as the main heating, i.e. the yearly 'Stove "
"Service' of the Fireplace & Wood Stove template counted in burn "
"hours. NOTE: disabled by default — the suggestion appears once the "
"user enables the sensor. The 'ignitions' counter and the 'alarm' "
"enum (pellets / air depression / CPU overheating) are not "
"maintenance duties."
),
tasks=(ConsumableSignature(("working_hours",), "Stove Service", "usage_delta", delta_units=1500),),
),
# ─── Round 16 HACS wave (2026-10-03): heating-loop pressure, the ─────
# ─── pellet-stove service countdown, a heat pump's vent filter ───────
# (Reviewed and left out: the sfstar 'victron' Modbus integration's
# generator_servicecounter — dbus-modbustcp returns 0 for an invalid
# value, so a GX without a service interval would read "due now".)
"ariston": IntegrationSignature(
name="Ariston NET (Remotethermo)",
verified="2026-10-03 @ fustom/ariston-remotethermo-home-assistant-v3 main (31900cb)",
source=(
"HACS ariston const.py ARISTON_SENSOR_TYPES "
"DeviceProperties.HEATING_CIRCUIT_PRESSURE: name f'{NAME} heating "
"circuit pressure' with NAME 'Ariston' and no has_entity_name / "
"translation_key → sensor.ariston_heating_circuit_pressure, suffix "
"_heating_circuit_pressure (the original name also matches a "
"second boiler's _2 id); PRESSURE, MEASUREMENT, DIAGNOSTIC, "
"enabled, GALEVO systems only. Value and unit are the cloud item's "
"own (ariston library galevo_device.heating_circuit_pressure_value"
" / _unit; HeatingCircuitPressure is in bar) → value_below 1 like "
"the other boiler-loop duties. Core 'ariston' is only a virtual "
"brand entry (supported_by midea) without entities."
),
tasks=(ConsumableSignature(("heating_circuit_pressure",), "Refill Heating Water", "value_below", delta_units=1),),
),
"aquarea": IntegrationSignature(
name="Panasonic Aquarea (HeishaMon)",
verified="2026-10-03 @ kamaradclimber/heishamon-homeassistant main (3a528fd)",
source=(
"HACS aquarea (HeishaMon, MQTT-fed) definitions.py build_sensors "
"TOP115 key f'{mqtt_prefix}main/Water_Pressure', name 'Aquarea "
"Water Pressure', PRESSURE, 'bar', entity_registry_enabled_default="
"False (K/L series only); sensor.py sets entity_id = "
"sensor.<slugify(key)> → sensor.panasonic_heat_pump_main_water_"
"pressure (suffix _water_pressure; the original name ends in it "
"too). No other HeishaMon key ends in water_pressure (High/Low "
"Pressure are the refrigerant side). NOTE: disabled by default — "
"the suggestion appears once the user enables the sensor. The "
"cloud fork wpatrik14/home-assistant-aquarea shares the domain but "
"has no pressure entity (verified @ a588223)."
),
tasks=(HEATING_WATER_PRESSURE_LOW,),
),
"maestro_mcz": IntegrationSignature(
name="MCZ pellet stoves (Maestro)",
verified="2026-10-03 @ Robbe-B/maestro_mcz main (a2ba9cf)",
source=(
"HACS maestro_mcz maestro/models/models.py supported_sensors: "
"SensorMczConfigItem 'Next Maintenance' (status field "
"'ore_prox_manut' = hours to the next maintenance, UnitOfTime.HOURS, "
"MEASUREMENT, DIAGNOSTIC, enabled; created only when the stove "
"reports the field). sensor.py MczSensorEntity has_entity_name with "
"_attr_name = the item name, no translation_key → suffix "
"_next_maintenance. The stove controller's own service countdown "
"(the fumis pattern) → duration_left 24 h; named after the "
"technician's 'Stove Service' of the Fireplace & Wood Stove "
"template, like the ecoforest duty. The only binary ('Alarm', "
"is_in_error) is problem-class."
),
tasks=(ConsumableSignature(("next_maintenance",), "Stove Service", "duration_left"),),
),
"bosch_homecom": IntegrationSignature(
name="Bosch HomeCom Easy",
verified="2026-10-03 @ serbanb11/bosch-homecom-hass main (d9c28a6)",
source=(
"HACS bosch_homecom sensor.py: K40/ICOM coordinators get "
"BoschComK40ExtraSensor('systemPressure', translation_key "
"'system_pressure', PRESSURE, 'bar') when the heat source reports "
"it (strings.json 'System pressure', has_entity_name). ICOM "
"devices additionally get BoschComIcomExtraSensor name "
"'hs_system_pressure' (no translation_key, bar) reading the same "
"heat_sources.systemPressure — its id ends in _system_pressure too, "
"so the duty watches both copies of one reading (any-low). "
"value_below 1 bar → the shared bosch duty."
),
tasks=(HEATING_SYSTEM_PRESSURE_LOW,),
),
"nefiteasy": IntegrationSignature(
name="Nefit Easy (Bosch thermostat)",
verified="2026-10-03 @ ksya/ha-nefiteasy dev (28880e4)",
source=(
"HACS nefiteasy const.py SENSORS: key 'system_pressure', name "
"'System pressure', url /system/appliance/systemPressure, "
"UnitOfPressure.BAR, PRESSURE, MEASUREMENT; nefit_entity.py sets "
"neither has_entity_name nor translation_key → "
"sensor.system_pressure (exact-object-id pattern; a second boiler's "
"_2 id is matched by the original name). value_below 1 bar → the "
"shared bosch duty."
),
tasks=(HEATING_SYSTEM_PRESSURE_LOW,),
),
"waterkotte_heatpump": IntegrationSignature(
name="Waterkotte heat pumps (BasicVent)",
verified="2026-10-03 @ marq24/ha-waterkotte main (f5491c9)",
source=(
"HACS waterkotte_heatpump const.py "
"BASICVENT_FILTER_CHANGE_REMAINING_OPERATING_DAYS_A4504 (DURATION, "
"UnitOfTime.DAYS, MEASUREMENT, vent feature only, "
"entity_registry_enabled_default=False); __init__.py sets "
"translation_key = key.lower() → tk "
"'basicvent_filter_change_remaining_operating_days_a4504' (en.json "
"'Vent Air-Filter-Change operating hours remaining time') — the "
"BasicVent ventilation unit's own filter countdown → duration_left "
"7 days. NOTE: disabled by default — the suggestion appears once "
"the user enables it. The counter reset "
"(BASICVENT_FILTER_CHANGE_OPERATING_HOURS_RESET_D1544) is a SWITCH, "
"not a button, and cannot be wired; the 'filter change display' "
"binary carries device_class running and is not signed."
),
tasks=(
ConsumableSignature(
("basicvent_filter_change_remaining_operating_days_a4504",),
"Replace Ventilation Filter",
"duration_left",
below_hours=168,
),
),
),
}