152 lines
7.4 KiB
Python
152 lines
7.4 KiB
Python
"""Protocol/hub transports whose duties are entity-domain-gated.
|
|
|
|
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 (
|
|
LOCK_CYLINDER_CYCLES,
|
|
MOWER_BLADES_RUNTIME,
|
|
MOWER_UNDERCARRIAGE_RUNTIME,
|
|
VACUUM_FILTER_CLEANING_RUNTIME,
|
|
VACUUM_MAIN_BRUSH_RUNTIME,
|
|
)
|
|
|
|
SIGNATURES: dict[str, IntegrationSignature] = {
|
|
"matter": IntegrationSignature(
|
|
name="Matter",
|
|
verified="2026-07-18 (lock) / 2026-09-27 (filters, vacuum) @ home-assistant/core 2026.9 + dev",
|
|
source=(
|
|
"home-assistant/core homeassistant/components/matter/lock.py "
|
|
"(MatterLock, lock domain entity per device). Matter bridges many "
|
|
"device types — the lock entity_domain restricts this signature "
|
|
"to locks; every transition to 'locked' is one mechanical cycle. "
|
|
"sensor.py: tk 'hepa_filter_condition' (HepaFilterMonitoring."
|
|
"Condition) and 'activated_carbon_filter_condition' "
|
|
"(ActivatedCarbonFilterMonitoring.Condition), PERCENTAGE, "
|
|
"MEASUREMENT, enabled — air purifiers and extractor hoods. Read "
|
|
"as % REMAINING: the Matter SDK's ResetCondition sets "
|
|
"100 for DegradationDirection 'down' (the SDK air-purifier example "
|
|
"and core's mock_air_purifier / mock_extractor_hood fixtures: "
|
|
"Condition 100, direction down); HA does not invert 'up' devices. "
|
|
"The two filters wear independently → two duties. button.py has "
|
|
"one reset per filter, but BOTH carry tk 'reset_filter_condition' "
|
|
"(only the unique_id tells HepaFilterMonitoringResetButton from "
|
|
"ActivatedCarbonFilterMonitoringResetButton). Wired as each duty's "
|
|
"reset: the lookup presses a button only when exactly ONE matches "
|
|
"the key on the device, so a single-filter purifier or hood gets "
|
|
"its reset and a dual-filter device gets none (a guess could "
|
|
"reset the wrong filter). vacuum.py: not docked/returning/paused/"
|
|
"error and an RVC run mode tagged Cleaning (or Mapping) → "
|
|
"VacuumActivity.CLEANING; core's RVC fixtures "
|
|
"(mock_vacuum_cleaner, eufy_vacuum_omni_e28) carry no "
|
|
"filter-monitoring cluster, so the ENGINE accumulates cleaning "
|
|
"time."
|
|
),
|
|
tasks=(
|
|
LOCK_CYLINDER_CYCLES,
|
|
ConsumableSignature(
|
|
("hepa_filter_condition",),
|
|
"Replace Filter",
|
|
"percent_left",
|
|
resets=(("hepa_filter_condition", "reset_filter_condition"),),
|
|
),
|
|
ConsumableSignature(
|
|
("activated_carbon_filter_condition",),
|
|
"Replace Activated Carbon",
|
|
"percent_left",
|
|
resets=(("activated_carbon_filter_condition", "reset_filter_condition"),),
|
|
),
|
|
VACUUM_FILTER_CLEANING_RUNTIME,
|
|
VACUUM_MAIN_BRUSH_RUNTIME,
|
|
),
|
|
),
|
|
"zwave_js": IntegrationSignature(
|
|
name="Z-Wave lock",
|
|
verified="2026-07-18 @ home-assistant/core dev",
|
|
source=(
|
|
"home-assistant/core homeassistant/components/zwave_js/lock.py "
|
|
"(lock platform verified present). Locks carry no wear sensor — "
|
|
"the ENGINE counts locking cycles; entity_domain-gated to locks, so the bridge's other device types are untouched."
|
|
),
|
|
tasks=(
|
|
LOCK_CYLINDER_CYCLES,
|
|
),
|
|
),
|
|
"zha": IntegrationSignature(
|
|
name="Zigbee (ZHA)",
|
|
verified="2026-07-18 (lock) / 2026-09-27 (STARKVIND filter) @ home-assistant/core 2026.9 + dev, zigpy/zha 2.2.0 + dev",
|
|
source=(
|
|
"home-assistant/core homeassistant/components/zha/lock.py "
|
|
"(lock platform verified present). Locks carry no wear sensor — "
|
|
"the ENGINE counts locking cycles; entity_domain-gated to locks, so the bridge's other device types are untouched. "
|
|
"IKEA STARKVIND purifiers: zha library application/platforms/"
|
|
"sensor IkeaFilterRunTime — tk 'filter_run_time' (HA "
|
|
"zha/strings.json 'Filter run time'), DURATION, MINUTES, "
|
|
"DIAGNOSTIC, 'run time of the current filter' (IKEA cluster "
|
|
"0xFC7D attribute 0x0000; counts UP and restarts at 0 when the "
|
|
"filter is reset on the purifier) → usage_above at 4,320 h = the "
|
|
"cluster's default filter_life_time of 259,200 min (the "
|
|
"DIRIGERA/STARKVIND duty). The 'replace_filter' binary is "
|
|
"device_class problem (adoption path); no reset button."
|
|
),
|
|
tasks=(
|
|
LOCK_CYLINDER_CYCLES,
|
|
ConsumableSignature(("filter_run_time",), "Replace Filter", "usage_above", above_hours=4320),
|
|
),
|
|
),
|
|
"mqtt": IntegrationSignature(
|
|
name="MQTT lock (Zigbee2MQTT etc.)",
|
|
verified="2026-07-18 @ home-assistant/core dev",
|
|
source=(
|
|
"home-assistant/core homeassistant/components/mqtt/lock.py "
|
|
"(lock platform verified present). Locks carry no wear sensor — "
|
|
"the ENGINE counts locking cycles; entity_domain-gated to locks, so the bridge's other device types are untouched."
|
|
),
|
|
tasks=(
|
|
LOCK_CYLINDER_CYCLES,
|
|
VACUUM_FILTER_CLEANING_RUNTIME,
|
|
VACUUM_MAIN_BRUSH_RUNTIME,
|
|
MOWER_BLADES_RUNTIME,
|
|
MOWER_UNDERCARRIAGE_RUNTIME,
|
|
),
|
|
),
|
|
# MQTT vacuums (Valetudo!) and mowers (OpenMower) expose only
|
|
# state entities — engine-accumulated usage covers their duties.
|
|
"homekit_controller": IntegrationSignature(
|
|
name="HomeKit Device",
|
|
verified="2026-07-18 (lock) / 2026-09-27 (filter) @ home-assistant/core 2026.9 + dev",
|
|
source=(
|
|
"home-assistant/core homeassistant/components/homekit_controller/lock.py "
|
|
"(lock platform verified present). Locks carry no wear sensor — "
|
|
"the ENGINE counts locking cycles; entity_domain-gated to locks, so the bridge's other device types are untouched. "
|
|
"sensor.py SIMPLE_SENSOR CharacteristicsTypes.FILTER_LIFE_LEVEL: "
|
|
"name 'Filter lifetime', PERCENTAGE, MEASUREMENT, no "
|
|
"translation_key — SimpleSensor names it '<accessory> Filter "
|
|
"lifetime' → suffix _filter_lifetime. HAP Filter Life Level is "
|
|
"the REMAINING life (core's own homekit bridge, type_air_purifiers"
|
|
".py, raises Filter Change Indication below 10 %). No reset "
|
|
"entity (Reset Filter Indication is not exposed)."
|
|
),
|
|
tasks=(
|
|
LOCK_CYLINDER_CYCLES,
|
|
ConsumableSignature(("filter_lifetime",), "Replace Filter", "percent_left"),
|
|
),
|
|
),
|
|
"deconz": IntegrationSignature(
|
|
name="deCONZ (Zigbee) lock",
|
|
verified="2026-07-18 @ home-assistant/core dev",
|
|
source=(
|
|
"home-assistant/core homeassistant/components/deconz/lock.py "
|
|
"(lock platform verified present) — engine-counted locking cycles, entity_domain-gated so the bridge's other device types are untouched."
|
|
),
|
|
tasks=(
|
|
LOCK_CYLINDER_CYCLES,
|
|
),
|
|
),
|
|
}
|