Deduplicate ISO-timestamp parsing and document the new device type (review follow-up, issue #131)
- vacuum_station._parse_iso_utc was a verbatim copy of water_purifier._parse_iso_utc; promoted to common.parse_iso_utc and pointed both families at it. Also made it tzinfo-aware rather than unconditionally overwriting with UTC -- harmless today since every dump seen is a bare or Z-suffixed UTC timestamp, but a board that ever emits a real offset would otherwise have it silently clobbered. - Added the new vacuum_station type to the README's supported-appliance table, and noted that combi microwaves route through the oven registry.
This commit is contained in:
@@ -25,7 +25,7 @@ Your state stays on your LAN: HA talks to the appliance over a direct DTLS sessi
|
|||||||
| Air purifier | `by_type/air_purifier.py` |
|
| Air purifier | `by_type/air_purifier.py` |
|
||||||
| Dehumidifier | `by_type/dehumidifier.py` |
|
| Dehumidifier | `by_type/dehumidifier.py` |
|
||||||
| Dryer | `by_type/dryer.py` |
|
| Dryer | `by_type/dryer.py` |
|
||||||
| Oven | `by_type/oven.py` |
|
| Oven (including combi microwaves) | `by_type/oven.py` |
|
||||||
| Gas cooktop (read-only burner status) | `by_type/cooktop.py` |
|
| Gas cooktop (read-only burner status) | `by_type/cooktop.py` |
|
||||||
| Range hood | `by_type/range_hood.py` |
|
| Range hood | `by_type/range_hood.py` |
|
||||||
| Range | `by_type/range.py` |
|
| Range | `by_type/range.py` |
|
||||||
@@ -33,6 +33,7 @@ Your state stays on your LAN: HA talks to the appliance over a direct DTLS sessi
|
|||||||
| Refrigerator | `by_type/refrigerator.py` |
|
| Refrigerator | `by_type/refrigerator.py` |
|
||||||
| Washer | `by_type/washer.py` |
|
| Washer | `by_type/washer.py` |
|
||||||
| Water purifier | `by_type/water_purifier.py` |
|
| Water purifier | `by_type/water_purifier.py` |
|
||||||
|
| Vacuum clean/auto-empty station | `by_type/vacuum_station.py` |
|
||||||
|
|
||||||
Each registry composes shared and family-specific `Capability` objects from `registry/capabilities/`; those modules document the individual resources/entities in more depth than a README table can stay current with.
|
Each registry composes shared and family-specific `Capability` objects from `registry/capabilities/`; those modules document the individual resources/entities in more depth than a README table can stay current with.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ against live device dumps:
|
|||||||
/water/consumption/vs/0 -> x.com.samsung.da.cumulativeWater
|
/water/consumption/vs/0 -> x.com.samsung.da.cumulativeWater
|
||||||
/filter/waterfilter/vs/0 -> x.com.samsung.da.filterUsage / filterStatus
|
/filter/waterfilter/vs/0 -> x.com.samsung.da.filterUsage / filterStatus
|
||||||
"""
|
"""
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
from ..capability import Capability
|
from ..capability import Capability
|
||||||
from ..entities import (
|
from ..entities import (
|
||||||
BinarySensorDesc, ButtonDesc, SelectDesc, SensorDesc, SwitchDesc,
|
BinarySensorDesc, ButtonDesc, SelectDesc, SensorDesc, SwitchDesc,
|
||||||
@@ -40,6 +42,22 @@ def wh_to_kwh(v):
|
|||||||
return round(n / 1000.0, 2) if n is not None else None
|
return round(n / 1000.0, 2) if n is not None else None
|
||||||
|
|
||||||
|
|
||||||
|
def parse_iso_utc(raw):
|
||||||
|
"""ISO datetime defaulting to UTC when the string carries no timezone
|
||||||
|
of its own (this integration's convention for other bare ISO datetime
|
||||||
|
fields -- see washer.py's drum-clean-log comment). A few boards do
|
||||||
|
ship a 'Z'/offset suffix (fromisoformat parses that natively since
|
||||||
|
Python 3.11) -- only fill in UTC when parsing left the result naive,
|
||||||
|
rather than unconditionally overwriting whatever offset was parsed."""
|
||||||
|
if not raw:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
dt = datetime.fromisoformat(raw)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
return dt if dt.tzinfo is not None else dt.replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
def filter_usage_percent(rep):
|
def filter_usage_percent(rep):
|
||||||
"""Filter usage as a percentage of rated capacity. Several families
|
"""Filter usage as a percentage of rated capacity. Several families
|
||||||
(AC, air purifier) report `filterUsage` as a raw count in
|
(AC, air purifier) report `filterUsage` as a raw count in
|
||||||
|
|||||||
@@ -15,23 +15,9 @@ docstring for that rule).
|
|||||||
|
|
||||||
Resources verified against the issue #131 diagnostics dump.
|
Resources verified against the issue #131 diagnostics dump.
|
||||||
"""
|
"""
|
||||||
from datetime import datetime, timezone
|
|
||||||
|
|
||||||
from ..capability import Capability
|
from ..capability import Capability
|
||||||
from ..entities import BinarySensorDesc, SelectDesc, SensorDesc, SwitchDesc
|
from ..entities import BinarySensorDesc, SelectDesc, SensorDesc, SwitchDesc
|
||||||
from .common import int_or_none
|
from .common import int_or_none, parse_iso_utc as _parse_iso_utc
|
||||||
|
|
||||||
|
|
||||||
def _parse_iso_utc(raw):
|
|
||||||
"""Bare ISO datetime with no timezone field alongside it -- treated as
|
|
||||||
UTC, matching this integration's convention for other bare ISO datetime
|
|
||||||
fields (see water_purifier.py's own _parse_iso_utc)."""
|
|
||||||
if not raw:
|
|
||||||
return None
|
|
||||||
try:
|
|
||||||
return datetime.fromisoformat(raw).replace(tzinfo=timezone.utc)
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
DUSTBAG = Capability(
|
DUSTBAG = Capability(
|
||||||
|
|||||||
@@ -3,23 +3,9 @@ issue #90, model TP2X_WATERPURIFIER_20K).
|
|||||||
|
|
||||||
Resources verified against the issue #90 diagnostics dump.
|
Resources verified against the issue #90 diagnostics dump.
|
||||||
"""
|
"""
|
||||||
from datetime import datetime, timezone
|
|
||||||
|
|
||||||
from ..capability import Capability
|
from ..capability import Capability
|
||||||
from ..entities import BinarySensorDesc, NumberDesc, SelectDesc, SensorDesc, SwitchDesc
|
from ..entities import BinarySensorDesc, NumberDesc, SelectDesc, SensorDesc, SwitchDesc
|
||||||
from .common import int_or_none
|
from .common import int_or_none, parse_iso_utc as _parse_iso_utc
|
||||||
|
|
||||||
|
|
||||||
def _parse_iso_utc(raw):
|
|
||||||
"""Bare ISO datetime with no timezone field alongside it -- treated as
|
|
||||||
UTC, matching this integration's convention for other bare ISO datetime
|
|
||||||
fields (see washer.py's drum-clean-log comment)."""
|
|
||||||
if not raw:
|
|
||||||
return None
|
|
||||||
try:
|
|
||||||
return datetime.fromisoformat(raw).replace(tzinfo=timezone.utc)
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
DISPENSE = Capability(
|
DISPENSE = Capability(
|
||||||
|
|||||||
Reference in New Issue
Block a user