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

59 lines
2.6 KiB
Python

"""Personal-care devices.
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
SIGNATURES: dict[str, IntegrationSignature] = {
"oralb": IntegrationSignature(
name="Oral-B toothbrush",
verified="2026-07-19 @ core/dev oralb/sensor.py",
source=(
"core oralb (BLE): tk 'toothbrush_state', ENUM incl. 'running' — "
"the engine accumulates brushing time (the per-session 'time' "
"sensor is session-scoped, unusable for deltas). 6 h of brushing "
"= the dentist's 3 months at 2x2 minutes a day. BLE gaps pause "
"the runtime trigger; brushing only happens while connected."
),
tasks=(
ConsumableSignature(
("toothbrush_state",),
"Replace Brush Head",
"runtime_hours",
delta_units=6,
on_states=("running",),
),
),
),
"oralb_live": IntegrationSignature(
name="Oral-B (live BLE)",
verified="2026-09-25 @ thomasgregg/oralb-ha main",
source=(
"thomasgregg/oralb-ha custom_components/oralb_live/sensor.py: key/tk "
"'refill_days' ('Brush head remaining', UnitOfTime.DAYS, DURATION, "
"entity_registry_enabled_default=False — discovered once the user "
"enables it); protocol.parse_refill_remainder decodes the handle's own "
"brush-head countdown (ff2d). The sibling 'refill_brushing_time' "
"(hours) is the same countdown in another unit — one signal per duty."
),
tasks=(ConsumableSignature(("refill_days",), "Replace Brush Head", "duration_left", below_hours=48),),
),
"philips_shaver": IntegrationSignature(
name="Philips shaver",
verified="2026-09-25 @ mtheli/philips_shaver main",
source=(
"mtheli/philips_shaver custom_components/philips_shaver/sensor.py "
"PhilipsHeadRemainingSensor: _attr_translation_key 'head_remaining', "
"PERCENTAGE (coordinator: CHAR_HEAD_REMAINING byte — the shaver's own "
"head-life counter). 'cleaning_cycles_remaining' is skipped: an "
"integration-side evaporation estimate, not a device value."
),
tasks=(ConsumableSignature(("head_remaining",), "Replace Shaver Head", "percent_left"),),
),
}