Merge pull request #33 from mbillow/claude/triage-dump-device-support-1pqxfr

feat: detect FlexWash (WV) washers; add combo dry-level select
This commit is contained in:
Marc Billow
2026-07-22 01:17:29 -05:00
committed by GitHub
25 changed files with 1774 additions and 12 deletions
+1 -1
View File
@@ -12,5 +12,5 @@
"pyOpenSSL>=23.0",
"smartthings-local>=0.1.0"
],
"version": "0.7.0"
"version": "0.8.0"
}
@@ -69,6 +69,7 @@ _CONSUMER_PREFIX_TO_KEY: dict[str, str] = {
'WW': 'washer',
'WD': 'washer',
'WF': 'washer',
'WV': 'washer', # FlexWash twin units (e.g. WV55M9600AW) -- issue #19
'DV': 'dryer',
'DW': 'dishwasher',
}
@@ -1,5 +1,5 @@
"""Refrigerator device registry."""
from ..capabilities import common, fridge, ignored
from ..capabilities import common, dishwasher, fridge, ignored
from ._base import DeviceRegistry, _build
REGISTRY = DeviceRegistry(
@@ -17,6 +17,7 @@ REGISTRY = DeviceRegistry(
common.ALARMS,
common.ENERGY_METER,
common.WATER_FILTER,
dishwasher.DIAGNOSIS,
fridge.ICEMAKER_NIGHTTIME,
fridge.FLEX_ZONE,
fridge.REFRIGERATION,
@@ -26,6 +27,7 @@ REGISTRY = DeviceRegistry(
fridge.CABINET_LIGHT_ENHANCED,
fridge.SABBATH,
fridge.BEVERAGE_ZONE,
fridge.PANTRY_ZONE,
fridge.FIRMWARE_UPDATE,
fridge.DEFROST_DELAY,
fridge.DEFROST_DELAY_NATIVE_DUPLICATE,
@@ -175,6 +175,38 @@ ENERGY_METER = Capability(
state_class='total_increasing', unit='kWh', value_fn=wh_to_kwh,
exists_fn=lambda rep, resources: (
not rep or 'x.com.samsung.da.cumulativePower' in rep)),
# cumulativeConsumption is a second, independently-varying running
# total alongside cumulativePower -- some fridges (issue #26) report
# both. Self-gates off where only cumulativePower is present. `not
# rep or` keeps the same empty-{} stub carve-out as power_watts/
# energy_kwh above -- without it, an exists_fn permanently drops the
# entity if setup happens to land on a not-yet-fetched stub.
SensorDesc(key='power_energy_kwh', field='x.com.samsung.da.cumulativeConsumption',
name='Power energy', device_class='energy',
state_class='total_increasing', unit='kWh', value_fn=wh_to_kwh,
exists_fn=lambda rep, resources: (
not rep or 'x.com.samsung.da.cumulativeConsumption' in rep)),
# AI Energy Mode's lifetime savings estimate vs. an unoptimized
# baseline -- present on some models (e.g. TP1X_REF_21K, issue #21/
# #27) and absent on others (issue #20/#26), unlike cumulativePower.
SensorDesc(key='energy_saved_kwh', field='x.com.samsung.da.cumulativeSavedPower',
name='Energy saved', device_class='energy',
state_class='total_increasing', unit='kWh', value_fn=wh_to_kwh,
exists_fn=lambda rep, resources: (
not rep or 'x.com.samsung.da.cumulativeSavedPower' in rep)),
# Monthly billing-cycle totals -- the completed prior month and the
# in-progress current month. Not ever-increasing (each resets at
# month boundary), so no state_class.
SensorDesc(key='energy_last_month_kwh', field='x.com.samsung.da.monthlyConsumption',
name='Energy (last month)', device_class='energy',
unit='kWh', value_fn=wh_to_kwh,
exists_fn=lambda rep, resources: (
not rep or 'x.com.samsung.da.monthlyConsumption' in rep)),
SensorDesc(key='energy_this_month_kwh', field='x.com.samsung.da.thismonthlyConsumption',
name='Energy (this month)', device_class='energy',
unit='kWh', value_fn=wh_to_kwh,
exists_fn=lambda rep, resources: (
not rep or 'x.com.samsung.da.thismonthlyConsumption' in rep)),
),
)
@@ -502,17 +502,64 @@ BEVERAGE_ZONE = Capability(
),
)
# ---------------------------------------------------------------------------
# Pantry / Cool Select Zone -- a convertible compartment toggled between
# wine/deli/drinks temperature presets (issue #20). Same shape as
# BEVERAGE_ZONE (a controllable named sub-zone with a mode + supported-modes
# list) but a distinct resource/field set -- x.com.samsung.da.mode /
# x.com.samsung.da.supportedOptions on /status/pantry/one/vs/0, rather than
# roomDesiredMode/roomSupportedModes on /specialzone/one/vs/0. Only a "one"
# instance has been seen; not generalized to a pattern cap until a second
# instance turns up.
# ---------------------------------------------------------------------------
def _pantry_write(p, rep, href=None):
return ['status', 'pantry', 'one', 'vs', '0'], {'x.com.samsung.da.mode': p}
PANTRY_ZONE = Capability(
href='/status/pantry/one/vs/0',
poll_tier='warm',
entities=(
SelectDesc(key='pantry_zone_mode', field='x.com.samsung.da.mode',
name='Pantry zone mode', icon='mdi:glass-wine',
translation_key='pantry_zone_mode',
entity_category='config',
options_field='x.com.samsung.da.supportedOptions',
write_fn=_pantry_write),
),
)
# ---------------------------------------------------------------------------
# Flex zone (convertible drawer — /mode/vs/0 on RF9000-class fridges)
#
# x.com.samsung.da.modes holds multiple orthogonal flags in one list.
# The flex zone entry is identified by the CV_TTYPE_RF9000A_ prefix.
# x.com.samsung.da.modes holds multiple orthogonal flags in one list; the
# flex-zone entry is whichever item is also a member of supportedOptions --
# the other flags (WATERFILTER_*, DEFROST_BLOCK_*, the CVN_*_ZONE marker)
# never appear there. The prefix on that item varies by fridge family
# (CV_TTYPE_RF9000A_ on RF9000-class, CV_FDR_ on Bespoke-class -- issue #27 /
# #26, where the old CV_TTYPE_RF9000A_-only match left this entity bound but
# stuck on None), so match by list membership instead of a hardcoded prefix.
# Write replaces only that item; other flags are preserved.
# ---------------------------------------------------------------------------
def _flex_zone_supported(rep):
return set(rep.get('x.com.samsung.da.supportedOptions') or ())
def _flex_zone_current(rep):
# Every dump seen has at most one modes/supportedOptions overlap, so
# "first match" and "strip all matches" (in the write below) agree. If a
# future device ever reports two, this reads the first and the write
# would drop both -- revisit if that turns up.
modes = rep.get('x.com.samsung.da.modes') or []
supported = _flex_zone_supported(rep)
return next((m for m in modes if m in supported), None)
def _flex_zone_write(p, rep, href=None):
modes = list(rep.get('x.com.samsung.da.modes') or [])
modes = [m for m in modes if not m.startswith('CV_TTYPE_RF9000A_')]
supported = _flex_zone_supported(rep)
modes = [m for m in (rep.get('x.com.samsung.da.modes') or []) if m not in supported]
modes.append(p)
return ['mode', 'vs', '0'], {'x.com.samsung.da.modes': modes}
@@ -522,16 +569,13 @@ FLEX_ZONE = Capability(
poll_tier='warm',
entities=(
SelectDesc(key='flex_zone_mode',
field='x.com.samsung.da.modes',
name='Flex zone mode', icon='mdi:thermostat',
translation_key='flex_zone_mode',
entity_category='config',
options_field='x.com.samsung.da.supportedOptions',
exists_fn=lambda rep, resources: bool(
rep.get('x.com.samsung.da.supportedOptions')),
value_fn=lambda modes: next(
(m for m in (modes or [])
if m.startswith('CV_TTYPE_RF9000A_')), None),
rep_fn=_flex_zone_current,
write_fn=_flex_zone_write),
),
)
@@ -82,6 +82,19 @@ WASHER_SETTINGS = Capability(
options_field='x.com.samsung.da.supportedRinseCycles',
write_fn=lambda p, rep, href=None: (
['washer', 'vs', '0'], {'x.com.samsung.da.rinseCycles': p})),
# Washer/dryer combo units carry a dryLevel field on the wash
# resource itself (no separate dryer device/course) -- see issue
# #22. Self-gates off on plain washers, which never report
# supportedDryLevel.
SelectDesc(key='dry_level', field='x.com.samsung.da.dryLevel',
name='Dry level', icon='mdi:tumble-dryer',
entity_category='config',
translation_key='washer_dry_level',
options_field='x.com.samsung.da.supportedDryLevel',
exists_fn=lambda rep, resources: bool(
rep.get('x.com.samsung.da.supportedDryLevel')),
write_fn=lambda p, rep, href=None: (
['washer', 'vs', '0'], {'x.com.samsung.da.dryLevel': p})),
),
)
+25 -1
View File
@@ -30,13 +30,25 @@
"sp_ttype_wine_dessert": "Wine and Dessert"
}
},
"pantry_zone_mode": {
"state": {
"fdr_wine": "Wine",
"fdr_deli": "Deli",
"fdr_drinks": "Drinks"
}
},
"flex_zone_mode": {
"state": {
"cv_ttype_rf9000a_freeze": "Freeze",
"cv_ttype_rf9000a_softfreeze": "Soft Freeze",
"cv_ttype_rf9000a_meat_fish": "Meat/Fish",
"cv_ttype_rf9000a_fruit_veggies": "Fruit & Veggies",
"cv_ttype_rf9000a_beverage": "Beverage"
"cv_ttype_rf9000a_beverage": "Beverage",
"cv_fdr_wine": "Wine",
"cv_fdr_deli": "Deli",
"cv_fdr_beverage": "Beverage",
"cv_fdr_meat": "Meat",
"cv_fdr_soft_freezer": "Soft Freezer"
}
},
"dishwasher_cycle": {
@@ -119,6 +131,18 @@
"02": "2x",
"03": "3x"
}
},
"washer_dry_level": {
"state": {
"none": "Off",
"cupboard": "Cupboard",
"30": "30 min",
"60": "1 hr",
"90": "1 hr 30",
"120": "2 hr",
"180": "3 hr",
"240": "4 hr"
}
}
},
"sensor": {
@@ -30,13 +30,25 @@
"sp_ttype_wine_dessert": "Wine and Dessert"
}
},
"pantry_zone_mode": {
"state": {
"fdr_wine": "Wine",
"fdr_deli": "Deli",
"fdr_drinks": "Drinks"
}
},
"flex_zone_mode": {
"state": {
"cv_ttype_rf9000a_freeze": "Freeze",
"cv_ttype_rf9000a_softfreeze": "Soft Freeze",
"cv_ttype_rf9000a_meat_fish": "Meat/Fish",
"cv_ttype_rf9000a_fruit_veggies": "Fruit & Veggies",
"cv_ttype_rf9000a_beverage": "Beverage"
"cv_ttype_rf9000a_beverage": "Beverage",
"cv_fdr_wine": "Wine",
"cv_fdr_deli": "Deli",
"cv_fdr_beverage": "Beverage",
"cv_fdr_meat": "Meat",
"cv_fdr_soft_freezer": "Soft Freezer"
}
},
"dishwasher_cycle": {
@@ -119,6 +131,18 @@
"02": "2x",
"03": "3x"
}
},
"washer_dry_level": {
"state": {
"none": "Off",
"cupboard": "Cupboard",
"30": "30 min",
"60": "1 hr",
"90": "1 hr 30",
"120": "2 hr",
"180": "3 hr",
"240": "4 hr"
}
}
},
"sensor": {
+1
View File
@@ -8,6 +8,7 @@
"climate",
"diagnosis_status",
"energy_kwh",
"energy_saved_kwh",
"power_watts"
]
}
+2
View File
@@ -8,6 +8,7 @@
"delay_start_hours",
"diagnosis_status",
"energy_kwh",
"energy_saved_kwh",
"finish_time",
"firmware_update",
"heated_dry",
@@ -39,6 +40,7 @@
"samsung_dishwasher_diagnosis_start",
"samsung_dishwasher_diagnosis_status",
"samsung_dishwasher_energy_kwh",
"samsung_dishwasher_energy_saved_kwh",
"samsung_dishwasher_finish_time",
"samsung_dishwasher_firmware_update",
"samsung_dishwasher_heated_dry",
+8
View File
@@ -16,6 +16,9 @@
"door_cooler_open",
"door_freezer_open",
"energy_kwh",
"energy_last_month_kwh",
"energy_saved_kwh",
"energy_this_month_kwh",
"filter_status",
"filter_usage",
"firmware_update",
@@ -31,6 +34,7 @@
"icemaker_two_type",
"night_end",
"night_start",
"power_energy_kwh",
"power_watts",
"rapid_freezing",
"rapid_fridge",
@@ -56,6 +60,9 @@
"samsung_refrigerator_door_cooler_open",
"samsung_refrigerator_door_freezer_open",
"samsung_refrigerator_energy_kwh",
"samsung_refrigerator_energy_last_month_kwh",
"samsung_refrigerator_energy_saved_kwh",
"samsung_refrigerator_energy_this_month_kwh",
"samsung_refrigerator_filter_status",
"samsung_refrigerator_filter_usage",
"samsung_refrigerator_firmware_update",
@@ -71,6 +78,7 @@
"samsung_refrigerator_icemaker_two_type",
"samsung_refrigerator_night_end",
"samsung_refrigerator_night_start",
"samsung_refrigerator_power_energy_kwh",
"samsung_refrigerator_power_watts",
"samsung_refrigerator_rapid_freezing",
"samsung_refrigerator_rapid_fridge",
@@ -0,0 +1,28 @@
{
"state_keys": [
"alarm_code",
"autofill",
"cooler_setpoint",
"cooler_temperature",
"defrost_active",
"defrost_delay",
"diagnosis_status",
"door_cooler_open",
"door_freezer_open",
"energy_last_month_kwh",
"energy_this_month_kwh",
"filter_status",
"filter_usage",
"firmware_update",
"freezer_setpoint",
"freezer_temperature",
"icemaker_one_enabled",
"icemaker_one_making_status",
"pantry_zone_mode",
"power_energy_kwh",
"power_watts",
"rapid_freezing",
"rapid_fridge",
"sabbath_mode"
]
}
@@ -10,6 +10,9 @@
"door_cvroom_open",
"door_freezer_open",
"energy_kwh",
"energy_last_month_kwh",
"energy_saved_kwh",
"energy_this_month_kwh",
"filter_status",
"filter_usage",
"firmware_update",
@@ -20,6 +23,7 @@
"icemaker_one_making_status",
"icemaker_two_enabled",
"icemaker_two_making_status",
"power_energy_kwh",
"power_watts",
"rapid_freezing",
"rapid_fridge",
+29
View File
@@ -0,0 +1,29 @@
{
"state_keys": [
"alarm_code",
"cooler_setpoint",
"cooler_temperature",
"defrost_active",
"defrost_delay",
"diagnosis_status",
"door_cooler_open",
"door_cvroom_open",
"door_freezer_open",
"energy_kwh",
"energy_last_month_kwh",
"energy_this_month_kwh",
"filter_status",
"filter_usage",
"firmware_update",
"flex_zone_mode",
"freezer_setpoint",
"freezer_temperature",
"icemaker_one_enabled",
"icemaker_one_making_status",
"power_energy_kwh",
"power_watts",
"rapid_freezing",
"rapid_fridge",
"sabbath_mode"
]
}
+1
View File
@@ -11,6 +11,7 @@
"drum_clean_cycles_remaining",
"drum_clean_last_cleaned",
"energy_kwh",
"energy_saved_kwh",
"finish_time",
"firmware_update",
"job_beginning_status",
+26
View File
@@ -0,0 +1,26 @@
{
"state_keys": [
"alarm_code",
"child_lock",
"cycle",
"cycle_active",
"delay_start_hours",
"detergent_low",
"diagnosis_status",
"drum_clean_cycles_remaining",
"dry_level",
"energy_kwh",
"finish_time",
"firmware_update",
"job_beginning_status",
"machine_state",
"power_switch",
"progress",
"progress_percentage",
"remote_control",
"rinse_cycles",
"softener_low",
"spin_speed",
"wash_temperature"
]
}
+22
View File
@@ -0,0 +1,22 @@
{
"state_keys": [
"alarm_code",
"child_lock",
"cycle_active",
"delay_start_hours",
"detergent_low",
"diagnosis_status",
"drum_clean_cycles_remaining",
"energy_kwh",
"finish_time",
"job_beginning_status",
"machine_state",
"power_switch",
"progress",
"progress_percentage",
"remote_control",
"rinse_cycles",
"spin_speed",
"wash_temperature"
]
}
+351
View File
@@ -0,0 +1,351 @@
{
"device0": [
{
"rt": [
"x.com.samsung.devcol",
"oic.wk.col"
],
"if": [
"oic.if.baseline",
"oic.if.ll",
"oic.if.b"
]
},
{
"href": "/alarms/vs/0",
"rep": {}
},
{
"href": "/temperatures/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Freezer",
"x.com.samsung.da.desired": "-21",
"x.com.samsung.da.current": "-21",
"x.com.samsung.da.maximum": "-15",
"x.com.samsung.da.minimum": "-23",
"x.com.samsung.da.unit": "Celsius"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Fridge",
"x.com.samsung.da.desired": "2",
"x.com.samsung.da.current": "2",
"x.com.samsung.da.maximum": "7",
"x.com.samsung.da.minimum": "1",
"x.com.samsung.da.unit": "Celsius"
}
]
}
},
{
"href": "/temperature/current/freezer/0",
"rep": {
"range": [
-23.0,
-15.0
],
"units": "C",
"temperature": -21.0
}
},
{
"href": "/temperature/desired/freezer/0",
"rep": {
"range": [
-23.0,
-15.0
],
"units": "C",
"temperature": -21.0
}
},
{
"href": "/temperature/current/cooler/0",
"rep": {
"range": [
1.0,
7.0
],
"units": "C",
"temperature": 2.0
}
},
{
"href": "/temperature/desired/cooler/0",
"rep": {
"range": [
1.0,
7.0
],
"units": "C",
"temperature": 2.0
}
},
{
"href": "/diagnosis/vs/0",
"rep": {
"x.com.samsung.da.diagnosisStart": "Ready"
}
},
{
"href": "/energy/consumption/vs/0",
"rep": {
"x.com.samsung.da.cumulativeConsumption": "0",
"x.com.samsung.da.cumulativeUnit": "Wh",
"x.com.samsung.da.instantaneousPower": "0",
"x.com.samsung.da.instantaneousPowerUnit": "W",
"x.com.samsung.da.monthlyConsumption": "86000",
"x.com.samsung.da.thismonthlyConsumption": "64026"
}
},
{
"href": "/mode/vs/0",
"rep": {
"x.com.samsung.da.supportedModes": [
"HOMECARE_WIZARD_V2",
"ENERGY_REPORT_MODEL",
"18K_REF_OUTDOOR_CONTROL_V2",
"SUPPORT_SABBATH_CONTROL"
],
"x.com.samsung.da.modes": [
"WATERFILTER_ENABLE"
]
}
},
{
"href": "/mode/0",
"rep": {
"supportedModes": [
"HOMECARE_WIZARD_V2",
"ENERGY_REPORT_MODEL",
"18K_REF_OUTDOOR_CONTROL_V2",
"SUPPORT_SABBATH_CONTROL"
],
"modes": [
"WATERFILTER_ENABLE"
]
}
},
{
"href": "/defrost/block/vs/0",
"rep": {
"x.com.samsung.da.supportedModes": [
"DEFROST_BLOCK_ON",
"DEFROST_BLOCK_OFF"
],
"x.com.samsung.da.modes": [
"DEFROST_BLOCK_OFF"
]
}
},
{
"href": "/sabbath/vs/0",
"rep": {
"x.com.samsung.da.sabbathMode": "Off"
}
},
{
"href": "/realtimenotiforclient/vs/0",
"rep": {
"x.com.samsung.da.timeforshortnoti": "0",
"x.com.samsung.da.periodicnotisubscription": "true"
}
},
{
"href": "/information/vs/0",
"rep": {
"x.com.samsung.da.modelNum": "ARTIK051_REF_17K|00117141|0002074E051311200103000010000000",
"x.com.samsung.da.description": "ARTIK051_REF_17K",
"x.com.samsung.da.serialNum": "REDACTED",
"x.com.samsung.da.otnDUID": "REDACTED",
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "WiFi Module",
"x.com.samsung.da.type": "Software",
"x.com.samsung.da.number": "02144A201124",
"x.com.samsung.da.newVersionAvailable": "0"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Micom",
"x.com.samsung.da.type": "Firmware",
"x.com.samsung.da.number": "2003030C,FFFFFFFF",
"x.com.samsung.da.newVersionAvailable": "0"
}
]
}
},
{
"href": "/file/information/vs/0",
"rep": {
"x.com.samsung.timeoffset": "-04:00",
"x.com.samsung.supprtedtype": 1
}
},
{
"href": "/doors/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Door",
"x.com.samsung.da.openState": "Close"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Door",
"x.com.samsung.da.openState": "Close"
}
]
}
},
{
"href": "/door/freezer/0",
"rep": {
"openState": "Close"
}
},
{
"href": "/door/cooler/0",
"rep": {
"openState": "Close"
}
},
{
"href": "/configuration/vs/0",
"rep": {
"x.com.samsung.da.countryCode": "US",
"x.com.samsung.da.region": ""
}
},
{
"href": "/defrost/delay/0",
"rep": {
"value": false
}
},
{
"href": "/defrost/delay/vs/0",
"rep": {
"x.com.samsung.da.delayDefrost": "Off"
}
},
{
"href": "/defrost/reservation/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Summer Season",
"x.com.samsung.da.startTime": "0000-05-01T15:00:00",
"x.com.samsung.da.period": "04:00:00",
"x.com.samsung.da.endTime": "0000-10-31T00:00:00"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Winter Season",
"x.com.samsung.da.startTime": "0000-11-01T06:00:00",
"x.com.samsung.da.period": "04:00:00",
"x.com.samsung.da.endTime": "0000-04-30T00:00:00"
}
]
}
},
{
"href": "/icemaker/status/0",
"rep": {
"status": "On"
}
},
{
"href": "/icemaker/status/vs/0",
"rep": {
"x.com.samsung.da.iceMaker": "On"
}
},
{
"href": "/refrigeration/0",
"rep": {
"defrost": false,
"rapidFreeze": false,
"rapidCool": false
}
},
{
"href": "/refrigeration/vs/0",
"rep": {
"x.com.samsung.da.rapidFridge": "Off",
"x.com.samsung.da.rapidFreezing": "Off"
}
},
{
"href": "/drlc/0",
"rep": {
"DRLevel": 0,
"start": "00:00:00",
"duration": 0,
"override": false
}
},
{
"href": "/drlc/vs/0",
"rep": {
"x.com.samsung.da.drlcLevel": "0",
"x.com.samsung.da.duration": "00:00:00",
"x.com.samsung.da.drlcStartTime": "00:00:00",
"x.com.samsung.da.override": "Off"
}
},
{
"href": "/otninformation/vs/0",
"rep": {
"x.com.samsung.da.target": "Micom",
"x.com.samsung.da.newVersionAvailable": "false"
}
},
{
"href": "/filter/waterfilter/vs/0",
"rep": {
"x.com.samsung.da.filterUsage": "100",
"x.com.samsung.da.filterUsageResolution": "1",
"x.com.samsung.da.filterStatus": "replace",
"x.com.samsung.da.filterResetType": [
"replaceable"
]
}
},
{
"href": "/autofill/vs/0",
"rep": {
"x.com.samsung.da.autofill": "Off"
}
},
{
"href": "/icemaker/one/vs/0",
"rep": {
"x.com.samsung.da.iceMaker.name": "ICE_MAKER",
"x.com.samsung.da.iceMaker.state": "On",
"x.com.samsung.da.iceMaker.type": "toggle",
"x.com.samsung.da.iceMaker.iceMakingStatus": "ICESTATUS_STOP",
"x.com.samsung.da.iceType.desired": "NORMAL"
}
},
{
"href": "/status/pantry/one/vs/0",
"rep": {
"x.com.samsung.da.controllable": "true",
"x.com.samsung.da.name": "COOL_SELECT_ZONE",
"x.com.samsung.da.mode": "FDR_DRINKS",
"x.com.samsung.da.supportedOptions": [
"FDR_WINE",
"FDR_DELI",
"FDR_DRINKS"
]
}
}
]
}
+351
View File
@@ -0,0 +1,351 @@
{
"device0": [
{
"rt": [
"x.com.samsung.devcol",
"oic.wk.col"
],
"if": [
"oic.if.baseline",
"oic.if.ll",
"oic.if.b"
]
},
{
"href": "/alarms/vs/0",
"rep": {}
},
{
"href": "/temperatures/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Freezer",
"x.com.samsung.da.desired": "0",
"x.com.samsung.da.current": "0",
"x.com.samsung.da.maximum": "5",
"x.com.samsung.da.minimum": "-8",
"x.com.samsung.da.unit": "Fahrenheit"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Fridge",
"x.com.samsung.da.desired": "37",
"x.com.samsung.da.current": "37",
"x.com.samsung.da.maximum": "44",
"x.com.samsung.da.minimum": "34",
"x.com.samsung.da.unit": "Fahrenheit"
}
]
}
},
{
"href": "/temperature/current/freezer/0",
"rep": {
"range": [
-8.0,
5.0
],
"units": "F",
"temperature": 0.0
}
},
{
"href": "/temperature/desired/freezer/0",
"rep": {
"range": [
-8.0,
5.0
],
"units": "F",
"temperature": 0.0
}
},
{
"href": "/temperature/current/cooler/0",
"rep": {
"range": [
34.0,
44.0
],
"units": "F",
"temperature": 37.0
}
},
{
"href": "/temperature/desired/cooler/0",
"rep": {
"range": [
34.0,
44.0
],
"units": "F",
"temperature": 37.0
}
},
{
"href": "/diagnosis/vs/0",
"rep": {
"x.com.samsung.da.diagnosisStart": "Ready"
}
},
{
"href": "/energy/consumption/vs/0",
"rep": {
"x.com.samsung.da.cumulativeConsumption": "288048",
"x.com.samsung.da.cumulativePower": "1797027",
"x.com.samsung.da.cumulativeUnit": "Wh",
"x.com.samsung.da.instantaneousPower": "115",
"x.com.samsung.da.instantaneousPowerUnit": "W",
"x.com.samsung.da.monthlyConsumption": "55400",
"x.com.samsung.da.thismonthlyConsumption": "39737"
}
},
{
"href": "/mode/vs/0",
"rep": {
"x.com.samsung.da.supportedModes": [
"HOMECARE_WIZARD_V2",
"ENERGY_REPORT_MODEL",
"18K_REF_OUTDOOR_CONTROL_V2",
"SUPPORT_SABBATH_CONTROL"
],
"x.com.samsung.da.modes": [
"CVN_CONVERTIBLE_ZONE",
"CV_FDR_BEVERAGE",
"WATERFILTER_DISABLE"
],
"x.com.samsung.da.supportedOptions": [
"CV_FDR_WINE",
"CV_FDR_DELI",
"CV_FDR_BEVERAGE",
"CV_FDR_MEAT"
]
}
},
{
"href": "/mode/0",
"rep": {
"supportedModes": [
"HOMECARE_WIZARD_V2",
"ENERGY_REPORT_MODEL",
"18K_REF_OUTDOOR_CONTROL_V2",
"SUPPORT_SABBATH_CONTROL"
],
"modes": [
"CVN_CONVERTIBLE_ZONE",
"CV_FDR_BEVERAGE",
"WATERFILTER_DISABLE"
]
}
},
{
"href": "/defrost/block/vs/0",
"rep": {
"x.com.samsung.da.supportedModes": [
"DEFROST_BLOCK_ON",
"DEFROST_BLOCK_OFF"
],
"x.com.samsung.da.modes": [
"DEFROST_BLOCK_OFF"
]
}
},
{
"href": "/sabbath/vs/0",
"rep": {
"x.com.samsung.da.sabbathMode": "Off"
}
},
{
"href": "/realtimenotiforclient/vs/0",
"rep": {
"x.com.samsung.da.timeforshortnoti": "0",
"x.com.samsung.da.periodicnotisubscription": "true"
}
},
{
"href": "/information/vs/0",
"rep": {
"x.com.samsung.da.modelNum": "TP2X_REF_20K|00113141|0002033F051311200103000010000000",
"x.com.samsung.da.description": "TP2X_REF_20K",
"x.com.samsung.da.serialNum": "REDACTED",
"x.com.samsung.da.otnDUID": "REDACTED",
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "WiFi Module",
"x.com.samsung.da.type": "Software",
"x.com.samsung.da.number": "02144A220110",
"x.com.samsung.da.newVersionAvailable": "0"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Micom",
"x.com.samsung.da.type": "Firmware",
"x.com.samsung.da.number": "2011030E,FFFFFFFF",
"x.com.samsung.da.newVersionAvailable": "0"
}
]
}
},
{
"href": "/file/information/vs/0",
"rep": {
"x.com.samsung.timeoffset": "+00:00",
"x.com.samsung.supprtedtype": 1
}
},
{
"href": "/doors/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Door",
"x.com.samsung.da.openState": "Close"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Door",
"x.com.samsung.da.openState": "Close"
},
{
"x.com.samsung.da.id": "2",
"x.com.samsung.da.description": "Door",
"x.com.samsung.da.openState": "Close"
}
]
}
},
{
"href": "/door/freezer/0",
"rep": {
"openState": "Close"
}
},
{
"href": "/door/cooler/0",
"rep": {
"openState": "Close"
}
},
{
"href": "/door/cvroom/0",
"rep": {
"openState": "Close"
}
},
{
"href": "/configuration/vs/0",
"rep": {
"x.com.samsung.da.countryCode": "US",
"x.com.samsung.da.region": ""
}
},
{
"href": "/defrost/delay/0",
"rep": {
"value": false
}
},
{
"href": "/defrost/delay/vs/0",
"rep": {
"x.com.samsung.da.delayDefrost": "Off"
}
},
{
"href": "/defrost/reservation/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Summer Season",
"x.com.samsung.da.startTime": "0000-05-01T15:00:00",
"x.com.samsung.da.period": "04:00:00",
"x.com.samsung.da.endTime": "0000-10-31T00:00:00"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Winter Season",
"x.com.samsung.da.startTime": "0000-11-01T06:00:00",
"x.com.samsung.da.period": "04:00:00",
"x.com.samsung.da.endTime": "0000-04-30T00:00:00"
}
]
}
},
{
"href": "/icemaker/status/0",
"rep": {
"status": "On"
}
},
{
"href": "/icemaker/status/vs/0",
"rep": {
"x.com.samsung.da.iceMaker": "On"
}
},
{
"href": "/refrigeration/0",
"rep": {
"defrost": false,
"rapidFreeze": false,
"rapidCool": false
}
},
{
"href": "/refrigeration/vs/0",
"rep": {
"x.com.samsung.da.rapidFridge": "Off",
"x.com.samsung.da.rapidFreezing": "Off"
}
},
{
"href": "/drlc/0",
"rep": {
"DRLevel": 0,
"override": false
}
},
{
"href": "/drlc/vs/0",
"rep": {
"x.com.samsung.da.drlcLevel": "0",
"x.com.samsung.da.override": "Off",
"x.com.samsung.da.durationminutes": "0"
}
},
{
"href": "/otninformation/vs/0",
"rep": {
"x.com.samsung.da.target": "Micom",
"x.com.samsung.da.newVersionAvailable": "false"
}
},
{
"href": "/filter/waterfilter/vs/0",
"rep": {
"x.com.samsung.da.filterUsage": "0",
"x.com.samsung.da.filterUsageResolution": "1",
"x.com.samsung.da.filterStatus": "normal",
"x.com.samsung.da.filterResetType": [
"replaceable"
]
}
},
{
"href": "/icemaker/one/vs/0",
"rep": {
"x.com.samsung.da.iceMaker.name": "ICE_MAKER",
"x.com.samsung.da.iceMaker.state": "On",
"x.com.samsung.da.iceMaker.type": "toggle",
"x.com.samsung.da.iceMaker.iceMakingStatus": "ICESTATUS_STOP",
"x.com.samsung.da.iceType.desired": "NORMAL"
}
}
]
}
+325
View File
@@ -0,0 +1,325 @@
{
"device0": [
{
"rt": [
"x.com.samsung.devcol",
"oic.wk.col"
],
"if": [
"oic.if.baseline",
"oic.if.ll",
"oic.if.b"
]
},
{
"href": "/realtimenotiforclient/vs/0",
"rep": {
"x.com.samsung.da.timeforshortnoti": "0",
"x.com.samsung.da.periodicnotisubscription": "true"
}
},
{
"href": "/alarms/vs/0",
"rep": {}
},
{
"href": "/diagnosis/vs/0",
"rep": {
"x.com.samsung.da.diagnosisStart": "Ready"
}
},
{
"href": "/energy/consumption/vs/0",
"rep": {
"x.com.samsung.da.instantaneousPower": "-500",
"x.com.samsung.da.instantaneousPowerUnit": "W",
"x.com.samsung.da.cumulativePower": "1210200",
"x.com.samsung.da.cumulativeUnit": "Wh",
"x.com.samsung.da.cumulativeDate": "1784671200",
"x.com.samsung.da.cumulativeDateUTC": "1784667600"
}
},
{
"href": "/energy/consumption/0",
"rep": {}
},
{
"href": "/course/vs/0",
"rep": {
"x.com.samsung.da.supportedModes": [
"HOMECARE_WIZARD_V2"
],
"x.com.samsung.da.options": [
"DeviceType_0167",
"UpdateAllow_NotAllowed",
"Course_1C",
"AiOption_On",
"LaundryOutTime_0",
"AddWashSet_0",
"AddWashAvailable_7",
"AddWashIndicator_On",
"SeamlessControl_Enable",
"KidsLockBypass_On",
"WashingTimes_25",
"DrumCleanProposal_40",
"DrumCleanLog_2024-07-10T22:36:33|2024-09-12T21:37:17|2024-12-06T02:13:28|2025-03-04T20:40:47|2025-05-25T11:02:07|2025-08-17T19:48:10|2025-10-30T20:20:13|2026-01-08T21:44:02|2026-04-02T21:17:40|2026-06-08T19:51:07",
"DetergentOnce_1",
"DetergentLeft_0",
"DetergentBase_5",
"DetergentAlarm_Off",
"DetergentType_2",
"DetergentTotal_49",
"SoftenerOnce_0",
"SoftenerLeft_0",
"SoftenerBase_0",
"SoftenerAlarm_Off",
"SoftenerType_0",
"SoftenerTotal_0",
"SpecialFunction_4",
"AvailableDelayTime_159",
"BubbleSoak_Off",
"LaundryPlannerUserSetTime_0",
"ProgressTimeSet_420BF48204D4A204F5",
"SendToDevice_Off",
"GMT_02",
"LaundryPlannerMicomSetTime_1704",
"PreWashSetting_Off",
"IntensiveSetting_Off",
"BubbleSoakSet_00F000F000F000F0F0F0F00000F000F0F00000F000000000",
"EnergyLevelSet_05030401040104020404020503020202030301010505050405",
"MostUsed_1C8410923FA67FB01F0000000000",
"PreWashAvailableSet_F0F000F0F0F000F0F0F0F00000F0F0F0F00000F000000000",
"IntensiveAvailableSet_F0F000F0F0F000F0F0F0F00000F0F0F0F00000F000000000",
"GeoFenceAlarm",
"UsagesDB_ok",
"EnergyKW_396",
"DrumCleanLog_2024-07-10T22:36:33|2024-09-12T21:37:17|2024-12-06T02:13:28|2025-03-04T20:40:47|2025-05-25T11:02:07|2025-08-17T19:48:10|2025-10-30T20:20:13|2026-01-08T21:44:02|2026-04-02T21:17:40|2026-06-08T19:51:07",
"TimeSync_NotSupported"
],
"x.com.samsung.da.supportedOptions": [
"41C8410923FA67FB01F1B847E923FA67FB01F1E811E933FA53FB01F1D841E923FA67FB01F1F8102923FA57FB01F25843E923FA57FB01F26841E920FA207B01F33857E933FA67FB00024841E930FA30FB00032833E923FA37FB00020857E943FA67FB01F22841E920FA30FB00023831E930FA57FB01F2F831E933FA30FB00021831E943FA57FB0002D841E923FA30FB00030843E923FA67FB000278000913FA67FB01F2880009000A67EB01F368410923FA640B11E3880009000A000B11E3980009000A000B11E3780009000A000B0002985209204A520B000"
]
}
},
{
"href": "/power/vs/0",
"rep": {
"x.com.samsung.da.power": "Off"
}
},
{
"href": "/power/0",
"rep": {
"value": false
}
},
{
"href": "/cycleinterface/vs/0",
"rep": {}
},
{
"href": "/kidslock/vs/0",
"rep": {
"x.com.samsung.da.kidsLock": "Ready"
}
},
{
"href": "/kidslock/0",
"rep": {
"value": false
}
},
{
"href": "/operational/state/vs/0",
"rep": {
"x.com.samsung.da.state": "Ready",
"x.com.samsung.da.remainingTime": "02:39:00",
"x.com.samsung.da.progressPercentage": "1",
"x.com.samsung.da.progress": "None",
"x.com.samsung.da.delayEndTime": "00:00:00",
"x.com.samsung.da.supportedProgress": [
"None",
"Weightsensing",
"Wash",
"Rinse",
"Spin",
"Finish"
]
}
},
{
"href": "/operational/state/0",
"rep": {
"currentMachineState": "**REDACTED**",
"machineStates": "**REDACTED**",
"jobStates": [
"None",
"Weightsensing",
"Wash",
"Rinse",
"Spin",
"Finish"
],
"currentJobState": "None",
"remainingTime": "02:39:00",
"progressPercentage": "1"
}
},
{
"href": "/information/vs/0",
"rep": {
"x.com.samsung.da.modelNum": "DA_WM_TP2_20_COMMON|20260041|20010102011411B402A3020700000000",
"x.com.samsung.da.description": "DA_WM_TP2_20_COMMON_WW6600R/DC92-02617A_5049",
"x.com.samsung.da.serialNum": "REDACTED",
"x.com.samsung.da.otnDUID": "REDACTED",
"x.com.samsung.da.diagProtocolType": "WIFI_HTTPS",
"x.com.samsung.da.diagLogType": [
"errCode",
"dump"
],
"x.com.samsung.da.diagDumpType": "file",
"x.com.samsung.da.diagEndPoint": "SSM",
"x.com.samsung.da.diagMnid": "0AJT",
"x.com.samsung.da.diagSetupid": "210",
"x.com.samsung.da.diagMinVersion": "1.0",
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "DA_WM_TP2_20_COMMON|20260041|20010102011411B402A3020700000000",
"x.com.samsung.da.type": "Software",
"x.com.samsung.da.number": "02674A250414(F546)",
"x.com.samsung.da.newVersionAvailable": "0"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Firmware_1_DB_20260041200911390FFFFF202617412101203104FFFF(01672026004120261741_30000000)(FileDown:0)(Type:0)",
"x.com.samsung.da.type": "Firmware",
"x.com.samsung.da.number": "20091139,21012031",
"x.com.samsung.da.newVersionAvailable": "0"
},
{
"x.com.samsung.da.id": "2",
"x.com.samsung.da.description": "Firmware_2_DB_2025984120072205042FFFFFFFFFFFFFFFFFFFFFFFFE(016720259841FFFFFFFF_30000000)(FileDown:0)(Type:0)",
"x.com.samsung.da.type": "Firmware",
"x.com.samsung.da.number": "20072205,FFFFFFFF"
}
]
}
},
{
"href": "/file/information/vs/0",
"rep": {
"x.com.samsung.timeoffset": "+01:00"
}
},
{
"href": "/washer/vs/0",
"rep": {
"x.com.samsung.da.waterTemperature": "40",
"x.com.samsung.da.supportedWaterTemperature": [
"None",
"Cold",
"20",
"30",
"40",
"60",
"90"
],
"x.com.samsung.da.spinLevel": "1400",
"x.com.samsung.da.supportedSpinLevel": [
"RinseHold",
"NoSpin",
"400",
"800",
"1000",
"1200",
"1400"
],
"x.com.samsung.da.dryLevel": "None",
"x.com.samsung.da.supportedDryLevel": [
"None",
"Cupboard",
"30",
"60",
"90",
"120",
"180",
"240"
],
"x.com.samsung.da.rinseCycles": "2",
"x.com.samsung.da.supportedRinseCycles": [
"0",
"1",
"2",
"3",
"4",
"5"
]
}
},
{
"href": "/st/washercourse/vs/0",
"rep": {
"x.com.samsung.da.st.washerMode": "Table_02_Course_1C",
"x.com.samsung.da.st.courseTable": "Table_02"
}
},
{
"href": "/setting/vs/0",
"rep": {
"x.com.samsung.da.supportedSetLanguage": [
"ko_KR",
"en_US"
],
"x.com.samsung.da.setLanguage": "en_GB"
}
},
{
"href": "/wm/editcourse/vs/0",
"rep": {
"x.com.samsung.da.editCourseList": "EditCourseList_1C3026241E293633281D27211B202F2223323825392D1F37",
"x.com.samsung.da.fixedCourseList": "FixedCourseList_1C353A29"
}
},
{
"href": "/wm/setinfo/vs/0",
"rep": {
"x.com.samsung.da.isModelSettingWithoutSC": "true",
"x.com.samsung.da.aiCourse": "true_formobile",
"x.com.samsung.da.isModelSettingPowerOnOff": "false"
}
},
{
"href": "/wm/jobbeginingstatus/vs/0",
"rep": {
"x.com.samsung.da.currentStatus": "None"
}
},
{
"href": "/otninformation/vs/0",
"rep": {
"x.com.samsung.da.target": "Micom",
"x.com.samsung.da.newVersionAvailable": "false"
}
},
{
"href": "/remotectrl/vs/0",
"rep": {
"x.com.samsung.da.remoteControlEnabled": "false"
}
},
{
"href": "/remotectrl/0",
"rep": {
"value": false
}
},
{
"href": "/configuration/vs/0",
"rep": {
"x.com.samsung.da.region": "0000000000",
"x.com.samsung.da.countryCode": "GB"
}
}
]
}
+253
View File
@@ -0,0 +1,253 @@
{
"device0": [
{
"rt": [
"x.com.samsung.devcol",
"oic.wk.col"
],
"if": [
"oic.if.baseline",
"oic.if.ll",
"oic.if.b"
]
},
{
"href": "/realtimenotiforclient/vs/0",
"rep": {
"x.com.samsung.da.timeforshortnoti": "0",
"x.com.samsung.da.periodicnotisubscription": "true"
}
},
{
"href": "/alarms/vs/0",
"rep": {}
},
{
"href": "/diagnosis/vs/0",
"rep": {
"x.com.samsung.da.diagnosisStart": "Ready"
}
},
{
"href": "/energy/consumption/vs/0",
"rep": {
"x.com.samsung.da.instantaneousPowerUnit": "W",
"x.com.samsung.da.instantaneousPower": "-500",
"x.com.samsung.da.cumulativePower": "199200",
"x.com.samsung.da.cumulativeUnit": "Wh",
"x.com.samsung.da.cumulativeDate": "1784631600",
"x.com.samsung.da.cumulativeDateUTC": "1784646000"
}
},
{
"href": "/energy/consumption/0",
"rep": {}
},
{
"href": "/course/vs/0",
"rep": {
"x.com.samsung.da.supportedModes": [
"HOMECARE_WIZARD_V2"
],
"x.com.samsung.da.options": [
"DeviceType_0146",
"UpdateAllow_NotAllowed",
"Course_A5",
"LaundryOutTime_0",
"AddGarmentIndicator_Off",
"SteamWash_Enable",
"SeamlessControl_Disable",
"KidsLockBypass_On",
"WashingTimes_14",
"DrumCleanProposal_40",
"DetergentOnce_0",
"DetergentLeft_0",
"DetergentBase_0",
"DetergentAlarm_Off",
"DetergentType_0",
"DetergentTotal_0",
"SpecialFunction_4",
"AvailableDelayTime_124",
"LaundryPlannerUserSetTime_0",
"ProgressTimeSet_4210E08209F6A2021C",
"EnergyLevelSet_0502040502030302030105",
"UsagesDB_ok",
"EnergyKW_396",
"DrumCleanLog_2023-08-11T19:17:11|2023-11-02T03:23:13|2023-12-22T22:35:54|2024-04-08T01:27:32|2024-04-22T01:07:26|2024-10-02T19:16:45|2025-02-03T02:01:33|2025-06-16T17:36:13|2026-01-04T18:34:46|2026-05-26T02:33:16",
"TimeSync_NotSupported"
],
"x.com.samsung.da.supportedOptions": [
"301833EA41BC20E9C843EA41FC30EA98520A41FC20EA2810EA207C20EAA831EA41FC20EA5830EA20FC20E9F831EA41FC10E9E830EA21FC20E9D8000A41FC000B18520A410C000"
]
}
},
{
"href": "/power/vs/0",
"rep": {
"x.com.samsung.da.power": "On"
}
},
{
"href": "/power/0",
"rep": {
"value": true
}
},
{
"href": "/cycleinterface/vs/0",
"rep": {}
},
{
"href": "/kidslock/vs/0",
"rep": {
"x.com.samsung.da.kidsLock": "Ready"
}
},
{
"href": "/kidslock/0",
"rep": {
"value": false
}
},
{
"href": "/operational/state/vs/0",
"rep": {
"x.com.samsung.da.state": "Ready",
"x.com.samsung.da.remainingTime": "02:04:00",
"x.com.samsung.da.progressPercentage": "1",
"x.com.samsung.da.progress": "None",
"x.com.samsung.da.delayEndTime": "00:00:00",
"x.com.samsung.da.supportedProgress": [
"None",
"Wash",
"Rinse",
"Spin",
"Finish"
]
}
},
{
"href": "/operational/state/0",
"rep": {
"currentMachineState": "**REDACTED**",
"machineStates": "**REDACTED**",
"jobStates": [
"None",
"Wash",
"Rinse",
"Spin",
"Finish"
],
"currentJobState": "None",
"remainingTime": "02:04:00",
"progressPercentage": "1"
}
},
{
"href": "/information/vs/0",
"rep": {
"x.com.samsung.da.modelNum": "DA_WM_A51_20_COMMON|20198042|20020001001111400203000000000000",
"x.com.samsung.da.description": "DA_WM_A51_20_COMMON_WV9600M/DC92-01980B_0014",
"x.com.samsung.da.serialNum": "REDACTED",
"x.com.samsung.da.otnDUID": "REDACTED",
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "DA_WM_A51_20_COMMON|20198042|20020001001111400203000000000000",
"x.com.samsung.da.type": "Software",
"x.com.samsung.da.number": "02198A230708(E257)",
"x.com.samsung.da.newVersionAvailable": "0"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "DA_WM_A51_20_COMMON",
"x.com.samsung.da.type": "Firmware",
"x.com.samsung.da.number": "18030902,18090603",
"x.com.samsung.da.newVersionAvailable": "0"
}
]
}
},
{
"href": "/file/information/vs/0",
"rep": {
"x.com.samsung.timeoffset": "-04:00"
}
},
{
"href": "/washer/vs/0",
"rep": {
"x.com.samsung.da.waterTemperature": "Warm",
"x.com.samsung.da.supportedWaterTemperature": [
"None",
"Cold",
"Cool",
"Warm",
"Hot",
"ExtraHot"
],
"x.com.samsung.da.spinLevel": "Low",
"x.com.samsung.da.supportedSpinLevel": [
"RinseHold",
"NoSpin",
"Low",
"Medium",
"High"
],
"x.com.samsung.da.soilLevel": "Heavy",
"x.com.samsung.da.supportedSoilLevel": [
"None",
"Light",
"Normal",
"Heavy"
],
"x.com.samsung.da.rinseCycles": "3"
}
},
{
"href": "/st/washercourse/vs/0",
"rep": {
"x.com.samsung.da.st.washerMode": "Table_00_Course_A5",
"x.com.samsung.da.st.courseTable": "Table_00"
}
},
{
"href": "/setting/vs/0",
"rep": {}
},
{
"href": "/wm/editcourse/vs/0",
"rep": {}
},
{
"href": "/wm/setinfo/vs/0",
"rep": {
"x.com.samsung.da.isModelSettingWithoutSC": "false",
"x.com.samsung.da.isModelSettingPowerOnOff": "false"
}
},
{
"href": "/wm/jobbeginingstatus/vs/0",
"rep": {}
},
{
"href": "/remotectrl/vs/0",
"rep": {
"x.com.samsung.da.remoteControlEnabled": "true"
}
},
{
"href": "/remotectrl/0",
"rep": {
"value": true
}
},
{
"href": "/configuration/vs/0",
"rep": {
"x.com.samsung.da.region": "0000000000",
"x.com.samsung.da.countryCode": "US"
}
}
]
}
+10
View File
@@ -190,6 +190,16 @@ class TestForDeviceByModel:
assert reg is not None
assert reg.name == 'washer'
def test_washer_wv_prefix(self):
"""FlexWash twin washers use the WV consumer-model prefix -- issue #19."""
from custom_components.localthings.registry.by_type import for_device_by_model
reg = for_device_by_model(
'DA_WM_A51_20_COMMON|20198042|20020001001111400203000000000000',
'DA_WM_A51_20_COMMON_WV9600M/DC92-01980B_0014',
)
assert reg is not None
assert reg.name == 'washer'
def test_unknown_model_returns_none(self):
from custom_components.localthings.registry.by_type import for_device_by_model
reg = for_device_by_model('SOME-UNKNOWN-BOARD', 'SOME-UNKNOWN-BOARD')
+94
View File
@@ -104,6 +104,43 @@ class TestRefrigerationFallback:
assert desc.exists_fn({}, {'/refrigeration/0': {}}) is True
class TestFlexZone:
"""Issue #32 (surfaced by #26/#27's TP2X/Bespoke dumps): the flex-zone
entry's prefix varies by fridge family (CV_TTYPE_RF9000A_ on RF9000-class,
CV_FDR_ on TP1X/Bespoke-class). The old hardcoded-prefix match left
CV_FDR_-family fridges with an always-unknown select, and a write would
have appended a duplicate flag instead of replacing the existing one."""
def test_reads_rf9000_prefix(self):
rep = {
'x.com.samsung.da.modes': ['CV_TTYPE_RF9000A_BEVERAGE', 'WATERFILTER_DISABLE'],
'x.com.samsung.da.supportedOptions': [
'CV_TTYPE_RF9000A_FREEZE', 'CV_TTYPE_RF9000A_BEVERAGE'],
}
assert fridge._flex_zone_current(rep) == 'CV_TTYPE_RF9000A_BEVERAGE'
def test_reads_cv_fdr_prefix(self):
rep = {
'x.com.samsung.da.modes': ['CVN_CONVERTIBLE_ZONE', 'CV_FDR_MEAT', 'WATERFILTER_ENABLE'],
'x.com.samsung.da.supportedOptions': [
'CV_FDR_WINE', 'CV_FDR_DELI', 'CV_FDR_BEVERAGE', 'CV_FDR_MEAT'],
}
assert fridge._flex_zone_current(rep) == 'CV_FDR_MEAT'
def test_write_replaces_rather_than_duplicates(self):
rep = {
'x.com.samsung.da.modes': ['CVN_CONVERTIBLE_ZONE', 'CV_FDR_MEAT', 'WATERFILTER_ENABLE'],
'x.com.samsung.da.supportedOptions': [
'CV_FDR_WINE', 'CV_FDR_DELI', 'CV_FDR_BEVERAGE', 'CV_FDR_MEAT'],
}
path, payload = fridge._flex_zone_write('CV_FDR_WINE', rep)
assert path == ['mode', 'vs', '0']
modes = payload['x.com.samsung.da.modes']
assert modes.count('CV_FDR_WINE') == 1
assert 'CV_FDR_MEAT' not in modes
assert 'CVN_CONVERTIBLE_ZONE' in modes and 'WATERFILTER_ENABLE' in modes
class TestTp1xNativeDuplicateResources:
"""The US TP1X_REF_21K publishes two native mirrors in addition to the
richer vendor resources. They must count as covered without producing
@@ -134,3 +171,60 @@ class TestTp1xNativeDuplicateResources:
assert 'ice_maker_enabled' not in state
assert state['icemaker_one_enabled'] is True
assert state['icemaker_two_enabled'] is True
class TestPantryZone:
"""Cool Select Zone pantry compartment on ARTIK051_REF_17K -- issue #20."""
def test_href(self):
assert fridge.PANTRY_ZONE.href == '/status/pantry/one/vs/0'
def test_write(self):
desc = fridge.PANTRY_ZONE.entities[0]
path, body = desc.write_fn('FDR_WINE', {})
assert path == ['status', 'pantry', 'one', 'vs', '0']
assert body == {'x.com.samsung.da.mode': 'FDR_WINE'}
class TestArtik051AndTp2xFixturesHaveCompleteCoverage:
"""issue #20 (ARTIK051_REF_17K) and #26 (TP2X_REF_20K) both triggered
the incomplete-capability-coverage repair; both must resolve to zero
unbound hrefs now that /diagnosis/vs/0 (dishwasher.DIAGNOSIS, reused for
fridges), /status/pantry/one/vs/0 (PANTRY_ZONE), and the OCF-native
defrost/icemaker mirrors are covered."""
def test_artik051_ref_17k(self):
from custom_components.localthings.registry.adapter import flatten
from custom_components.localthings.registry.by_type import refrigerator
from custom_components.localthings.registry.discovery import discover
from tests.conftest import _load_device
resources = _load_device('refrigerator_artik051_ref_17k')
unbound = []
bound = discover(
resources,
refrigerator.REGISTRY.capabilities,
refrigerator.REGISTRY.pattern_capabilities,
log=unbound.append,
)
assert unbound == []
state = flatten(bound, resources)
assert state['pantry_zone_mode'] == 'FDR_DRINKS'
def test_tp2x_ref_20k(self):
from custom_components.localthings.registry.adapter import flatten
from custom_components.localthings.registry.by_type import refrigerator
from custom_components.localthings.registry.discovery import discover
from tests.conftest import _load_device
resources = _load_device('refrigerator_tp2x_ref_20k')
unbound = []
bound = discover(
resources,
refrigerator.REGISTRY.capabilities,
refrigerator.REGISTRY.pattern_capabilities,
log=unbound.append,
)
assert unbound == []
state = flatten(bound, resources)
assert state['flex_zone_mode'] == 'CV_FDR_BEVERAGE'
+58
View File
@@ -95,6 +95,64 @@ def test_registry_reproduces_golden_state_keys_for_tp1x_ref_21k_us():
)
def test_registry_reproduces_golden_state_keys_for_washer_flexwash():
"""FlexWash twin washers (WV-prefix consumer model, e.g. WV55M9600AW)
report no oneUiVersion and previously fell through for_device_by_model's
consumer-prefix map entirely -- issue #19."""
from tests.conftest import _load_device
resources = _load_device('washer_flexwash')
golden = json.loads((GOLDEN / 'washer_flexwash.json').read_text())
state_keys = _new_state_keys('washer_flexwash', resources)
assert set(state_keys) == set(golden['state_keys']), (
f"state_keys mismatch:\n"
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
f" missing: {sorted(set(golden['state_keys']) - set(state_keys))}"
)
def test_registry_reproduces_golden_state_keys_for_washer_dryer_combo():
"""Washer/dryer combo units carry a writable dryLevel field on
/washer/vs/0 itself, with no separate dryer resource -- issue #22."""
from tests.conftest import _load_device
resources = _load_device('washer_dryer_combo')
golden = json.loads((GOLDEN / 'washer_dryer_combo.json').read_text())
state_keys = _new_state_keys('washer_dryer_combo', resources)
assert set(state_keys) == set(golden['state_keys']), (
f"state_keys mismatch:\n"
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
f" missing: {sorted(set(golden['state_keys']) - set(state_keys))}"
)
def test_registry_reproduces_golden_state_keys_for_artik051_ref_17k():
"""ARTIK051_REF_17K's Cool Select Zone pantry compartment
(/status/pantry/one/vs/0) -- issue #20."""
from tests.conftest import _load_device
resources = _load_device('refrigerator_artik051_ref_17k')
golden = json.loads((GOLDEN / 'refrigerator_artik051_ref_17k.json').read_text())
state_keys = _new_state_keys('refrigerator_artik051_ref_17k', resources)
assert set(state_keys) == set(golden['state_keys']), (
f"state_keys mismatch:\n"
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
f" missing: {sorted(set(golden['state_keys']) - set(state_keys))}"
)
def test_registry_reproduces_golden_state_keys_for_tp2x_ref_20k():
"""TP2X_REF_20K -- CV_FDR_-prefixed flex zone (issue #32) plus the extra
energy fields (cumulativeConsumption/monthlyConsumption/
thismonthlyConsumption) surfaced by issue #26."""
from tests.conftest import _load_device
resources = _load_device('refrigerator_tp2x_ref_20k')
golden = json.loads((GOLDEN / 'refrigerator_tp2x_ref_20k.json').read_text())
state_keys = _new_state_keys('refrigerator_tp2x_ref_20k', resources)
assert set(state_keys) == set(golden['state_keys']), (
f"state_keys mismatch:\n"
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
f" missing: {sorted(set(golden['state_keys']) - set(state_keys))}"
)
def test_resources_from_batch_preferred_over_flat():
from tests.conftest import _resources_from_dump
dump = {
+59
View File
@@ -40,6 +40,22 @@ class TestWasherSettings:
assert body == {'x.com.samsung.da.rinseCycles': '3'}
class TestDryLevel:
"""Washer/dryer combo units carry a writable dryLevel field on
/washer/vs/0 itself, self-gated off on plain washers -- issue #22."""
def test_exists_only_when_supported_dry_level_present(self):
desc = next(e for e in washer.WASHER_SETTINGS.entities if e.key == 'dry_level')
assert desc.exists_fn({'x.com.samsung.da.supportedDryLevel': ['None', '30']}, {}) is True
assert desc.exists_fn({}, {}) is False
def test_write(self):
desc = next(e for e in washer.WASHER_SETTINGS.entities if e.key == 'dry_level')
path, body = desc.write_fn('Cupboard', {})
assert path == ['washer', 'vs', '0']
assert body == {'x.com.samsung.da.dryLevel': 'Cupboard'}
class TestWasherCourse:
def test_href(self):
assert washer.WASHER_COURSE.href == '/course/vs/0'
@@ -233,3 +249,46 @@ class TestDetergentSoftenerDosing:
assert self._desc('detergent_low').exists_fn({'x.com.samsung.da.options': []}, {}) is False
rep = {'x.com.samsung.da.options': _DOSING_OPTIONS}
assert self._desc('detergent_low').exists_fn(rep, {}) is True
class TestFlexWashAndComboFixturesHaveCompleteCoverage:
"""FlexWash (issue #19, previously unrecognized entirely) and
washer/dryer combo (issue #22, dry_level) dumps must both resolve to
zero unbound hrefs."""
def test_flexwash(self):
from custom_components.localthings.registry.adapter import flatten
from custom_components.localthings.registry.by_type import washer as washer_registry
from custom_components.localthings.registry.discovery import discover
from tests.conftest import _load_device
resources = _load_device('washer_flexwash')
unbound = []
bound = discover(
resources,
washer_registry.REGISTRY.capabilities,
washer_registry.REGISTRY.pattern_capabilities,
log=unbound.append,
)
assert unbound == []
state = flatten(bound, resources)
assert 'dry_level' not in state # plain washer -- no supportedDryLevel field
def test_dryer_combo(self):
from custom_components.localthings.registry.adapter import flatten
from custom_components.localthings.registry.by_type import washer as washer_registry
from custom_components.localthings.registry.discovery import discover
from tests.conftest import _load_device
resources = _load_device('washer_dryer_combo')
unbound = []
bound = discover(
resources,
washer_registry.REGISTRY.capabilities,
washer_registry.REGISTRY.pattern_capabilities,
log=unbound.append,
)
assert unbound == []
state = flatten(bound, resources)
# the device's own "off" sentinel is the literal string 'None', not absence
assert state['dry_level'] == 'None'