From b9d145299eecca62603e1fcd534e1b456ce33573 Mon Sep 17 00:00:00 2001 From: trip-g Date: Tue, 21 Jul 2026 16:53:11 -0400 Subject: [PATCH] Add settings.fan support to LyricDevice Resideo's device response nests a separate fan object under settings (allowedModes and its own changeableValues.mode), distinct from the top-level fanMode field aiolyric already exposes. Adds SettingsFan and SettingsFanChangeableValues classes plus Settings.fan, following the existing pattern used for hardware_settings/temperature_mode. --- aiolyric/objects/device.py | 28 ++++++++++++++++++++++++++++ tests/__init__.py | 8 ++++++++ tests/objects/test_device.py | 8 ++++++++ tests/objects/test_location.py | 10 ++++++++++ 4 files changed, 54 insertions(+) diff --git a/aiolyric/objects/device.py b/aiolyric/objects/device.py index 113c73e..895f45e 100644 --- a/aiolyric/objects/device.py +++ b/aiolyric/objects/device.py @@ -81,6 +81,29 @@ class SettingsSpecialMode(LyricBaseObject): """Special mode.""" +class SettingsFanChangeableValues(LyricBaseObject): + """Fan changeable values.""" + + @property + def mode(self): + """Return the fan mode.""" + return self.attributes.get("mode", None) + + +class SettingsFan(LyricBaseObject): + """Fan settings.""" + + @property + def allowed_modes(self): + """Return the allowed fan modes.""" + return self.attributes.get("allowedModes", []) + + @property + def changeable_values(self): + """Return the fan changeable values.""" + return SettingsFanChangeableValues(self.attributes.get("changeableValues", {})) + + class Settings(LyricBaseObject): """Settings.""" @@ -89,6 +112,11 @@ def hardware_settings(self): """Return hardware settings.""" return SettingsHardwareSettings(self.attributes.get("hardwareSettings", {})) + @property + def fan(self): + """Return fan settings.""" + return SettingsFan(self.attributes.get("fan", {})) + @property def temperature_mode(self): """Return temperature mode.""" diff --git a/tests/__init__.py b/tests/__init__.py index ee93752..e5da173 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -19,6 +19,10 @@ "allowedTimeIncrements": 10, "settings": { "hardwareSettings": {"brightness": 5, "maxBrightness": 5}, + "fan": { + "allowedModes": ["On", "Auto", "Circulate"], + "changeableValues": {"mode": "Auto"}, + }, "temperatureMode": {"air": True}, "specialMode": {}, "devicePairingEnabled": True, @@ -85,6 +89,10 @@ "allowedTimeIncrements": 10, "settings": { "hardwareSettings": {"brightness": 5, "maxBrightness": 5}, + "fan": { + "allowedModes": ["On", "Auto", "Circulate"], + "changeableValues": {"mode": "Auto"}, + }, "temperatureMode": {"air": True}, "specialMode": {}, "devicePairingEnabled": True, diff --git a/tests/objects/test_device.py b/tests/objects/test_device.py index 5b81664..1a009fc 100644 --- a/tests/objects/test_device.py +++ b/tests/objects/test_device.py @@ -55,6 +55,14 @@ def test_device( obj.settings.hardware_settings.max_brightness == device_fixture_response["settings"]["hardwareSettings"]["maxBrightness"] ) + assert ( + obj.settings.fan.allowed_modes + == device_fixture_response["settings"]["fan"]["allowedModes"] + ) + assert ( + obj.settings.fan.changeable_values.mode + == device_fixture_response["settings"]["fan"]["changeableValues"]["mode"] + ) assert ( obj.settings.temperature_mode.air == device_fixture_response["settings"]["temperatureMode"]["air"] diff --git a/tests/objects/test_location.py b/tests/objects/test_location.py index 095cfcb..cc77eff 100644 --- a/tests/objects/test_location.py +++ b/tests/objects/test_location.py @@ -74,6 +74,16 @@ def test_location( "maxBrightness" ] ) + assert ( + obj.devices[0].settings.fan.allowed_modes + == location_fixture_response["devices"][0]["settings"]["fan"]["allowedModes"] + ) + assert ( + obj.devices[0].settings.fan.changeable_values.mode + == location_fixture_response["devices"][0]["settings"]["fan"][ + "changeableValues" + ]["mode"] + ) assert ( obj.devices[0].settings.temperature_mode.air == location_fixture_response["devices"][0]["settings"]["temperatureMode"]["air"]