diff --git a/homeassistant/components/advantage_air/__init__.py b/homeassistant/components/advantage_air/__init__.py index 609e9044e0d..b66306d2c69 100644 --- a/homeassistant/components/advantage_air/__init__.py +++ b/homeassistant/components/advantage_air/__init__.py @@ -17,7 +17,7 @@ from homeassistant.helpers.update_coordinator import ( from .const import ADVANTAGE_AIR_RETRY, DOMAIN ADVANTAGE_AIR_SYNC_INTERVAL = 15 -ADVANTAGE_AIR_PLATFORMS = ["climate", "cover", "binary_sensor", "sensor"] +ADVANTAGE_AIR_PLATFORMS = ["climate", "cover", "binary_sensor", "sensor", "switch"] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/advantage_air/switch.py b/homeassistant/components/advantage_air/switch.py new file mode 100644 index 00000000000..0416613bf8c --- /dev/null +++ b/homeassistant/components/advantage_air/switch.py @@ -0,0 +1,58 @@ +"""Switch platform for Advantage Air integration.""" + +from homeassistant.components.advantage_air import AdvantageAirEntity +from homeassistant.helpers.entity import ToggleEntity + +from .const import ( + ADVANTAGE_AIR_STATE_OFF, + ADVANTAGE_AIR_STATE_ON, + DOMAIN as ADVANTAGE_AIR_DOMAIN, +) + + +async def async_setup_entry(hass, config_entry, async_add_entities): + """Set up AdvantageAir toggle platform.""" + + instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id] + + entities = [] + for ac_key, ac_device in instance["coordinator"].data["aircons"].items(): + if ac_device["info"]["freshAirStatus"] != "none": + entities.append(AdvantageAirFreshAir(instance, ac_key)) + async_add_entities(entities) + + +class AdvantageAirFreshAir(AdvantageAirEntity, ToggleEntity): + """Representation of Advantage Air fresh air control.""" + + @property + def name(self): + """Return the name.""" + return f'{self._ac["name"]} Fresh Air' + + @property + def unique_id(self): + """Return a unique id.""" + return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-freshair' + + @property + def is_on(self): + """Return the fresh air status.""" + return self._ac["freshAirStatus"] == ADVANTAGE_AIR_STATE_ON + + @property + def icon(self): + """Return a representative icon of the fresh air switch.""" + return "mdi:air-filter" + + async def async_turn_on(self, **kwargs): + """Turn fresh air on.""" + await self.async_change( + {self.ac_key: {"info": {"freshAirStatus": ADVANTAGE_AIR_STATE_ON}}} + ) + + async def async_turn_off(self, **kwargs): + """Turn fresh air off.""" + await self.async_change( + {self.ac_key: {"info": {"freshAirStatus": ADVANTAGE_AIR_STATE_OFF}}} + ) diff --git a/tests/components/advantage_air/test_switch.py b/tests/components/advantage_air/test_switch.py new file mode 100644 index 00000000000..f45477adc70 --- /dev/null +++ b/tests/components/advantage_air/test_switch.py @@ -0,0 +1,79 @@ +"""Test the Advantage Air Switch Platform.""" + +from json import loads + +from homeassistant.components.advantage_air.const import ( + ADVANTAGE_AIR_STATE_OFF, + ADVANTAGE_AIR_STATE_ON, +) +from homeassistant.components.switch import ( + DOMAIN as SWITCH_DOMAIN, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF + +from tests.components.advantage_air import ( + TEST_SET_RESPONSE, + TEST_SET_URL, + TEST_SYSTEM_DATA, + TEST_SYSTEM_URL, + add_mock_config, +) + + +async def test_cover_async_setup_entry(hass, aioclient_mock): + """Test climate setup without sensors.""" + + aioclient_mock.get( + TEST_SYSTEM_URL, + text=TEST_SYSTEM_DATA, + ) + aioclient_mock.get( + TEST_SET_URL, + text=TEST_SET_RESPONSE, + ) + + await add_mock_config(hass) + + registry = await hass.helpers.entity_registry.async_get_registry() + + assert len(aioclient_mock.mock_calls) == 1 + + # Test Switch Entity + entity_id = "switch.ac_one_fresh_air" + state = hass.states.get(entity_id) + assert state + assert state.state == STATE_OFF + + entry = registry.async_get(entity_id) + assert entry + assert entry.unique_id == "uniqueid-ac1-freshair" + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: [entity_id]}, + blocking=True, + ) + assert len(aioclient_mock.mock_calls) == 3 + assert aioclient_mock.mock_calls[-2][0] == "GET" + assert aioclient_mock.mock_calls[-2][1].path == "/setAircon" + data = loads(aioclient_mock.mock_calls[-2][1].query["json"]) + assert data["ac1"]["info"]["freshAirStatus"] == ADVANTAGE_AIR_STATE_ON + assert aioclient_mock.mock_calls[-1][0] == "GET" + assert aioclient_mock.mock_calls[-1][1].path == "/getSystemData" + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: [entity_id]}, + blocking=True, + ) + assert len(aioclient_mock.mock_calls) == 5 + assert aioclient_mock.mock_calls[-2][0] == "GET" + assert aioclient_mock.mock_calls[-2][1].path == "/setAircon" + data = loads(aioclient_mock.mock_calls[-2][1].query["json"]) + assert data["ac1"]["info"]["freshAirStatus"] == ADVANTAGE_AIR_STATE_OFF + assert aioclient_mock.mock_calls[-1][0] == "GET" + assert aioclient_mock.mock_calls[-1][1].path == "/getSystemData" diff --git a/tests/fixtures/advantage_air/getSystemData.json b/tests/fixtures/advantage_air/getSystemData.json index 88f184b2dc0..65dbf8d672b 100644 --- a/tests/fixtures/advantage_air/getSystemData.json +++ b/tests/fixtures/advantage_air/getSystemData.json @@ -7,7 +7,7 @@ "countDownToOn": 0, "fan": "high", "filterCleanStatus": 0, - "freshAirStatus": "none", + "freshAirStatus": "off", "mode": "vent", "myZone": 0, "name": "AC One",