review: address Opus code-review findings on this branch

- config_flow: the #192 port-rescue made the "every port refused" fast-fail
  permanently unreachable (PREFERRED_PROBE_PORTS is always non-empty and
  always rescued), so removed the dead branch instead of leaving it as
  misleading dead code. A dead host now fails via the handshake loop's own
  error, which carries the real per-port reason.
- oven._has_option: added the is_stub_rep carve-out cooktop.py's identical
  per-token exists_fn already has on the same kind of href, so a not-yet
  sub-polled /mode/vs/0 doesn't permanently exclude energy_saving/
  cooktop_on_alert before their first real fetch lands.
- airconditioner.ENERGY_METER_LEGACY: build via dataclasses.replace() like
  its ENERGY_METER_GENERIC sibling, instead of hand-copying href/poll_tier
  (which would silently drift if common.ENERGY_METER ever gains a field).
- Fixed two stale comments: is_legacy_board()'s docstring still listed
  Volume among tokens needing legacy-only gating, though 'beep' now applies
  unconditionally across board generations; and common.py's UNIVERSAL
  invariant comment didn't mention that airconditioner also now excludes
  ENERGY_METER from the wholesale bundle.
- #191 (CAC token): added the fixture/golden/capability-test coverage the
  AVT token in the same branch got, including an honestly-documented list
  of the ten hrefs this board generation doesn't cover yet.
- fridge.cooler_temperature_setpoint: dropped the hardcoded "N °C" state
  labels -- the resource's own unit field isn't necessarily Celsius on a
  different model reporting the same href, and the options themselves are
  already read live via options_field, so a static per-value label risked
  asserting the wrong unit for a future device sharing this capability.
