393 files
This commit is contained in:
1 parent
b05b7a897e
commit
39d97ac2db
404 files changed
+54006
-11034
No files matched your search
@@ -12,17 +12,48 @@ integration's source; drift-probed weekly)."""
|
||||
from __future__ import annotations
|
||||
|
||||
from ._model import ConsumableSignature, IntegrationSignature
|
||||
from ._shared import (
|
||||
FILTER_LIFE_PERCENT,
|
||||
HOOD_GREASE_FILTER_USAGE,
|
||||
SIDE_BRUSH_LIFE_PERCENT,
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
)
|
||||
|
||||
SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"roborock": IntegrationSignature(
|
||||
name="Roborock",
|
||||
verified="2026-07-16 @ home-assistant/core dev",
|
||||
source="home-assistant/core homeassistant/components/roborock/sensor.py (translation_key, duration s→h)",
|
||||
verified="2026-09-25 @ home-assistant/core dev + Python-roborock/python-roborock main",
|
||||
source=(
|
||||
"home-assistant/core homeassistant/components/roborock/sensor.py (translation_key, "
|
||||
"duration s→h). 2026-09 round: dock tks 'strainer_time_left' / "
|
||||
"'cleaning_brush_time_left' (HOURS; python-roborock v1_containers: "
|
||||
"STRAINER_REPLACE_TIME 150 / CLEANING_BRUSH_REPLACE_TIME 300 minus work "
|
||||
"count — countdowns to replacement, HA docs: 'replace your dock's "
|
||||
"strainer/maintenance brush'); Q7 (B01) tk 'mop_life_time_left' (MINUTES, "
|
||||
"b01_q7_containers: max(0, 10800 - mop_life) = remaining); Dyad tk "
|
||||
"'brush_remaining' ('Roller left', SECONDS, DyadDataProtocol.BRUSH_LEFT) joins "
|
||||
"the main-brush duty; Zeo washer tk 'times_after_clean' (unitless "
|
||||
"RoborockZeoProtocol.TIMES_AFTER_CLEAN, washes since the last drum clean — "
|
||||
"usage_above like LG's tub_clean_counter). Q10 tks main_brush_life/"
|
||||
"side_brush_life/filter_life/sensor_life are SKIPPED: HA names them 'time "
|
||||
"used' while python-roborock's Q10Consumable calls them remaining life."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(("main_brush_time_left",), "Replace Main Brush", "duration_left"),
|
||||
# Dyad wet-dry vacuums report their roller brush as 'brush_remaining'
|
||||
# — same duty, same direction → one signature (per-device dedupe).
|
||||
ConsumableSignature(("main_brush_time_left", "brush_remaining"), "Replace Main Brush", "duration_left"),
|
||||
ConsumableSignature(("side_brush_time_left",), "Replace Side Brush", "duration_left"),
|
||||
ConsumableSignature(("filter_time_left",), "Replace Filter", "duration_left"),
|
||||
ConsumableSignature(("sensor_time_left",), "Clean Sensors", "duration_left"),
|
||||
ConsumableSignature(("mop_life_time_left",), "Replace Mop Pads", "duration_left"),
|
||||
# Dock consumables: the 'hours' are the dock's wash-count budget
|
||||
# (150 / 300); 24 left ≈ the last 8-16 % of the part's life.
|
||||
ConsumableSignature(("strainer_time_left",), "Replace Dock Strainer", "duration_left"),
|
||||
ConsumableSignature(("cleaning_brush_time_left",), "Replace Maintenance Brush", "duration_left"),
|
||||
# Zeo washer: washes since the last drum-clean program (unitless;
|
||||
# above_hours is the wash count, ~monthly like LG's tub counter).
|
||||
ConsumableSignature(("times_after_clean",), "Clean Tub", "usage_above", above_hours=30),
|
||||
),
|
||||
),
|
||||
"xiaomi_miio": IntegrationSignature(
|
||||
@@ -61,20 +92,42 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
),
|
||||
"ecovacs": IntegrationSignature(
|
||||
name="Ecovacs",
|
||||
verified="2026-07-17 @ home-assistant/core dev + DeebotUniverse/client.py main",
|
||||
verified="2026-09-25 @ home-assistant/core dev + DeebotUniverse/client.py main",
|
||||
source=(
|
||||
"home-assistant/core homeassistant/components/ecovacs/sensor.py "
|
||||
"(translation_key f'lifespan_{component.name.lower()}', PERCENTAGE) + "
|
||||
"DeebotUniverse/client.py deebot_client/events LifeSpan enum members"
|
||||
"(translation_key f'lifespan_{component.name.lower()}' over const.py "
|
||||
"SUPPORTED_LIFESPANS, PERCENTAGE; LEGACY_LIFESPAN_SENSORS "
|
||||
"f'lifespan_{component}' for main_brush/side_brush/filter) + "
|
||||
"DeebotUniverse/client.py deebot_client/events LifeSpan enum members "
|
||||
"(LifeSpanEvent.percent = remaining). 2026.8 added cleaning_solution, "
|
||||
"sewage_box (the dirty-water box), water_sink (the station's cleaning "
|
||||
"sink), trimmer_brush and weed_rope (GOAT edge trimmer). "
|
||||
"total_stats_time_mower = the mower override of total_stats_time "
|
||||
"(SECONDS, suggested h, TOTAL_INCREASING lifetime). unit_care is "
|
||||
"SKIPPED (which parts it covers is not established from source)."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(("lifespan_brush",), "Replace Main Brush", "percent_left"),
|
||||
ConsumableSignature(("lifespan_brush", "lifespan_main_brush"), "Replace Main Brush", "percent_left"),
|
||||
ConsumableSignature(("lifespan_side_brush",), "Replace Side Brush", "percent_left"),
|
||||
ConsumableSignature(("lifespan_filter",), "Replace Filter", "percent_left"),
|
||||
# The robot's filter and the handheld unit's filter (combo models)
|
||||
# are separate parts — one task per entity when a device has both.
|
||||
ConsumableSignature(("lifespan_filter", "lifespan_hand_filter"), "Replace Filter", "percent_left", per_entity=True),
|
||||
ConsumableSignature(("lifespan_station_filter",), "Replace Secondary Filter", "percent_left"),
|
||||
ConsumableSignature(("lifespan_dust_bag",), "Replace Dust Bag", "percent_left"),
|
||||
ConsumableSignature(("lifespan_round_mop",), "Replace Mop Pads", "percent_left"),
|
||||
# GOAT robotic mowers report blade lifespan through the same platform.
|
||||
ConsumableSignature(("lifespan_cleaning_solution",), "Refill Detergent", "percent_left"),
|
||||
ConsumableSignature(("lifespan_sewage_box",), "Empty Dirty Water Tank", "percent_left"),
|
||||
ConsumableSignature(("lifespan_water_sink",), "Clean Mop Tray", "percent_left"),
|
||||
ConsumableSignature(("lifespan_air_freshener",), "Replace Air Freshener", "percent_left"),
|
||||
ConsumableSignature(("lifespan_uv_sanitizer",), "Replace UV Lamp", "percent_left"),
|
||||
# GOAT robotic mowers report their wear parts through the same platform.
|
||||
ConsumableSignature(("lifespan_blade",), "Replace Blades", "percent_left"),
|
||||
ConsumableSignature(("lifespan_lens_brush",), "Replace Lens Brush", "percent_left"),
|
||||
ConsumableSignature(("lifespan_trimmer_brush",), "Replace Trimmer Brush", "percent_left"),
|
||||
ConsumableSignature(("lifespan_weed_rope",), "Replace Trimmer Line", "percent_left"),
|
||||
# Lifetime mowing time — undercarriage wash every 25 h like the
|
||||
# automower/landroid signatures.
|
||||
ConsumableSignature(("total_stats_time_mower",), "Clean Undercarriage", "usage_delta", delta_units=25),
|
||||
),
|
||||
),
|
||||
"weback_vacuum": IntegrationSignature(
|
||||
@@ -86,22 +139,8 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"the ENGINE accumulates cleaning time on the vacuum entity."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
),
|
||||
),
|
||||
"roomba": IntegrationSignature(
|
||||
@@ -113,22 +152,8 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"ENGINE accumulates cleaning time."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
ConsumableSignature(
|
||||
("bin_full",),
|
||||
"Empty Dustbin",
|
||||
@@ -149,22 +174,8 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"ENGINE accumulates cleaning time."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
),
|
||||
),
|
||||
"romy": IntegrationSignature(
|
||||
@@ -176,49 +187,39 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"ENGINE accumulates cleaning time."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
),
|
||||
),
|
||||
"tuya": IntegrationSignature(
|
||||
name="Tuya vacuum",
|
||||
verified="2026-07-18 @ home-assistant/core dev",
|
||||
verified="2026-09-25 @ home-assistant/core dev",
|
||||
source=(
|
||||
"home-assistant/core homeassistant/components/tuya/vacuum.py "
|
||||
"(vacuum platform verified present; no consumable sensors) — the "
|
||||
"ENGINE accumulates cleaning time, entity_domain-gated so the bridge's other device types are untouched."
|
||||
"home-assistant/core homeassistant/components/tuya/vacuum.py (vacuum "
|
||||
"platform) — the ENGINE accumulates cleaning time, entity_domain-gated so "
|
||||
"the bridge's other device types are untouched. sensor.py category SD "
|
||||
"(robot vacuum) ALSO has consumable sensors (present since 2026.7): tks "
|
||||
"'duster_cloth_life' (DP duster_cloth), 'side_brush_life' (DP edge_brush), "
|
||||
"'filter_life' (DPCode.FILTER_LIFE = DP 'filter', const.py: 'Filter life "
|
||||
"(percentage)'), 'rolling_brush_life' (DP roll_brush). No unit in the "
|
||||
"description — TuyaSensorEntity takes the device's DP unit; Tuya's sd "
|
||||
"standard status set defines all four as 'life' Integer 0-100 %, reset via "
|
||||
"reset_* DPs → percent_left. Devices whose DP reports 'min'/'h' instead are "
|
||||
"NOT matched (unit gate): real devices mislabel the unit (Neatsvor X600 "
|
||||
"reports 'min' with a 200-max range), so no duration signature. SKIPPED: "
|
||||
"KJ purifier 'filter_utilization' (Tuya: 'Filter cartridge utilization', "
|
||||
"used-vs-remaining undetermined) and CWYSJ fountain 'filter_duration' (DP "
|
||||
"filter_life 'hours', direction undetermined). The runtime duties stay: "
|
||||
"washing the filter / de-tangling the brush is a separate duty from "
|
||||
"replacing the part at end of life."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(("rolling_brush_life",), "Replace Main Brush", "percent_left"),
|
||||
SIDE_BRUSH_LIFE_PERCENT,
|
||||
FILTER_LIFE_PERCENT,
|
||||
ConsumableSignature(("duster_cloth_life",), "Replace Mop Pads", "percent_left"),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
),
|
||||
),
|
||||
"switchbot_cloud": IntegrationSignature(
|
||||
@@ -230,22 +231,8 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"ENGINE accumulates cleaning time, entity_domain-gated so the bridge's other device types are untouched."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
),
|
||||
),
|
||||
"smartthings": IntegrationSignature(
|
||||
@@ -261,26 +248,12 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"(SAMSUNG_CE_HOOD_FILTER, PERCENTAGE) — same up-counting shape."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
# Samsung fridge water filter / hood grease filter: usage counts
|
||||
# UP in percent; replacing/cleaning resets to 0 (auto-resolve).
|
||||
ConsumableSignature(("water_filter_usage",), "Replace Water Filter", "alert_above", delta_units=90),
|
||||
ConsumableSignature(("hood_filter_usage",), "Clean Grease Filter", "alert_above", delta_units=90),
|
||||
HOOD_GREASE_FILTER_USAGE,
|
||||
),
|
||||
),
|
||||
"sharkiq": IntegrationSignature(
|
||||
@@ -292,22 +265,8 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"ENGINE accumulates cleaning time."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
),
|
||||
),
|
||||
"tplink": IntegrationSignature(
|
||||
@@ -319,22 +278,8 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
"ENGINE accumulates cleaning time, entity_domain-gated so the bridge's other device types are untouched."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Filter Cleaning",
|
||||
"runtime_hours",
|
||||
delta_units=15,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
ConsumableSignature(
|
||||
(),
|
||||
"Clean Main Brush",
|
||||
"runtime_hours",
|
||||
delta_units=30,
|
||||
entity_domain="vacuum",
|
||||
on_states=("cleaning",),
|
||||
),
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
),
|
||||
),
|
||||
"mydolphin_plus": IntegrationSignature(
|
||||
@@ -356,4 +301,107 @@ SIGNATURES: dict[str, IntegrationSignature] = {
|
||||
),
|
||||
),
|
||||
),
|
||||
"robovac_mqtt": IntegrationSignature(
|
||||
name="Eufy Clean",
|
||||
verified="2026-09-25 @ jeppesens/eufy-clean main",
|
||||
source=(
|
||||
"jeppesens/eufy-clean custom_components/robovac_mqtt/sensor.py accessory "
|
||||
"sensors: RoboVacSensor(coordinator, attr.replace('_usage', '_remaining'), "
|
||||
"name, …) with _attr_has_entity_name and names 'Filter Remaining' / "
|
||||
"'Rolling Brush Remaining' / 'Side Brush Remaining' / 'Sensor Remaining' / "
|
||||
"'Cleaning Tray Remaining' / 'Mopping Cloth Remaining' → entity-id "
|
||||
"suffixes; unit 'h', value = max life − usage (const.py "
|
||||
"ACCESSORY_MAX_LIFE / SCALAR_ACCESSORY_MAX_LIFE) → hours REMAINING, reset "
|
||||
"buttons in button.py. Tray and mop only on mop-capable (novel) models."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(("filter_remaining",), "Replace Filter", "duration_left"),
|
||||
ConsumableSignature(("rolling_brush_remaining",), "Replace Main Brush", "duration_left"),
|
||||
ConsumableSignature(("side_brush_remaining",), "Replace Side Brush", "duration_left"),
|
||||
ConsumableSignature(("mopping_cloth_remaining",), "Replace Mop Pads", "duration_left"),
|
||||
# Short cleaning intervals (sensors 60/35 h, tray 30 h): warn in
|
||||
# the last 6 h instead of the 24 h default, which would fire
|
||||
# almost right after the previous cleaning.
|
||||
ConsumableSignature(("sensor_remaining",), "Clean Sensors", "duration_left", below_hours=6),
|
||||
ConsumableSignature(("cleaning_tray_remaining",), "Clean Mop Tray", "duration_left", below_hours=6),
|
||||
),
|
||||
),
|
||||
"robovac": IntegrationSignature(
|
||||
name="Eufy RoboVac",
|
||||
verified="2026-09-25 @ damacus/robovac main",
|
||||
source=(
|
||||
"damacus/robovac custom_components/robovac/vacuum.py (vacuum platform, "
|
||||
"VacuumActivity.CLEANING) — the ENGINE accumulates cleaning time on every "
|
||||
"model. sensor.py RobovacConsumableSensor (proto models with DPS 168 only): "
|
||||
"_attr_has_entity_name, _attr_name = label from _PROTO_CONSUMABLES ('Side "
|
||||
"Brush' / 'Rolling Brush' / 'Filter' / 'Scraper' / 'Sensor' / 'Mop') → "
|
||||
"entity-id suffixes; unit 'h' = 'cumulative hours since the last manual "
|
||||
"reset' (proto_decode.decode_consumable_response) → usage_above. Limits = "
|
||||
"Eufy's accessory lifetimes as encoded in jeppesens/eufy-clean const.py "
|
||||
"ACCESSORY_MAX_LIFE (same DPS 168 ConsumableResponse). 'Dust Bag' skipped "
|
||||
"(no lifetime reference)."
|
||||
),
|
||||
tasks=(
|
||||
VACUUM_FILTER_CLEANING_RUNTIME,
|
||||
VACUUM_MAIN_BRUSH_RUNTIME,
|
||||
ConsumableSignature(("filter",), "Replace Filter", "usage_above", above_hours=360),
|
||||
ConsumableSignature(("rolling_brush",), "Replace Main Brush", "usage_above", above_hours=360),
|
||||
ConsumableSignature(("side_brush",), "Replace Side Brush", "usage_above", above_hours=180),
|
||||
ConsumableSignature(("mop",), "Replace Mop Pads", "usage_above", above_hours=180),
|
||||
ConsumableSignature(("sensor",), "Clean Sensors", "usage_above", above_hours=60),
|
||||
ConsumableSignature(("scraper",), "Clean Mop Tray", "usage_above", above_hours=30),
|
||||
),
|
||||
),
|
||||
"tineco": IntegrationSignature(
|
||||
name="Tineco",
|
||||
verified="2026-09-25 @ wheeller123/Tineco-Integration main",
|
||||
source=(
|
||||
"wheeller123/Tineco-Integration custom_components/tineco/sensor.py "
|
||||
"TinecoBrushRollerSensor: _attr_translation_key 'brush_roller', ENUM "
|
||||
"options normal/tangled/stuck/needs_cleaning (br code 3) — latch on "
|
||||
"'needs_cleaning'; the device reporting 'normal' again auto-resolves."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(
|
||||
("brush_roller",),
|
||||
"Clean Main Brush",
|
||||
"event_present",
|
||||
on_states=("needs_cleaning",),
|
||||
),
|
||||
),
|
||||
),
|
||||
"xiaomi_vacuum": IntegrationSignature(
|
||||
name="Xiaomi Vacuum (cloud)",
|
||||
verified="2026-09-25 @ roquerodrigo/ha-xiaomi-vacuum main",
|
||||
source=(
|
||||
"roquerodrigo/ha-xiaomi-vacuum custom_components/xiaomi_vacuum/sensor/"
|
||||
"{filter,main_brush,side_brush,mop}_life.py: _attr_translation_key "
|
||||
"'filter_life' / 'main_brush_life' / 'side_brush_life' / 'mop_life', "
|
||||
"life_base.py PERCENTAGE 'remaining life 0-100' (MIoT life-level)."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(("main_brush_life",), "Replace Main Brush", "percent_left"),
|
||||
SIDE_BRUSH_LIFE_PERCENT,
|
||||
FILTER_LIFE_PERCENT,
|
||||
ConsumableSignature(("mop_life",), "Replace Mop Pads", "percent_left"),
|
||||
),
|
||||
),
|
||||
"ilife": IntegrationSignature(
|
||||
name="ILIFE",
|
||||
verified="2026-09-25 @ maximedeprince/ha-ilife main",
|
||||
source=(
|
||||
"maximedeprince/ha-ilife custom_components/ilife/sensor.py SENSORS "
|
||||
"(ILIFE-cloud backend): translation_key 'main_brush' / 'side_brush' / "
|
||||
"'filter', PERCENTAGE from PartsStatus MainBrushLife/SideBrushLife/"
|
||||
"FilterLife; api.py reset_part sets the field back to 100 → remaining. "
|
||||
"Gated on the sibling tk 'history' (ILifeHistorySensor, cloud backend "
|
||||
"only): the Tuya backend's TuyaGenericSensor names raw DP codes (a bare "
|
||||
"'filter' DP of unknown unit/direction would otherwise suffix-match)."
|
||||
),
|
||||
tasks=(
|
||||
ConsumableSignature(("main_brush",), "Replace Main Brush", "percent_left", require_sibling_keys=("history",)),
|
||||
ConsumableSignature(("side_brush",), "Replace Side Brush", "percent_left", require_sibling_keys=("history",)),
|
||||
ConsumableSignature(("filter",), "Replace Filter", "percent_left", require_sibling_keys=("history",)),
|
||||
),
|
||||
),
|
||||
}
|
||||
Reference in new issue
Block a user