diff --git a/homeassistant/components/airzone_cloud/manifest.json b/homeassistant/components/airzone_cloud/manifest.json index ea22487f4a2..ab8e08835a3 100644 --- a/homeassistant/components/airzone_cloud/manifest.json +++ b/homeassistant/components/airzone_cloud/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/airzone_cloud", "iot_class": "cloud_polling", "loggers": ["aioairzone_cloud"], - "requirements": ["aioairzone-cloud==0.3.5"] + "requirements": ["aioairzone-cloud==0.3.6"] } diff --git a/requirements_all.txt b/requirements_all.txt index 9b8cdb0640f..09501cf8471 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -192,7 +192,7 @@ aio-georss-gdacs==0.8 aioairq==0.2.4 # homeassistant.components.airzone_cloud -aioairzone-cloud==0.3.5 +aioairzone-cloud==0.3.6 # homeassistant.components.airzone aioairzone==0.6.9 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 09c457191e2..936fe51a00d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -173,7 +173,7 @@ aio-georss-gdacs==0.8 aioairq==0.2.4 # homeassistant.components.airzone_cloud -aioairzone-cloud==0.3.5 +aioairzone-cloud==0.3.6 # homeassistant.components.airzone aioairzone==0.6.9 diff --git a/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr b/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr index 1d1d060e80a..594a5e6765a 100644 --- a/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr +++ b/tests/components/airzone_cloud/snapshots/test_diagnostics.ambr @@ -5,10 +5,18 @@ 'devices-config': dict({ 'device1': dict({ }), + 'device2': dict({ + }), + 'device3': dict({ + }), }), 'devices-status': dict({ 'device1': dict({ }), + 'device2': dict({ + }), + 'device3': dict({ + }), }), 'installations': dict({ 'installation1': dict({ @@ -22,11 +30,31 @@ ]), 'group_id': 'group1', }), + dict({ + 'devices': list([ + dict({ + 'device_id': 'device2', + 'ws_id': 'webserver2', + }), + ]), + 'group_id': 'group2', + }), + dict({ + 'devices': list([ + dict({ + 'device_id': 'device3', + 'ws_id': 'webserver3', + }), + ]), + 'group_id': 'group3', + }), ]), 'plugins': dict({ 'schedules': dict({ 'calendar_ws_ids': list([ 'webserver1', + 'webserver2', + 'webserver3', ]), }), }), @@ -50,6 +78,10 @@ 'webservers': dict({ 'webserver1': dict({ }), + 'webserver2': dict({ + }), + 'webserver3': dict({ + }), }), }), 'config_entry': dict({ @@ -90,6 +122,13 @@ 'name': 'Bron', 'power': False, 'problems': False, + 'speed': 6, + 'speed-type': 0, + 'speeds': dict({ + '1': 2, + '2': 4, + '3': 6, + }), 'temperature': 21.0, 'temperature-setpoint': 22.0, 'temperature-setpoint-cool-air': 22.0, @@ -103,7 +142,51 @@ 'temperature-setpoint-min-cool-air': 18.0, 'temperature-setpoint-min-hot-air': 16.0, 'temperature-step': 0.5, - 'web-server': '11:22:33:44:55:67', + 'web-server': 'webserver2', + 'ws-connected': True, + }), + 'aidoo_pro': dict({ + 'action': 1, + 'active': True, + 'available': True, + 'id': 'aidoo_pro', + 'installation': 'installation1', + 'is-connected': True, + 'mode': 2, + 'modes': list([ + 1, + 2, + 3, + 4, + 5, + ]), + 'name': 'Bron Pro', + 'power': True, + 'problems': False, + 'speed': 3, + 'speed-type': 0, + 'speeds': dict({ + '0': 0, + '1': 1, + '2': 2, + '3': 3, + '4': 4, + '5': 5, + }), + 'temperature': 20.0, + 'temperature-setpoint': 22.0, + 'temperature-setpoint-cool-air': 22.0, + 'temperature-setpoint-hot-air': 22.0, + 'temperature-setpoint-max': 30.0, + 'temperature-setpoint-max-auto-air': 30.0, + 'temperature-setpoint-max-cool-air': 30.0, + 'temperature-setpoint-max-hot-air': 30.0, + 'temperature-setpoint-min': 15.0, + 'temperature-setpoint-min-auto-air': 18.0, + 'temperature-setpoint-min-cool-air': 18.0, + 'temperature-setpoint-min-hot-air': 16.0, + 'temperature-step': 0.5, + 'web-server': 'webserver3', 'ws-connected': True, }), }), @@ -138,14 +221,14 @@ 'zone2', ]), }), - 'grp2': dict({ + 'group2': dict({ 'action': 6, 'active': False, 'aidoos': list([ 'aidoo1', ]), 'available': True, - 'id': 'grp2', + 'id': 'group2', 'installation': 'installation1', 'mode': 3, 'modes': list([ @@ -164,6 +247,32 @@ 'temperature-setpoint-min': 15.0, 'temperature-step': 0.5, }), + 'group3': dict({ + 'action': 1, + 'active': True, + 'aidoos': list([ + 'aidoo_pro', + ]), + 'available': True, + 'id': 'group3', + 'installation': 'installation1', + 'mode': 2, + 'modes': list([ + 1, + 2, + 3, + 4, + 5, + ]), + 'name': 'Aidoo Pro Group', + 'num-devices': 1, + 'power': True, + 'temperature': 20.0, + 'temperature-setpoint': 22.0, + 'temperature-setpoint-max': 30.0, + 'temperature-setpoint-min': 15.0, + 'temperature-step': 0.5, + }), }), 'installations': dict({ 'installation1': dict({ @@ -171,11 +280,13 @@ 'active': True, 'aidoos': list([ 'aidoo1', + 'aidoo_pro', ]), 'available': True, 'groups': list([ 'group1', - 'grp2', + 'group2', + 'group3', ]), 'humidity': 27, 'id': 'installation1', @@ -188,20 +299,21 @@ 5, ]), 'name': 'House', - 'num-devices': 3, - 'num-groups': 2, + 'num-devices': 4, + 'num-groups': 3, 'power': True, 'systems': list([ 'system1', ]), - 'temperature': 22.0, - 'temperature-setpoint': 23.3, + 'temperature': 21.5, + 'temperature-setpoint': 23.0, 'temperature-setpoint-max': 30.0, 'temperature-setpoint-min': 15.0, 'temperature-step': 0.5, 'web-servers': list([ 'webserver1', - '11:22:33:44:55:67', + 'webserver2', + 'webserver3', ]), 'zones': list([ 'zone1', @@ -235,21 +347,6 @@ }), }), 'web-servers': dict({ - '11:22:33:44:55:67': dict({ - 'available': True, - 'connection-date': '2023-05-24 17:00:52 +0200', - 'disconnection-date': '2023-05-24 17:00:25 +0200', - 'firmware': '3.13', - 'id': '11:22:33:44:55:67', - 'installation': 'installation1', - 'name': 'WebServer 11:22:33:44:55:67', - 'type': 'ws_aidoo', - 'wifi-channel': 1, - 'wifi-mac': '**REDACTED**', - 'wifi-quality': 4, - 'wifi-rssi': -77, - 'wifi-ssid': 'Wifi', - }), 'webserver1': dict({ 'available': True, 'connection-date': '2023-05-07T12:55:51.000Z', @@ -265,6 +362,36 @@ 'wifi-rssi': -56, 'wifi-ssid': 'Wifi', }), + 'webserver2': dict({ + 'available': True, + 'connection-date': '2023-05-24 17:00:52 +0200', + 'disconnection-date': '2023-05-24 17:00:25 +0200', + 'firmware': '3.13', + 'id': 'webserver2', + 'installation': 'installation1', + 'name': 'WebServer 11:22:33:44:55:67', + 'type': 'ws_aidoo', + 'wifi-channel': 1, + 'wifi-mac': '**REDACTED**', + 'wifi-quality': 4, + 'wifi-rssi': -77, + 'wifi-ssid': 'Wifi', + }), + 'webserver3': dict({ + 'available': True, + 'connection-date': '2023-11-05 17:00:52 +0200', + 'disconnection-date': '2023-11-05 17:00:25 +0200', + 'firmware': '4.01', + 'id': 'webserver3', + 'installation': 'installation1', + 'name': 'WebServer 11:22:33:44:55:68', + 'type': 'ws_aidoo', + 'wifi-channel': 6, + 'wifi-mac': '**REDACTED**', + 'wifi-quality': 4, + 'wifi-rssi': -67, + 'wifi-ssid': 'Wifi', + }), }), 'zones': dict({ 'zone1': dict({ diff --git a/tests/components/airzone_cloud/test_binary_sensor.py b/tests/components/airzone_cloud/test_binary_sensor.py index a1b5d5319c0..ca40a732046 100644 --- a/tests/components/airzone_cloud/test_binary_sensor.py +++ b/tests/components/airzone_cloud/test_binary_sensor.py @@ -22,6 +22,14 @@ async def test_airzone_create_binary_sensors(hass: HomeAssistant) -> None: state = hass.states.get("binary_sensor.bron_running") assert state.state == STATE_OFF + state = hass.states.get("binary_sensor.bron_pro_problem") + assert state.state == STATE_OFF + assert state.attributes.get("errors") is None + assert state.attributes.get("warnings") is None + + state = hass.states.get("binary_sensor.bron_pro_running") + assert state.state == STATE_ON + # Systems state = hass.states.get("binary_sensor.system_1_problem") assert state.state == STATE_ON diff --git a/tests/components/airzone_cloud/test_climate.py b/tests/components/airzone_cloud/test_climate.py index 010c0d51072..7c273dc8bc2 100644 --- a/tests/components/airzone_cloud/test_climate.py +++ b/tests/components/airzone_cloud/test_climate.py @@ -40,7 +40,7 @@ async def test_airzone_create_climates(hass: HomeAssistant) -> None: # Aidoos state = hass.states.get("climate.bron") assert state.state == HVACMode.OFF - assert state.attributes.get(ATTR_CURRENT_HUMIDITY) is None + assert ATTR_CURRENT_HUMIDITY not in state.attributes assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 21.0 assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.OFF assert state.attributes[ATTR_HVAC_MODES] == [ @@ -56,6 +56,24 @@ async def test_airzone_create_climates(hass: HomeAssistant) -> None: assert state.attributes[ATTR_TARGET_TEMP_STEP] == API_TEMPERATURE_STEP assert state.attributes[ATTR_TEMPERATURE] == 22.0 + state = hass.states.get("climate.bron_pro") + assert state.state == HVACMode.COOL + assert ATTR_CURRENT_HUMIDITY not in state.attributes + assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 20.0 + assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.COOLING + assert state.attributes[ATTR_HVAC_MODES] == [ + HVACMode.HEAT_COOL, + HVACMode.COOL, + HVACMode.HEAT, + HVACMode.FAN_ONLY, + HVACMode.DRY, + HVACMode.OFF, + ] + assert state.attributes[ATTR_MAX_TEMP] == 30 + assert state.attributes[ATTR_MIN_TEMP] == 15 + assert state.attributes[ATTR_TARGET_TEMP_STEP] == API_TEMPERATURE_STEP + assert state.attributes[ATTR_TEMPERATURE] == 22.0 + # Groups state = hass.states.get("climate.group") assert state.state == HVACMode.COOL @@ -78,7 +96,7 @@ async def test_airzone_create_climates(hass: HomeAssistant) -> None: state = hass.states.get("climate.house") assert state.state == HVACMode.COOL assert state.attributes[ATTR_CURRENT_HUMIDITY] == 27 - assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 22.0 + assert state.attributes[ATTR_CURRENT_TEMPERATURE] == 21.5 assert state.attributes[ATTR_HVAC_ACTION] == HVACAction.COOLING assert state.attributes[ATTR_HVAC_MODES] == [ HVACMode.HEAT_COOL, @@ -91,7 +109,7 @@ async def test_airzone_create_climates(hass: HomeAssistant) -> None: assert state.attributes[ATTR_MAX_TEMP] == 30 assert state.attributes[ATTR_MIN_TEMP] == 15 assert state.attributes[ATTR_TARGET_TEMP_STEP] == API_TEMPERATURE_STEP - assert state.attributes[ATTR_TEMPERATURE] == 23.3 + assert state.attributes[ATTR_TEMPERATURE] == 23.0 # Zones state = hass.states.get("climate.dormitorio") @@ -541,7 +559,7 @@ async def test_airzone_climate_set_temp_error(hass: HomeAssistant) -> None: ) state = hass.states.get("climate.house") - assert state.attributes[ATTR_TEMPERATURE] == 23.3 + assert state.attributes[ATTR_TEMPERATURE] == 23.0 # Zones with patch( diff --git a/tests/components/airzone_cloud/test_diagnostics.py b/tests/components/airzone_cloud/test_diagnostics.py index 8bef70501e7..2b2e3f33105 100644 --- a/tests/components/airzone_cloud/test_diagnostics.py +++ b/tests/components/airzone_cloud/test_diagnostics.py @@ -20,7 +20,7 @@ from homeassistant.components.airzone_cloud.const import DOMAIN from homeassistant.const import CONF_ID from homeassistant.core import HomeAssistant -from .util import CONFIG, WS_ID, async_init_integration +from .util import CONFIG, WS_ID, WS_ID_AIDOO, WS_ID_AIDOO_PRO, async_init_integration from tests.components.diagnostics import get_diagnostics_for_config_entry from tests.typing import ClientSessionGenerator @@ -28,9 +28,13 @@ from tests.typing import ClientSessionGenerator RAW_DATA_MOCK = { RAW_DEVICES_CONFIG: { "dev1": {}, + "dev2": {}, + "dev3": {}, }, RAW_DEVICES_STATUS: { "dev1": {}, + "dev2": {}, + "dev3": {}, }, RAW_INSTALLATIONS: { CONFIG[CONF_ID]: { @@ -44,11 +48,31 @@ RAW_DATA_MOCK = { }, ], }, + { + API_GROUP_ID: "grp2", + API_DEVICES: [ + { + API_DEVICE_ID: "dev2", + API_WS_ID: WS_ID_AIDOO, + }, + ], + }, + { + API_GROUP_ID: "grp3", + API_DEVICES: [ + { + API_DEVICE_ID: "dev3", + API_WS_ID: WS_ID_AIDOO_PRO, + }, + ], + }, ], "plugins": { "schedules": { "calendar_ws_ids": [ WS_ID, + WS_ID_AIDOO, + WS_ID_AIDOO_PRO, ], }, }, @@ -57,6 +81,8 @@ RAW_DATA_MOCK = { RAW_INSTALLATIONS_LIST: {}, RAW_WEBSERVERS: { WS_ID: {}, + WS_ID_AIDOO: {}, + WS_ID_AIDOO_PRO: {}, }, "test_cov": { "1": None, diff --git a/tests/components/airzone_cloud/test_sensor.py b/tests/components/airzone_cloud/test_sensor.py index d9b19f93f7d..b370e75c9aa 100644 --- a/tests/components/airzone_cloud/test_sensor.py +++ b/tests/components/airzone_cloud/test_sensor.py @@ -16,6 +16,9 @@ async def test_airzone_create_sensors( state = hass.states.get("sensor.bron_temperature") assert state.state == "21.0" + state = hass.states.get("sensor.bron_pro_temperature") + assert state.state == "20.0" + # WebServers state = hass.states.get("sensor.webserver_11_22_33_44_55_66_signal_strength") assert state.state == "-56" diff --git a/tests/components/airzone_cloud/util.py b/tests/components/airzone_cloud/util.py index 76349d06481..6924344a092 100644 --- a/tests/components/airzone_cloud/util.py +++ b/tests/components/airzone_cloud/util.py @@ -7,6 +7,7 @@ from aioairzone_cloud.common import OperationMode from aioairzone_cloud.const import ( API_ACTIVE, API_AZ_AIDOO, + API_AZ_AIDOO_PRO, API_AZ_SYSTEM, API_AZ_ZONE, API_CELSIUS, @@ -52,6 +53,9 @@ from aioairzone_cloud.const import ( API_SP_AIR_HEAT, API_SP_AIR_STOP, API_SP_AIR_VENT, + API_SPEED_CONF, + API_SPEED_TYPE, + API_SPEED_VALUES, API_STAT_AP_MAC, API_STAT_CHANNEL, API_STAT_QUALITY, @@ -79,6 +83,7 @@ from tests.common import MockConfigEntry WS_ID = "11:22:33:44:55:66" WS_ID_AIDOO = "11:22:33:44:55:67" +WS_ID_AIDOO_PRO = "11:22:33:44:55:68" CONFIG = { CONF_ID: "inst1", @@ -136,6 +141,18 @@ GET_INSTALLATION_MOCK = { }, ], }, + { + API_GROUP_ID: "grp3", + API_NAME: "Aidoo Pro Group", + API_DEVICES: [ + { + API_DEVICE_ID: "aidoo_pro", + API_NAME: "Bron Pro", + API_TYPE: API_AZ_AIDOO_PRO, + API_WS_ID: WS_ID_AIDOO_PRO, + }, + ], + }, ], } @@ -147,6 +164,7 @@ GET_INSTALLATIONS_MOCK = { API_WS_IDS: [ WS_ID, WS_ID_AIDOO, + WS_ID_AIDOO_PRO, ], }, ], @@ -186,6 +204,23 @@ GET_WEBSERVER_MOCK_AIDOO = { }, } +GET_WEBSERVER_MOCK_AIDOO_PRO = { + API_WS_TYPE: "ws_aidoo", + API_CONFIG: { + API_WS_FW: "4.01", + API_STAT_SSID: "Wifi", + API_STAT_CHANNEL: 6, + API_STAT_AP_MAC: "00:00:00:00:00:02", + }, + API_STATUS: { + API_IS_CONNECTED: True, + API_STAT_QUALITY: 4, + API_STAT_RSSI: -67, + API_CONNECTION_DATE: "2023-11-05 17:00:52 +0200", + API_DISCONNECTION_DATE: "2023-11-05 17:00:25 +0200", + }, +} + def mock_get_device_status(device: Device) -> dict[str, Any]: """Mock API device status.""" @@ -214,11 +249,46 @@ def mock_get_device_status(device: Device) -> dict[str, Any]: API_RANGE_SP_MIN_COOL_AIR: {API_CELSIUS: 18, API_FAH: 64}, API_RANGE_SP_MIN_HOT_AIR: {API_CELSIUS: 16, API_FAH: 61}, API_POWER: False, + API_SPEED_CONF: 6, + API_SPEED_VALUES: [2, 4, 6], + API_SPEED_TYPE: 0, API_IS_CONNECTED: True, API_WS_CONNECTED: True, API_LOCAL_TEMP: {API_CELSIUS: 21, API_FAH: 70}, API_WARNINGS: [], } + if device.get_id() == "aidoo_pro": + return { + API_ACTIVE: True, + API_ERRORS: [], + API_MODE: OperationMode.COOLING.value, + API_MODE_AVAIL: [ + OperationMode.AUTO.value, + OperationMode.COOLING.value, + OperationMode.HEATING.value, + OperationMode.VENTILATION.value, + OperationMode.DRY.value, + ], + API_SP_AIR_AUTO: {API_CELSIUS: 22, API_FAH: 72}, + API_SP_AIR_COOL: {API_CELSIUS: 22, API_FAH: 72}, + API_SP_AIR_HEAT: {API_CELSIUS: 22, API_FAH: 72}, + API_RANGE_MAX_AIR: {API_CELSIUS: 30, API_FAH: 86}, + API_RANGE_SP_MAX_AUTO_AIR: {API_CELSIUS: 30, API_FAH: 86}, + API_RANGE_SP_MAX_COOL_AIR: {API_CELSIUS: 30, API_FAH: 86}, + API_RANGE_SP_MAX_HOT_AIR: {API_CELSIUS: 30, API_FAH: 86}, + API_RANGE_MIN_AIR: {API_CELSIUS: 15, API_FAH: 59}, + API_RANGE_SP_MIN_AUTO_AIR: {API_CELSIUS: 18, API_FAH: 64}, + API_RANGE_SP_MIN_COOL_AIR: {API_CELSIUS: 18, API_FAH: 64}, + API_RANGE_SP_MIN_HOT_AIR: {API_CELSIUS: 16, API_FAH: 61}, + API_POWER: True, + API_SPEED_CONF: 3, + API_SPEED_VALUES: [0, 1, 2, 3, 4, 5], + API_SPEED_TYPE: 0, + API_IS_CONNECTED: True, + API_WS_CONNECTED: True, + API_LOCAL_TEMP: {API_CELSIUS: 20, API_FAH: 68}, + API_WARNINGS: [], + } if device.get_id() == "system1": return { API_ERRORS: [ @@ -304,16 +374,19 @@ def mock_get_device_status(device: Device) -> dict[str, Any]: API_LOCAL_TEMP: {API_FAH: 77, API_CELSIUS: 25}, API_WARNINGS: [], } - return None + return {} def mock_get_webserver(webserver: WebServer, devices: bool) -> dict[str, Any]: """Mock API get webserver.""" + if webserver.get_id() == WS_ID: + return GET_WEBSERVER_MOCK if webserver.get_id() == WS_ID_AIDOO: return GET_WEBSERVER_MOCK_AIDOO - - return GET_WEBSERVER_MOCK + if webserver.get_id() == WS_ID_AIDOO_PRO: + return GET_WEBSERVER_MOCK_AIDOO_PRO + return {} async def async_init_integration(