- airconditioner._legacy_cumulative_power_kwh: parse with float (matching
  common.wh_to_kwh's own numeric parsing) instead of this module's
  integer-only _int, so a decimal-formatted reading doesn't raise.
- test_config_flow: the port-rescue test bound the real 49154 directly,
  which could collide with an actually-running service on some machine;
  now monkeypatches PREFERRED_PROBE_PORTS to an OS-assigned port instead.
- oven.py: consolidated six byte-for-byte-identical single-token options
  write_fns (lamp/sound/fast_preheat/natural_steam/energy_saving/
  cooktop_on_alert) into one _option_switch_write(prefix) factory.

845 tests passing (up from 841 -- 4 new CAC coverage tests).
This commit is contained in:
Marc Billow committed 2026-07-29 18:04:23 +00:00
1 parent a003650d31
commit bd3ca80d3c
11 files changed
+1129 -117

No files matched your search

+919
View File
@@ -0,0 +1,919 @@
{
"device0": [
{
"rt": [
"x.com.samsung.devcol",
"oic.wk.col"
],
"if": [
"oic.if.baseline",
"oic.if.ll",
"oic.if.b"
]
},
{
"href": "/airlevelcheck/vs/0",
"rep": {
"x.com.samsung.da.periodicSensingInterval": "1800",
"x.com.samsung.da.sensingState": "NonProcessing",
"x.com.samsung.da.lastSensingTime": "1785327477",
"x.com.samsung.da.lastSensingLevel": "Kr1",
"x.com.samsung.da.periodicSensingSkipStatus": "Off",
"x.com.samsung.da.periodicSensingSkipTime": "00000000",
"x.com.samsung.da.periodicSensingActivationState": "On",
"x.com.samsung.da.autoExeState": "Alarm",
"x.com.samsung.da.supportedAutoExeState": [
"Airpurify",
"Alarm",
"Sensing"
],
"x.com.samsung.da.startSensingOnce": "Off",
"x.com.samsung.da.autoExeSetting": "On",
"x.com.samsung.da.supportedAutoExeSetting": [
"On",
"Off"
]
}
},
{
"href": "/aisleep/vs/0",
"rep": {
"x.com.samsung.da.displayNightMode": "Off",
"x.com.samsung.da.elapsedTime": "0",
"x.com.samsung.da.requestFeedback": "Off",
"x.com.samsung.da.resultFeedback": 0,
"x.com.samsung.da.statusFeedback": "Idle",
"x.com.samsung.da.sleepTime": "14002200"
}
},
{
"href": "/alarms/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.alarmType": "Device",
"x.com.samsung.da.code": "ErrorCode_OFF",
"x.com.samsung.da.triggeredTime": "2026-07-29T12:19:55",
"x.com.samsung.da.state": "Deleted"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.alarmType": "Device",
"x.com.samsung.da.code": "FilterAlarm_OFF",
"x.com.samsung.da.triggeredTime": "2026-07-29T12:19:55",
"x.com.samsung.da.state": "Deleted"
},
{
"x.com.samsung.da.id": "2",
"x.com.samsung.da.alarmType": "Device",
"x.com.samsung.da.code": "DA_SAC_M_OFF",
"x.com.samsung.da.triggeredTime": "2026-07-29T12:19:55",
"x.com.samsung.da.state": "Deleted"
}
],
"rt": [
"x.com.samsung.da.alarms"
],
"if": [
"oic.if.baseline",
"oic.if.a"
]
}
},
{
"href": "/availablecontrolsets/vs/0",
"rep": {
"x.com.samsung.da.sets": "000100B4012C0000B20001000000",
"x.com.samsung.da.id": "CAC",
"x.com.samsung.da.version": "1.0"
}
},
{
"href": "/configuration/vs/0",
"rep": {
"x.com.samsung.da.region": "4146100000",
"x.com.samsung.da.airconOptionList": [
"AI_KOREA_COOLONLY_4.0",
"HOMECARE_WIZARD_V2",
"CLEAN_OPTION_SUPPORT",
"DR",
"SingleCommand_1"
]
}
},
{
"href": "/da/softreset/vs/0",
"rep": {
"x.com.samsung.da.softwarereset": "false"
}
},
{
"href": "/drlc/vs/0",
"rep": {
"x.com.samsung.da.start": "2026-07-29T07:26:56Z",
"x.com.samsung.da.override": "Off",
"x.com.samsung.da.durationminutes": "1019",
"x.com.samsung.da.drlcLevel": "1",
"x.com.samsung.da.realSaving": "Off"
}
},
{
"href": "/edgelighting/vs/0",
"rep": {
"status": "On",
"convenientMode": "On",
"operatingOption": "On",
"welcomeLightStatus": "Off",
"colorOption": "3000K",
"mode": "Smart",
"modeSupportedList": [
"Smart",
"High",
"Low"
],
"colorSupportedList": [
"3000K",
"4000K",
"6500K"
]
}
},
{
"href": "/energy/consumption/vs/0",
"rep": {
"x.com.samsung.da.cumulativeDate": "1785327589",
"x.com.samsung.da.instantaneousPower": "15",
"x.com.samsung.da.cumulativeSavedPower": "1611",
"x.com.samsung.da.cumulativePower": "84044",
"x.com.samsung.da.cumulativeUnit": "Wh",
"x.com.samsung.da.instantaneousPowerUnit": "W",
"x.com.samsung.da.cumulativePowerType": "individual"
}
},
{
"href": "/file/information/vs/0",
"rep": {
"x.com.samsung.timeoffset": "+09:00",
"x.com.samsung.supprtedtype": 1
}
},
{
"href": "/filter/airdustPM1filter/vs/0",
"rep": {
"x.com.samsung.da.filterUsageResolution": "1",
"x.com.samsung.da.filterCapacity": "2400",
"x.com.samsung.da.filterCapacityUnit": "Hour",
"x.com.samsung.da.filterResetType": [
"washable"
],
"x.com.samsung.da.filterStatus": "normal",
"x.com.samsung.da.filterUsage": "11"
}
},
{
"href": "/filter/airdustfilter/vs/0",
"rep": {
"x.com.samsung.da.filterUsageResolution": "1",
"x.com.samsung.da.filterCapacity": "180",
"x.com.samsung.da.filterCapacityUnit": "Hour",
"x.com.samsung.da.filterResetType": [
"washable"
],
"x.com.samsung.da.filterStatus": "normal",
"x.com.samsung.da.filterUsage": "26"
}
},
{
"href": "/humidity/vs/0",
"rep": {
"x.com.samsung.da.humidity": "0",
"x.com.samsung.da.fivepercentHumidity": "59"
}
},
{
"href": "/information/vs/0",
"rep": {
"x.com.samsung.da.otnDUID": "**REDACTED**",
"x.com.samsung.da.modelNum": "TP1X_DA-AC-CAC-01001_0000|10255541|60030748171811DF42005F2A00F2ED00",
"x.com.samsung.da.description": "TP1X_DA-AC-CAC-01001_0000",
"x.com.samsung.da.serialNum": "**REDACTED**",
"x.com.samsung.da.serialNumOption": "**REDACTED**",
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Version",
"x.com.samsung.da.type": "Software",
"x.com.samsung.da.number": "02706A260401",
"x.com.samsung.da.newVersionAvailable": "0"
},
{
"x.com.samsung.da.id": "1",
"x.com.samsung.da.description": "Version",
"x.com.samsung.da.type": "Firmware",
"x.com.samsung.da.newVersionAvailable": "0",
"x.com.samsung.da.number": "02555A25052600,02556A24040200"
},
{
"x.com.samsung.da.id": "2",
"x.com.samsung.da.description": "Version",
"x.com.samsung.da.type": "Outdoor",
"x.com.samsung.da.newVersionAvailable": "0",
"x.com.samsung.da.number": "FFFFFFFFFFFFFF,FFFFFFFFFFFFFF"
}
],
"x.com.samsung.da.diagDumpType": "file",
"x.com.samsung.da.diagEndPoint": "SSM",
"x.com.samsung.da.diagLogType": [
"errCode",
"dump"
],
"x.com.samsung.da.diagMnid": "0AJT",
"x.com.samsung.da.diagSetupid": "AS3",
"x.com.samsung.da.diagProtocolType": "BLE_OCF",
"x.com.samsung.da.diagMinVersion": "3.0",
"x.com.samsung.da.diagTsId": "DA01"
}
},
{
"href": "/keepnormalstate/vs/0",
"rep": {
"x.com.samsung.da.keepnormal": 0
}
},
{
"href": "/light/stateful/vs/0",
"rep": {
"status": "On",
"mode": "Smart",
"supportedModes": [
"Smart",
"Low",
"High"
]
}
},
{
"href": "/mds/absenceclean/vs/0",
"rep": {
"mode": "Off",
"supportedModes": [
"On",
"Off"
]
}
},
{
"href": "/mds/absencemonitoring/vs/0",
"rep": {
"status": "Off"
}
},
{
"href": "/mds/absencepowersaving/vs/0",
"rep": {
"status": "On",
"modes": "Cooling",
"switchPowerSaveMode": "Normal",
"supportedModes": [
"Standby",
"Cooling"
],
"supportedSwitchPowerSaveMode": [
"Eco",
"Normal",
"Comfort"
]
}
},
{
"href": "/mds/absencestate/vs/0",
"rep": {
"status": "On",
"absenceTime": "0",
"maxDetectCount": [
"0",
"0",
"0",
"0",
"0",
"0",
"3",
"3",
"3",
"2",
"3",
"0",
"0",
"3",
"0",
"3",
"3",
"3",
"0",
"3",
"1",
"2",
"3",
"3",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"0",
"1",
"0",
"3",
"2",
"3",
"1",
"2",
"1",
"0",
"0",
"0",
"0"
],
"supportedTimes": [
"0",
"30",
"60",
"120"
]
}
},
{
"href": "/mode/convenient/vs/0",
"rep": {
"x.com.samsung.da.modes": "Off",
"x.com.samsung.da.supportedModes": [
"Off",
"Nano",
"LongWind",
"Speed",
"Sleep",
"NanoSleep"
]
}
},
{
"href": "/mode/vs/0",
"rep": {
"x.com.samsung.da.modes": [
"Cool"
],
"workingMode": "Cool",
"x.com.samsung.da.supportedModes": [
"AIComfort",
"Auto",
"Cool",
"Dry",
"Fan"
],
"x.com.samsung.da.options": [
"OptionCode_512",
"Sleep_0",
"ArtificialWorking_Off",
"ComfortAICooling_Off",
"AiTempChanged_Off",
"AiTemp_240",
"welcomecareElapsedTime_0",
"welcomecareThresholdTemp_0",
"welcomecareStartDate_0000",
"welcomecareEndDate_0000",
"welcomecareSeason_None",
"welcomecare_Off",
"DiagnosisAI_Off",
"ProgressDiagnosisAI_0",
"ResultDiagnosisAI_Normal",
"SmartCoolClean_Off",
"ProgressSmartClean_0",
"FreezeAlarmSetting_On",
"DesiredFreezeAlarm_112",
"ExtendOptionCode_0",
"UpdateAllow_NotAllowed",
"DurationOn_0",
"OutdoorTemp_55",
"KeyInputPermit_On",
"ModePermit_NoLimit"
],
"rt": [
"x.com.samsung.da.mode"
],
"if": [
"oic.if.baseline",
"oic.if.a"
],
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Temperature",
"x.com.samsung.da.current": "28.5",
"x.com.samsung.da.desired": "28.0",
"x.com.samsung.da.minimum": "18",
"x.com.samsung.da.maximum": "30",
"x.com.samsung.da.increment": "0.5",
"x.com.samsung.da.unit": "Celsius"
}
]
}
},
{
"href": "/option/airpurify/vs/0",
"rep": {
"x.com.samsung.da.modes": "Off",
"x.com.samsung.da.supportedModes": [
"On",
"Off"
]
}
},
{
"href": "/option/autoclean/vs/0",
"rep": {
"x.com.samsung.da.status": "Stop",
"x.com.samsung.da.supportedStatus": [
"Start",
"Stop"
],
"x.com.samsung.da.progress": "0",
"x.com.samsung.da.settingStatus": "On",
"x.com.samsung.da.supportedSettingStatus": [
"On",
"Off"
],
"defaultSettingStatus": "On"
}
},
{
"href": "/option/motiondetectwind/stateful/vs/0",
"rep": {
"status": "On",
"modes": "Indirect",
"supportedModes": [
"Indirect",
"Direct"
]
}
},
{
"href": "/option/muteonce/vs/0",
"rep": {
"muteonce": "Off"
}
},
{
"href": "/personality/presence/vs/0",
"rep": {}
},
{
"href": "/power/vs/0",
"rep": {
"x.com.samsung.da.power": "Off",
"operationNumber": "46"
}
},
{
"href": "/realtimenotiforclient/vs/0",
"rep": {
"x.com.samsung.da.timeforshortnoti": "0",
"x.com.samsung.da.longnotisubscription": "true",
"x.com.samsung.da.periodicnotisubscription": "true"
}
},
{
"href": "/remotedatacontrol/vs/0",
"rep": {
"x.com.samsung.da.status": "Off",
"x.com.samsung.da.connectionStatus": "Disconnected"
}
},
{
"href": "/remotetemperature/vs/0",
"rep": {
"x.com.samsung.da.temperature": "",
"x.com.samsung.da.unit": "",
"x.com.samsung.da.error": ""
}
},
{
"href": "/reserverulesets/vs/0",
"rep": {
"x.com.samsung.da.sets": "1F121E121E121E121EFFFFFFFF010001000F0001000E0000001C3E",
"x.com.samsung.da.id": "CAC",
"x.com.samsung.da.version": "1.0"
}
},
{
"href": "/sac/installationinfo/vs/0",
"rep": {
"installationOptions": [
{
"id": "0",
"option": "184449945E0484800017"
},
{
"id": "1",
"option": "28010000010000000100"
},
{
"id": "2",
"option": "50000000000000000001"
},
{
"id": "3",
"option": "30000000000000000000"
}
],
"installationDeviceNum": [
{
"id": "0",
"number": "0"
},
{
"id": "1",
"number": "5"
},
{
"id": "2",
"number": "0"
}
],
"outdoorInfo": [
{
"id": "0",
"info": "02571A250514",
"serial": "**REDACTED**"
},
{
"id": "1",
"info": "000000000000",
"serial": "**REDACTED**"
},
{
"id": "2",
"info": "000000000000",
"serial": "**REDACTED**"
},
{
"id": "3",
"info": "000000000000",
"serial": "**REDACTED**"
}
],
"mcuInfo": [
{
"id": "0",
"info": "000000000000"
},
{
"id": "1",
"info": "000000000000"
},
{
"id": "2",
"info": "000000000000"
},
{
"id": "3",
"info": "000000000000"
},
{
"id": "4",
"info": "000000000000"
},
{
"id": "5",
"info": "000000000000"
},
{
"id": "6",
"info": "000000000000"
},
{
"id": "7",
"info": "000000000000"
},
{
"id": "8",
"info": "000000000000"
},
{
"id": "9",
"info": "000000000000"
},
{
"id": "10",
"info": "000000000000"
},
{
"id": "11",
"info": "000000000000"
},
{
"id": "12",
"info": "000000000000"
},
{
"id": "13",
"info": "000000000000"
},
{
"id": "14",
"info": "000000000000"
}
]
}
},
{
"href": "/selfcheck/vs/0",
"rep": {
"x.com.samsung.da.start": "Cancel",
"x.com.samsung.da.status": "Ready",
"x.com.samsung.da.progress": "0",
"x.com.samsung.da.result": "NA",
"x.com.samsung.da.supportedActions": [
"Start",
"Cancel"
],
"x.com.samsung.da.error": [
"DA_ERROR_NONE"
]
}
},
{
"href": "/sensors/vs/0",
"rep": {
"x.com.samsung.da.cleanLevel": "1",
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Sensor for CleanLevel",
"x.com.samsung.da.type": "CleanLevel",
"x.com.samsung.da.value": [
"1"
]
},
{
"x.com.samsung.da.id": "2",
"x.com.samsung.da.description": "Sensor for Dust",
"x.com.samsung.da.type": "Dust",
"x.com.samsung.da.value": [
"7",
"1"
]
},
{
"x.com.samsung.da.id": "3",
"x.com.samsung.da.description": "Sensor for FineDust",
"x.com.samsung.da.type": "FineDust",
"x.com.samsung.da.value": [
"5",
"1"
]
},
{
"x.com.samsung.da.id": "4",
"x.com.samsung.da.description": "Sensor for SuperFineDust",
"x.com.samsung.da.type": "SuperFineDust",
"x.com.samsung.da.value": [
"5",
"1"
]
}
]
}
},
{
"href": "/settings/sound/mode/vs/0",
"rep": {
"mode": "voice",
"supportedModes": [
"mute",
"tone",
"voice"
]
}
},
{
"href": "/settings/sound/optimization/vs/0",
"rep": {
"status": "Off",
"supportedModes": [
"On",
"Off"
]
}
},
{
"href": "/settings/sound/output/vs/0",
"rep": {
"deviceType": "speaker"
}
},
{
"href": "/settings/sound/volume/vs/0",
"rep": {
"level": "2",
"minLevel": "0",
"maxLevel": "3",
"resolution": "1"
}
},
{
"href": "/smartsensingcooling/vs/0",
"rep": {
"status": "On",
"supportedModes": [
"On",
"Off"
]
}
},
{
"href": "/temperature/control/vs/0",
"rep": {
"x.com.samsung.da.increment": "0.5"
}
},
{
"href": "/temperatures/vs/0",
"rep": {
"x.com.samsung.da.items": [
{
"x.com.samsung.da.id": "0",
"x.com.samsung.da.description": "Temperature",
"x.com.samsung.da.current": "28.5",
"x.com.samsung.da.desired": "28.0",
"x.com.samsung.da.minimum": "18",
"x.com.samsung.da.maximum": "30",
"x.com.samsung.da.increment": "0.5",
"x.com.samsung.da.unit": "Celsius"
}
]
}
},
{
"href": "/uvled/vs/0",
"rep": {
"x.com.samsung.da.modes": "On",
"x.com.samsung.da.start": "Cancel",
"x.com.samsung.da.pushAlarmStatus": "Off",
"x.com.samsung.da.supportedModes": [
"On",
"Off"
]
}
},
{
"href": "/wind/direction/vs/0",
"rep": {
"x.com.samsung.da.modes": "Fix",
"x.com.samsung.da.supportedModes": [
"Left_And_Right",
"All"
]
}
},
{
"href": "/wind/strength/vs/0",
"rep": {
"x.com.samsung.da.modes": "0",
"x.com.samsung.da.supportedModes": [
"0",
"1",
"2",
"3"
],
"x.com.samsung.da.modesName": [
"Auto",
"Low",
"Mid",
"High"
]
}
},
{
"href": "/otninformation/vs/0",
"rep": {
"x.com.samsung.da.target": "",
"x.com.samsung.da.newVersionAvailable": "false",
"otnStatus": "None",
"flashingProgress": "0",
"otnCompleteDate": "noHistory",
"scheduledTime": "None",
"swVersionInfo": {
"platform": "Tizen Lite",
"oneUiVersion": "7.0 Air conditioner",
"osVersion": "4.0"
},
"otnList": [
{
"type": "WIFI",
"modelId": "ASA-WW-TP1-24-INFSAC",
"versions": [
"14260401"
],
"visVersion": "260401"
},
{
"type": "Micom",
"modelId": "04001025554110255641",
"versions": [
"25052600",
"24040200"
],
"visVersion": "250526"
},
{
"type": "Micom",
"modelId": "FGCAN2",
"versions": [
"",
""
],
"visVersion": "999999"
}
]
}
},
{
"href": "/timezone/vs/0",
"rep": {
"timezoneid": "Asia/Seoul",
"offset": "+09:00",
"DST": "OFF"
}
},
{
"href": "/connectionconfig/vs/0",
"rep": {
"autoReconnectionMinVersion": "1.0",
"autoReconnection": "true",
"autoReconnectionProtocolType": [
"helper_hotspot",
"ble_ocf"
],
"supportedWiFiAuthType": [
"OPEN",
"WEP",
"WPA-PSK",
"WPA2-PSK",
"SAE"
],
"supportedWiFiCryptoType": [
"TKIP",
"AES",
"WEP-64",
"WEP-128"
],
"supportedWiFiFreq": [
"2.4G"
],
"calmConnectionCare": {
"version": "1.0",
"role": [
"things"
]
}
}
},
{
"href": "/wirelessinfo/vs/0",
"rep": {
"macaddressWiFi": "**REDACTED**",
"macaddressBLE": "**REDACTED**",
"connectedApSsid": "boksil"
}
},
{
"href": "/quickcontrol/info/vs/0",
"rep": {
"supportedVersion": "1.0"
}
},
{
"href": "/dginformation/vs/0",
"rep": {
"enrolmentstatus": "Unknown",
"devicestate": "Unknown",
"lockstatus": "Unknown",
"nextduedate": "",
"workingminutes": 0,
"paymentinfo": {
"emiplan": "Unknown",
"currency": "Unknown",
"totalemi": 0,
"totalemipaid": 0
}
}
}
]
}
+30
View File
@@ -0,0 +1,30 @@
{
"state_keys": [
"absence_power_saving_active",
"absence_power_saving_mode",
"air_filter_status",
"air_filter_usage",
"air_filter_usage_hours",
"air_purify",
"alarm_code",
"auto_clean",
"clean_level",
"climate",
"current_temperature_c",
"dust",
"energy_kwh",
"energy_saved_kwh",
"fine_dust",
"firmware_update",
"humidity",
"motion_detect_wind_active",
"motion_detect_wind_mode",
"mute_once",
"power_watts",
"selfcheck_error",
"selfcheck_result",
"selfcheck_status",
"super_fine_dust",
"tropical_night_mode"
]
}
+21 -12
View File
@@ -106,35 +106,44 @@ def test_find_live_ports_detects_silent_port(socket_enabled) -> None:
def test_find_live_ports_rescues_preferred_ports_the_sweep_missed(
socket_enabled,
socket_enabled, monkeypatch,
) -> None:
"""Issue #192: a segregated VLAN made the ICMP-based sweep call three
closed ports live while missing the one port (49154, a historically
confirmed DTLS port) that nmap showed as genuinely open|filtered. The
sweep's verdict on a preferred port shouldn't be trusted blindly --
it must always come back as a candidate even if the sweep marked it
dead, so the config flow gets a real handshake attempt against it."""
closed ports live while missing the one port (a historically confirmed
DTLS port) that nmap showed as genuinely open|filtered. The sweep's
verdict on a preferred port shouldn't be trusted blindly -- it must
always come back as a candidate even if the sweep marked it dead, so the
config flow gets a real handshake attempt against it.
Uses an OS-assigned port monkeypatched into PREFERRED_PROBE_PORTS rather
than the real 49154/49155, so this doesn't depend on those specific
system ports being free on whatever machine runs the suite.
"""
import socket
from custom_components.localthings import config_flow
from custom_components.localthings.config_flow import _find_live_ports
# Bind and immediately close a socket on 49154 so loopback refuses
# datagrams to it -- standing in for the sweep wrongly ruling out a
# port we have strong prior evidence for.
# Bind an OS-assigned port and immediately close it, same technique
# test_find_live_ports_detects_silent_port uses for its "closed" ports --
# once closed, loopback refuses datagrams to it, standing in for the
# sweep wrongly ruling out a port we have strong prior evidence for.
reserved = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
reserved.bind(('127.0.0.1', 49154))
reserved.bind(('127.0.0.1', 0))
preferred_port = reserved.getsockname()[1]
reserved.close()
monkeypatch.setattr(config_flow, 'PREFERRED_PROBE_PORTS', [preferred_port])
live_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
live_sock.bind(('127.0.0.1', 0))
live_port = live_sock.getsockname()[1]
try:
result = _find_live_ports('127.0.0.1', [49154, live_port], 0.8)
result = _find_live_ports('127.0.0.1', [preferred_port, live_port], 0.8)
finally:
live_sock.close()
assert set(result) == {49154, live_port}
assert set(result) == {preferred_port, live_port}
async def test_probe_uses_discovered_low_port(hass: HomeAssistant, monkeypatch) -> None:
+70
View File
@@ -0,0 +1,70 @@
"""Tests for the TP1X_DA-AC-CAC-01001_0000 cassette AC (issue #191).
0.16.0's device-type simplification dropped oneUiVersion detection on the
assumption every device it typed was already reachable via a modelNum board
token -- this board was the one exception (its oneUiVersion self-reports
"7.0 Air conditioner", but 'CAC' had never been added to the board-token
table), so it silently fell back to common caps and lost its climate entity.
This dump is NOT fully covered yet -- ten hrefs remain unbound (edge
lighting, PM1 filter, a second stateful light resource, absence-clean, four
`/settings/sound/*` resources, smart-sensing-cooling, UV LED), all genuinely
new to this board generation. That's a real device-support gap, left
documented here rather than guessed at, per the 'don't guess' rule -- fixing
the routing regression was the scope of #191.
"""
from custom_components.localthings.registry.adapter import flatten
from custom_components.localthings.registry.by_type import for_device_by_model
from custom_components.localthings.registry.discovery import discover
from tests.conftest import _load_device
_STILL_UNBOUND = frozenset({
'/edgelighting/vs/0',
'/filter/airdustPM1filter/vs/0',
'/light/stateful/vs/0',
'/mds/absenceclean/vs/0',
'/settings/sound/mode/vs/0',
'/settings/sound/optimization/vs/0',
'/settings/sound/output/vs/0',
'/settings/sound/volume/vs/0',
'/smartsensingcooling/vs/0',
'/uvled/vs/0',
})
def _resources():
return _load_device('airconditioner_cac')
def _reg(resources):
info = resources['/information/vs/0']
return for_device_by_model(
info['x.com.samsung.da.modelNum'], info['x.com.samsung.da.description'])
def test_resolves_to_airconditioner_registry():
assert _reg(_resources()).name == 'airconditioner'
def test_documented_coverage_gap_is_exactly_this_set():
"""Locks in the current, known-incomplete coverage so a future fix to
any of these hrefs shows up as a golden-regression diff (extra keys) to
update here, rather than silently shrinking this list unnoticed."""
resources = _resources()
reg = _reg(resources)
unbound = []
discover(resources, reg.capabilities, reg.pattern_capabilities, log=unbound.append)
assert set(unbound) == _STILL_UNBOUND
def test_non_legacy_board_uses_the_generic_energy_scale():
"""This board reports /wind/strength/vs/0 (not /airflow/vs/0), so
is_legacy_board() is False and it must use the plain wh_to_kwh scale,
not the /100000 correction added for the unrelated ARTIK051_KRAC-class
board in issue #193."""
resources = _resources()
reg = _reg(resources)
bound = discover(resources, reg.capabilities, reg.pattern_capabilities)
state = flatten(bound, resources)
assert state['energy_kwh'] == round(84044 / 1000.0, 2)
+20
View File
@@ -859,6 +859,26 @@ def test_registry_reproduces_golden_state_keys_for_airconditioner_fac_bora():
)
def test_registry_reproduces_golden_state_keys_for_airconditioner_cac():
"""TP1X_DA-AC-CAC-01001_0000 (issue #191) -- fell back to 'unknown' in
0.16.0 when oneUiVersion detection was dropped, since 'CAC' had never
been added to the modelNum board-token table. Resolved via the new 'CAC'
token onto the existing airconditioner registry. Not fully covered yet --
ten hrefs remain unbound (edge lighting, PM1 filter, stateful light,
absence-clean, four sound-settings resources, smart-sensing-cooling, UV
LED), all genuinely new to this board generation and out of scope for
the routing fix; see test_airconditioner_cac.py for the documented gap."""
from tests.conftest import _load_device
resources = _load_device('airconditioner_cac')
golden = json.loads((GOLDEN / 'airconditioner_cac.json').read_text())
state_keys = _new_state_keys('airconditioner_cac', 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_air_purifier_avt_ww():
"""AVT-WW-TP1-23-AXX500 (issue #190) -- next-gen BESPOKE Cube Air board;
reports device_type 'unknown' with empty oneUiVersion because 'VTWW' as a