From 074142400a6bb9ebc693949aff171816d591589d Mon Sep 17 00:00:00 2001 From: Andrew Sayre <6730289+andrewsayre@users.noreply.github.com> Date: Mon, 6 May 2019 12:21:16 -0500 Subject: [PATCH] Fix SmartThings Samsung Air Conditioner Support (#23706) * Bump pysmartthings to 0.6.8 * Fix AC climate device * Fix stale comment --- .../components/smartthings/climate.py | 51 ++++++++++++------- .../components/smartthings/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/smartthings/test_climate.py | 12 +++-- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/smartthings/climate.py b/homeassistant/components/smartthings/climate.py index f45ea10ce47..f872e14bc77 100644 --- a/homeassistant/components/smartthings/climate.py +++ b/homeassistant/components/smartthings/climate.py @@ -39,19 +39,19 @@ AC_MODE_TO_STATE = { 'auto': STATE_AUTO, 'cool': STATE_COOL, 'dry': STATE_DRY, + 'coolClean': STATE_COOL, + 'dryClean': STATE_DRY, 'heat': STATE_HEAT, + 'heatClean': STATE_HEAT, 'fanOnly': STATE_FAN_ONLY } -STATE_TO_AC_MODE = {v: k for k, v in AC_MODE_TO_STATE.items()} - -SPEED_TO_FAN_MODE = { - 0: 'auto', - 1: 'low', - 2: 'medium', - 3: 'high', - 4: 'turbo' +STATE_TO_AC_MODE = { + STATE_AUTO: 'auto', + STATE_COOL: 'cool', + STATE_DRY: 'dry', + STATE_HEAT: 'heat', + STATE_FAN_ONLY: 'fanOnly' } -FAN_MODE_TO_SPEED = {v: k for k, v in SPEED_TO_FAN_MODE.items()} UNIT_MAP = { 'C': TEMP_CELSIUS, @@ -73,7 +73,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): ac_capabilities = [ Capability.air_conditioner_mode, - Capability.fan_speed, + Capability.air_conditioner_fan_mode, Capability.switch, Capability.temperature_measurement, Capability.thermostat_cooling_setpoint] @@ -98,7 +98,7 @@ def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: supported = [ Capability.air_conditioner_mode, Capability.demand_response_load_control, - Capability.fan_speed, + Capability.air_conditioner_fan_mode, Capability.power_consumption_report, Capability.relative_humidity_measurement, Capability.switch, @@ -124,7 +124,7 @@ def get_capabilities(capabilities: Sequence[str]) -> Optional[Sequence[str]]: # Or must have all of these A/C capabilities ac_capabilities = [ Capability.air_conditioner_mode, - Capability.fan_speed, + Capability.air_conditioner_fan_mode, Capability.switch, Capability.temperature_measurement, Capability.thermostat_cooling_setpoint] @@ -309,10 +309,14 @@ class SmartThingsThermostat(SmartThingsEntity, ClimateDevice): class SmartThingsAirConditioner(SmartThingsEntity, ClimateDevice): """Define a SmartThings Air Conditioner.""" + def __init__(self, device): + """Init the class.""" + super().__init__(device) + self._operations = None + async def async_set_fan_mode(self, fan_mode): """Set new target fan mode.""" - await self._device.set_fan_speed( - FAN_MODE_TO_SPEED[fan_mode], set_status=True) + await self._device.set_fan_mode(fan_mode, set_status=True) # State is set optimistically in the command above, therefore update # the entity state ahead of receiving the confirming push updates self.async_schedule_update_ha_state() @@ -354,10 +358,23 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateDevice): # the entity state ahead of receiving the confirming push updates self.async_schedule_update_ha_state() + async def async_update(self): + """Update the calculated fields of the AC.""" + operations = set() + for mode in self._device.status.supported_ac_modes: + state = AC_MODE_TO_STATE.get(mode) + if state is not None: + operations.add(state) + else: + _LOGGER.debug('Device %s (%s) returned an invalid supported ' + 'AC mode: %s', self._device.label, + self._device.device_id, mode) + self._operations = operations + @property def current_fan_mode(self): """Return the fan setting.""" - return SPEED_TO_FAN_MODE.get(self._device.status.fan_speed) + return self._device.status.fan_mode @property def current_operation(self): @@ -397,7 +414,7 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateDevice): @property def fan_list(self): """Return the list of available fan modes.""" - return list(FAN_MODE_TO_SPEED) + return self._device.status.supported_ac_fan_modes @property def is_on(self): @@ -407,7 +424,7 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateDevice): @property def operation_list(self): """Return the list of available operation modes.""" - return list(STATE_TO_AC_MODE) + return self._operations @property def supported_features(self): diff --git a/homeassistant/components/smartthings/manifest.json b/homeassistant/components/smartthings/manifest.json index d4baf69b108..d31a90c6eb8 100644 --- a/homeassistant/components/smartthings/manifest.json +++ b/homeassistant/components/smartthings/manifest.json @@ -4,7 +4,7 @@ "documentation": "https://www.home-assistant.io/components/smartthings", "requirements": [ "pysmartapp==0.3.2", - "pysmartthings==0.6.7" + "pysmartthings==0.6.8" ], "dependencies": [ "webhook" diff --git a/requirements_all.txt b/requirements_all.txt index 76d919f5e33..b80f14f0408 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1294,7 +1294,7 @@ pysma==0.3.1 pysmartapp==0.3.2 # homeassistant.components.smartthings -pysmartthings==0.6.7 +pysmartthings==0.6.8 # homeassistant.components.snmp pysnmp==4.4.9 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7e381a96445..202fc26907e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -261,7 +261,7 @@ pyqwikswitch==0.93 pysmartapp==0.3.2 # homeassistant.components.smartthings -pysmartthings==0.6.7 +pysmartthings==0.6.8 # homeassistant.components.sonos pysonos==0.0.12 diff --git a/tests/components/smartthings/test_climate.py b/tests/components/smartthings/test_climate.py index 8789b3e7730..b4a04bb5663 100644 --- a/tests/components/smartthings/test_climate.py +++ b/tests/components/smartthings/test_climate.py @@ -124,26 +124,30 @@ def air_conditioner_fixture(device_factory): capabilities=[ Capability.air_conditioner_mode, Capability.demand_response_load_control, - Capability.fan_speed, + Capability.air_conditioner_fan_mode, Capability.power_consumption_report, Capability.switch, Capability.temperature_measurement, Capability.thermostat_cooling_setpoint], status={ Attribute.air_conditioner_mode: 'auto', + Attribute.supported_ac_modes: + ["cool", "dry", "wind", "auto", "heat", "fanOnly"], Attribute.drlc_status: { "duration": 0, "drlcLevel": -1, "start": "1970-01-01T00:00:00Z", "override": False - }, - Attribute.fan_speed: 2, + }, + Attribute.fan_mode: 'medium', + Attribute.supported_ac_fan_modes: + ["auto", "low", "medium", "high", "turbo"], Attribute.power_consumption: { "start": "2019-02-24T21:03:04Z", "power": 0, "energy": 500, "end": "2019-02-26T02:05:55Z" - }, + }, Attribute.switch: 'on', Attribute.cooling_setpoint: 23} )