Add coffee-maker capabilities to the water purifier registry (issue #107)

Some TP2X_WATERPURIFIER_20K units are coffee-capable and expose five
resources issue #90's original dump never had:
/favorite/coffee/vs/0, /favorite/hotwater/vs/0,
/brand/recipe/info/vs/0, /coffee/custom/recipe/vs/0,
/recipe/coffee/vs/0, and /recipe/coffee/deletion/vs/0.

Adds FAVORITE_HOTWATER (a switch + select pair on
/favorite/hotwater/vs/0, mirroring the existing FAVORITE_CAPACITY
pattern) and COFFEE (a switch + status sensor on
/favorite/coffee/vs/0). The remaining four hrefs are static
capability-advertisement blobs or empty on every dump seen so far --
no live "current recipe" or "current custom slot" field to expose --
so they're added to the ignored coverage list per the 'don't guess'
rule rather than modeled speculatively.

Confirmed against the issue #107 diagnostics dump with zero unbound
hrefs.
This commit is contained in:
Marc Billow committed 2026-07-27 04:19:19 +00:00
1 parent b3a9192088
commit 35775c3d4a
8 files changed
+496

No files matched your search

@@ -12,6 +12,8 @@ REGISTRY = DeviceRegistry(
water_purifier.DISPENSE,
water_purifier.STATUS,
water_purifier.FAVORITE_CAPACITY,
water_purifier.FAVORITE_HOTWATER,
water_purifier.COFFEE,
water_purifier.LOCK,
*water_purifier.COVERAGE,
]),
@@ -116,6 +116,50 @@ FAVORITE_CAPACITY = Capability(
),
)
# Coffee-capable variant (issue #107) -- same "favorite" enable-toggle +
# supported-list select shape as FAVORITE_CAPACITY above, but for the hot
# water dispensed alongside brewing rather than the pour capacity.
FAVORITE_HOTWATER = Capability(
href='/favorite/hotwater/vs/0',
poll_tier='cold',
entities=(
SwitchDesc(key='favorite_hotwater_enabled', field='x.com.samsung.da.switchHotwater',
icon='mdi:star-outline',
entity_category='config',
value_fn=lambda v: v != 'Locked',
write_fn=lambda p, rep, href=None: (
['favorite', 'hotwater', 'vs', '0'],
{'x.com.samsung.da.switchHotwater': 'Unlocked' if p == 'On' else 'Locked'})),
SelectDesc(key='favorite_hotwater_temperature',
field='x.com.samsung.da.favorite.defaultTemperature',
icon='mdi:thermometer',
entity_category='config',
options_field='x.com.samsung.da.favorite.supportedList',
write_fn=lambda p, rep, href=None: (
['favorite', 'hotwater', 'vs', '0'],
{'x.com.samsung.da.favorite.defaultTemperature': p})),
),
)
# Coffee-capable variant (issue #107). No 'x.com.samsung.da.' field prefix
# on this resource, unlike the rest of the water-purifier surface.
COFFEE = Capability(
href='/favorite/coffee/vs/0',
poll_tier='warm',
entities=(
SwitchDesc(key='favorite_coffee_enabled', field='favorite.activate',
icon='mdi:coffee-outline',
entity_category='config',
value_fn=lambda v: v == 'On',
write_fn=lambda p, rep, href=None: (
['favorite', 'coffee', 'vs', '0'],
{'favorite.activate': 'On' if p == 'On' else 'Off'})),
SensorDesc(key='coffee_brew_status', field='brew.status',
icon='mdi:coffee-outline',
entity_category='diagnostic'),
),
)
LOCK = Capability(
href='/status/lock/vs/0',
poll_tier='warm',
@@ -160,6 +204,14 @@ _WP_IGNORED = [
# Static support-flags blob (automation.supported.modes/options) -- no
# live "current automation setting" field to expose.
'/automation/waterpurifier/vs/0',
# Coffee-capable variant (issue #107). All four are static
# capability-advertisement blobs or empty -- no live "current recipe" /
# "current custom slot" field to expose, unlike /favorite/coffee/vs/0
# (COFFEE above), which does carry live brew status.
'/brand/recipe/info/vs/0', # revision + max-brand-count metadata
'/coffee/custom/recipe/vs/0', # publisher.support: allowed custom-recipe slot IDs
'/recipe/coffee/vs/0', # same publisher.support shape, no per-recipe content
'/recipe/coffee/deletion/vs/0', # empty {} on this dump
]
COVERAGE = [Capability(href=h) for h in _WP_IGNORED]
@@ -250,6 +250,9 @@
"favorite_capacity": {
"name": "Favorite capacity"
},
"favorite_hotwater_temperature": {
"name": "Favorite hot water temperature"
},
"finish_sound": {
"name": "Finish sound",
"state": {
@@ -487,6 +490,9 @@
"clean_level": {
"name": "Clean level"
},
"coffee_brew_status": {
"name": "Coffee brew status"
},
"connection_mode": {
"name": "Connection mode",
"state": {
@@ -759,6 +765,12 @@
"favorite_capacity_enabled": {
"name": "Favorite capacity"
},
"favorite_coffee_enabled": {
"name": "Favorite coffee"
},
"favorite_hotwater_enabled": {
"name": "Favorite hot water"
},
"fridge_sound": {
"name": "Sound"
},
@@ -250,6 +250,9 @@
"favorite_capacity": {
"name": "Favoriete capaciteit"
},
"favorite_hotwater_temperature": {
"name": "Favoriete temperatuur warm water"
},
"finish_sound": {
"name": "Eindgeluid",
"state": {
@@ -487,6 +490,9 @@
"clean_level": {
"name": "Reinigingsniveau"
},
"coffee_brew_status": {
"name": "Koffiezetstatus"
},
"connection_mode": {
"name": "Verbindingsmodus",
"state": {
@@ -759,6 +765,12 @@
"favorite_capacity_enabled": {
"name": "Favoriete capaciteit"
},
"favorite_coffee_enabled": {
"name": "Favoriete koffie"
},
"favorite_hotwater_enabled": {
"name": "Favoriet warm water"
},
"fridge_sound": {
"name": "Geluid"
},