diff --git a/homeassistant/components/zwave_js/climate.py b/homeassistant/components/zwave_js/climate.py index 82c212a99a5..f38508ec09c 100644 --- a/homeassistant/components/zwave_js/climate.py +++ b/homeassistant/components/zwave_js/climate.py @@ -9,8 +9,6 @@ from zwave_js_server.const.command_class.thermostat import ( THERMOSTAT_CURRENT_TEMP_PROPERTY, THERMOSTAT_HUMIDITY_PROPERTY, THERMOSTAT_MODE_PROPERTY, - THERMOSTAT_MODE_SETPOINT_MAP, - THERMOSTAT_MODES, THERMOSTAT_OPERATING_STATE_PROPERTY, THERMOSTAT_SETPOINT_PROPERTY, ThermostatMode, @@ -40,7 +38,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.util.unit_conversion import TemperatureConverter -from .const import DATA_CLIENT, DOMAIN +from .const import DATA_CLIENT, DOMAIN, LOGGER from .discovery import ZwaveDiscoveryInfo from .discovery_data_template import DynamicCurrentTempClimateDataTemplate from .entity import ZWaveBaseEntity @@ -48,6 +46,38 @@ from .helpers import get_value_of_zwave_value PARALLEL_UPDATES = 0 +THERMOSTAT_MODES = [ + ThermostatMode.OFF, + ThermostatMode.HEAT, + ThermostatMode.COOL, + ThermostatMode.AUTO, + ThermostatMode.AUTO_CHANGE_OVER, + ThermostatMode.FAN, + ThermostatMode.DRY, +] + +THERMOSTAT_MODE_SETPOINT_MAP: dict[int, list[ThermostatSetpointType]] = { + ThermostatMode.OFF: [], + ThermostatMode.HEAT: [ThermostatSetpointType.HEATING], + ThermostatMode.COOL: [ThermostatSetpointType.COOLING], + ThermostatMode.AUTO: [ + ThermostatSetpointType.HEATING, + ThermostatSetpointType.COOLING, + ], + ThermostatMode.AUXILIARY: [ThermostatSetpointType.HEATING], + ThermostatMode.FURNACE: [ThermostatSetpointType.FURNACE], + ThermostatMode.DRY: [ThermostatSetpointType.DRY_AIR], + ThermostatMode.MOIST: [ThermostatSetpointType.MOIST_AIR], + ThermostatMode.AUTO_CHANGE_OVER: [ThermostatSetpointType.AUTO_CHANGEOVER], + ThermostatMode.HEATING_ECON: [ThermostatSetpointType.ENERGY_SAVE_HEATING], + ThermostatMode.COOLING_ECON: [ThermostatSetpointType.ENERGY_SAVE_COOLING], + ThermostatMode.AWAY: [ + ThermostatSetpointType.AWAY_HEATING, + ThermostatSetpointType.AWAY_COOLING, + ], + ThermostatMode.FULL_POWER: [ThermostatSetpointType.FULL_POWER], +} + # Map Z-Wave HVAC Mode to Home Assistant value # Note: We treat "auto" as "heat_cool" as most Z-Wave devices # report auto_changeover as auto without schedule support. @@ -233,9 +263,15 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity): # treat value as hvac mode if hass_mode := ZW_HVAC_MODE_MAP.get(mode_id): all_modes[hass_mode] = mode_id + # Dry and Fan modes are in the process of being migrated from + # presets to hvac modes. In the meantime, we will set them as + # both, presets and hvac modes, to maintain backwards compatibility + if mode_id in (ThermostatMode.DRY, ThermostatMode.FAN): + all_presets[mode_name] = mode_id else: # treat value as hvac preset all_presets[mode_name] = mode_id + self._hvac_modes = all_modes self._hvac_presets = all_presets @@ -487,6 +523,13 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity): preset_mode_value = self._hvac_presets.get(preset_mode) if preset_mode_value is None: raise ValueError(f"Received an invalid preset mode: {preset_mode}") + # Dry and Fan preset modes are deprecated as of 2023.8 + # Use Dry and Fan HVAC modes instead + if preset_mode_value in (ThermostatMode.DRY, ThermostatMode.FAN): + LOGGER.warning( + "Dry and Fan preset modes are deprecated and will be removed in a future release. " + "Use the corresponding Dry and Fan HVAC modes instead" + ) await self._async_set_value(self._current_mode, preset_mode_value) diff --git a/tests/components/zwave_js/common.py b/tests/components/zwave_js/common.py index 3da63419a4b..606dda30b24 100644 --- a/tests/components/zwave_js/common.py +++ b/tests/components/zwave_js/common.py @@ -35,6 +35,7 @@ CLIMATE_DANFOSS_LC13_ENTITY = "climate.living_connect_z_thermostat" CLIMATE_EUROTRONICS_SPIRIT_Z_ENTITY = "climate.thermostatic_valve" CLIMATE_FLOOR_THERMOSTAT_ENTITY = "climate.floor_thermostat" CLIMATE_MAIN_HEAT_ACTIONNER = "climate.main_heat_actionner" +CLIMATE_AIDOO_HVAC_UNIT_ENTITY = "climate.aidoo_control_hvac_unit" BULB_6_MULTI_COLOR_LIGHT_ENTITY = "light.bulb_6_multi_color" EATON_RF9640_ENTITY = "light.allloaddimmer" AEON_SMART_SWITCH_LIGHT_ENTITY = "light.smart_switch_6" diff --git a/tests/components/zwave_js/conftest.py b/tests/components/zwave_js/conftest.py index 68484111802..0eb4ec775f9 100644 --- a/tests/components/zwave_js/conftest.py +++ b/tests/components/zwave_js/conftest.py @@ -365,6 +365,14 @@ def climate_adc_t3000_state_fixture(): return json.loads(load_fixture("zwave_js/climate_adc_t3000_state.json")) +@pytest.fixture(name="climate_airzone_aidoo_control_hvac_unit_state", scope="session") +def climate_airzone_aidoo_control_hvac_unit_state_fixture(): + """Load the climate Airzone Aidoo Control HVAC Unit state fixture data.""" + return json.loads( + load_fixture("zwave_js/climate_airzone_aidoo_control_hvac_unit_state.json") + ) + + @pytest.fixture(name="climate_danfoss_lc_13_state", scope="session") def climate_danfoss_lc_13_state_fixture(): """Load Danfoss (LC-13) electronic radiator thermostat node state fixture data.""" @@ -826,6 +834,16 @@ def climate_adc_t3000_missing_fan_mode_states_fixture(client, climate_adc_t3000_ return node +@pytest.fixture(name="climate_airzone_aidoo_control_hvac_unit") +def climate_airzone_aidoo_control_hvac_unit_fixture( + client, climate_airzone_aidoo_control_hvac_unit_state +): + """Mock a climate Airzone Aidoo Control HVAC node.""" + node = Node(client, copy.deepcopy(climate_airzone_aidoo_control_hvac_unit_state)) + client.driver.controller.nodes[node.node_id] = node + return node + + @pytest.fixture(name="climate_danfoss_lc_13") def climate_danfoss_lc_13_fixture(client, climate_danfoss_lc_13_state): """Mock a climate radio danfoss LC-13 node.""" diff --git a/tests/components/zwave_js/fixtures/climate_airzone_aidoo_control_hvac_unit_state.json b/tests/components/zwave_js/fixtures/climate_airzone_aidoo_control_hvac_unit_state.json new file mode 100644 index 00000000000..b5afa1131a8 --- /dev/null +++ b/tests/components/zwave_js/fixtures/climate_airzone_aidoo_control_hvac_unit_state.json @@ -0,0 +1,818 @@ +{ + "nodeId": 12, + "index": 0, + "installerIcon": 4608, + "userIcon": 4608, + "status": 4, + "ready": true, + "isListening": true, + "isRouting": true, + "isSecure": false, + "manufacturerId": 1102, + "productId": 1, + "productType": 4, + "firmwareVersion": "10.20.1", + "zwavePlusVersion": 2, + "deviceConfig": { + "filename": "/data/db/devices/0x044e/AZAI6WSPFU2.json", + "isEmbedded": true, + "manufacturer": "Airzone", + "manufacturerId": 1102, + "label": "AZAI6WSPFU2", + "description": "Aidoo Control HVAC unit", + "devices": [ + { + "productType": 4, + "productId": 1 + } + ], + "firmwareVersion": { + "min": "0.0", + "max": "255.255" + }, + "preferred": false, + "compat": { + "overrideFloatEncoding": { + "precision": 1 + } + } + }, + "label": "AZAI6WSPFU2", + "interviewAttempts": 0, + "endpoints": [ + { + "nodeId": 12, + "index": 0, + "installerIcon": 4608, + "userIcon": 4608, + "deviceClass": { + "basic": { + "key": 4, + "label": "Routing Slave" + }, + "generic": { + "key": 8, + "label": "Thermostat" + }, + "specific": { + "key": 6, + "label": "General Thermostat V2" + }, + "mandatorySupportedCCs": [32, 114, 64, 67, 134], + "mandatoryControlledCCs": [] + }, + "commandClasses": [ + { + "id": 114, + "name": "Manufacturer Specific", + "version": 2, + "isSecure": false + }, + { + "id": 64, + "name": "Thermostat Mode", + "version": 3, + "isSecure": false + }, + { + "id": 67, + "name": "Thermostat Setpoint", + "version": 1, + "isSecure": false + }, + { + "id": 134, + "name": "Version", + "version": 3, + "isSecure": false + }, + { + "id": 94, + "name": "Z-Wave Plus Info", + "version": 2, + "isSecure": false + }, + { + "id": 68, + "name": "Thermostat Fan Mode", + "version": 2, + "isSecure": false + }, + { + "id": 49, + "name": "Multilevel Sensor", + "version": 1, + "isSecure": false + }, + { + "id": 113, + "name": "Notification", + "version": 8, + "isSecure": false + }, + { + "id": 133, + "name": "Association", + "version": 2, + "isSecure": false + }, + { + "id": 142, + "name": "Multi Channel Association", + "version": 3, + "isSecure": false + }, + { + "id": 89, + "name": "Association Group Information", + "version": 3, + "isSecure": false + }, + { + "id": 85, + "name": "Transport Service", + "version": 2, + "isSecure": false + }, + { + "id": 90, + "name": "Device Reset Locally", + "version": 1, + "isSecure": false + }, + { + "id": 135, + "name": "Indicator", + "version": 3, + "isSecure": false + }, + { + "id": 115, + "name": "Powerlevel", + "version": 1, + "isSecure": false + }, + { + "id": 152, + "name": "Security", + "version": 1, + "isSecure": true + }, + { + "id": 108, + "name": "Supervision", + "version": 1, + "isSecure": false + }, + { + "id": 122, + "name": "Firmware Update Meta Data", + "version": 5, + "isSecure": false + }, + { + "id": 159, + "name": "Security 2", + "version": 1, + "isSecure": true + } + ] + } + ], + "values": [ + { + "endpoint": 0, + "commandClass": 49, + "commandClassName": "Multilevel Sensor", + "property": "Air temperature", + "propertyName": "Air temperature", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Air temperature", + "ccSpecific": { + "sensorType": 1, + "scale": 0 + }, + "unit": "\u00b0C", + "stateful": true, + "secret": false + }, + "value": 29 + }, + { + "endpoint": 0, + "commandClass": 64, + "commandClassName": "Thermostat Mode", + "property": "mode", + "propertyName": "mode", + "ccVersion": 3, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Thermostat mode", + "min": 0, + "max": 255, + "states": { + "0": "Off", + "1": "Heat", + "2": "Cool", + "6": "Fan", + "8": "Dry", + "10": "Auto changeover" + }, + "stateful": true, + "secret": false + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 64, + "commandClassName": "Thermostat Mode", + "property": "manufacturerData", + "propertyName": "manufacturerData", + "ccVersion": 3, + "metadata": { + "type": "buffer", + "readable": true, + "writeable": false, + "label": "Manufacturer data", + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 67, + "commandClassName": "Thermostat Setpoint", + "property": "setpoint", + "propertyKey": 1, + "propertyName": "setpoint", + "propertyKeyName": "Heating", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Setpoint (Heating)", + "ccSpecific": { + "setpointType": 1 + }, + "unit": "\u00b0C", + "stateful": true, + "secret": false + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 67, + "commandClassName": "Thermostat Setpoint", + "property": "setpoint", + "propertyKey": 2, + "propertyName": "setpoint", + "propertyKeyName": "Cooling", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Setpoint (Cooling)", + "ccSpecific": { + "setpointType": 2 + }, + "unit": "\u00b0C", + "stateful": true, + "secret": false + }, + "value": 23 + }, + { + "endpoint": 0, + "commandClass": 67, + "commandClassName": "Thermostat Setpoint", + "property": "setpoint", + "propertyKey": 8, + "propertyName": "setpoint", + "propertyKeyName": "Dry Air", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Setpoint (Dry Air)", + "ccSpecific": { + "setpointType": 8 + }, + "unit": "\u00b0C", + "stateful": true, + "secret": false + }, + "value": 23 + }, + { + "endpoint": 0, + "commandClass": 67, + "commandClassName": "Thermostat Setpoint", + "property": "setpoint", + "propertyKey": 10, + "propertyName": "setpoint", + "propertyKeyName": "Auto Changeover", + "ccVersion": 1, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Setpoint (Auto Changeover)", + "ccSpecific": { + "setpointType": 10 + }, + "unit": "\u00b0C", + "stateful": true, + "secret": false + }, + "value": 32 + }, + { + "endpoint": 0, + "commandClass": 68, + "commandClassName": "Thermostat Fan Mode", + "property": "mode", + "propertyName": "mode", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Thermostat fan mode", + "min": 0, + "max": 255, + "states": { + "1": "Low", + "3": "High", + "4": "Auto medium", + "5": "Medium" + }, + "stateful": true, + "secret": false + }, + "value": 5 + }, + { + "endpoint": 0, + "commandClass": 113, + "commandClassName": "Notification", + "property": "System", + "propertyKey": "Hardware status", + "propertyName": "System", + "propertyKeyName": "Hardware status", + "ccVersion": 8, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Hardware status", + "ccSpecific": { + "notificationType": 9 + }, + "min": 0, + "max": 255, + "states": { + "0": "idle", + "3": "System hardware failure (with failure code)" + }, + "stateful": true, + "secret": false + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 113, + "commandClassName": "Notification", + "property": "alarmType", + "propertyName": "alarmType", + "ccVersion": 8, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Alarm Type", + "min": 0, + "max": 255, + "stateful": true, + "secret": false + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 113, + "commandClassName": "Notification", + "property": "alarmLevel", + "propertyName": "alarmLevel", + "ccVersion": 8, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Alarm Level", + "min": 0, + "max": 255, + "stateful": true, + "secret": false + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "manufacturerId", + "propertyName": "manufacturerId", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Manufacturer ID", + "min": 0, + "max": 65535, + "stateful": true, + "secret": false + }, + "value": 1102 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productType", + "propertyName": "productType", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Product type", + "min": 0, + "max": 65535, + "stateful": true, + "secret": false + }, + "value": 4 + }, + { + "endpoint": 0, + "commandClass": 114, + "commandClassName": "Manufacturer Specific", + "property": "productId", + "propertyName": "productId", + "ccVersion": 2, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Product ID", + "min": 0, + "max": 65535, + "stateful": true, + "secret": false + }, + "value": 1 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "libraryType", + "propertyName": "libraryType", + "ccVersion": 3, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Library type", + "states": { + "0": "Unknown", + "1": "Static Controller", + "2": "Controller", + "3": "Enhanced Slave", + "4": "Slave", + "5": "Installer", + "6": "Routing Slave", + "7": "Bridge Controller", + "8": "Device under Test", + "9": "N/A", + "10": "AV Remote", + "11": "AV Device" + }, + "stateful": true, + "secret": false + }, + "value": 3 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "protocolVersion", + "propertyName": "protocolVersion", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Z-Wave protocol version", + "stateful": true, + "secret": false + }, + "value": "7.16" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "firmwareVersions", + "propertyName": "firmwareVersions", + "ccVersion": 3, + "metadata": { + "type": "string[]", + "readable": true, + "writeable": false, + "label": "Z-Wave chip firmware versions", + "stateful": true, + "secret": false + }, + "value": ["10.20"] + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "hardwareVersion", + "propertyName": "hardwareVersion", + "ccVersion": 3, + "metadata": { + "type": "number", + "readable": true, + "writeable": false, + "label": "Z-Wave chip hardware version", + "stateful": true, + "secret": false + }, + "value": 1 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "sdkVersion", + "propertyName": "sdkVersion", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "SDK version", + "stateful": true, + "secret": false + }, + "value": "7.16.3" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "applicationFrameworkAPIVersion", + "propertyName": "applicationFrameworkAPIVersion", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Z-Wave application framework API version", + "stateful": true, + "secret": false + }, + "value": "10.16.3" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "applicationFrameworkBuildNumber", + "propertyName": "applicationFrameworkBuildNumber", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Z-Wave application framework API build number", + "stateful": true, + "secret": false + }, + "value": 297 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "hostInterfaceVersion", + "propertyName": "hostInterfaceVersion", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Serial API version", + "stateful": true, + "secret": false + }, + "value": "unused" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "hostInterfaceBuildNumber", + "propertyName": "hostInterfaceBuildNumber", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Serial API build number", + "stateful": true, + "secret": false + }, + "value": 0 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "zWaveProtocolVersion", + "propertyName": "zWaveProtocolVersion", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Z-Wave protocol version", + "stateful": true, + "secret": false + }, + "value": "7.16.3" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "zWaveProtocolBuildNumber", + "propertyName": "zWaveProtocolBuildNumber", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Z-Wave protocol build number", + "stateful": true, + "secret": false + }, + "value": 297 + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "applicationVersion", + "propertyName": "applicationVersion", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Application version", + "stateful": true, + "secret": false + }, + "value": "10.20.1" + }, + { + "endpoint": 0, + "commandClass": 134, + "commandClassName": "Version", + "property": "applicationBuildNumber", + "propertyName": "applicationBuildNumber", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": false, + "label": "Application build number", + "stateful": true, + "secret": false + }, + "value": 43707 + }, + { + "endpoint": 0, + "commandClass": 135, + "commandClassName": "Indicator", + "property": "value", + "propertyName": "value", + "ccVersion": 3, + "metadata": { + "type": "number", + "readable": true, + "writeable": true, + "label": "Indicator value", + "ccSpecific": { + "indicatorId": 0 + }, + "min": 0, + "max": 255, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 135, + "commandClassName": "Indicator", + "property": "identify", + "propertyName": "identify", + "ccVersion": 3, + "metadata": { + "type": "boolean", + "readable": false, + "writeable": true, + "label": "Identify", + "states": { + "true": "Identify" + }, + "stateful": true, + "secret": false + } + }, + { + "endpoint": 0, + "commandClass": 135, + "commandClassName": "Indicator", + "property": "timeout", + "propertyName": "timeout", + "ccVersion": 3, + "metadata": { + "type": "string", + "readable": true, + "writeable": true, + "label": "Timeout", + "stateful": true, + "secret": false + } + } + ], + "isFrequentListening": false, + "maxDataRate": 100000, + "supportedDataRates": [40000, 100000], + "protocolVersion": 3, + "supportsBeaming": true, + "supportsSecurity": false, + "nodeType": 1, + "zwavePlusNodeType": 0, + "zwavePlusRoleType": 5, + "deviceClass": { + "basic": { + "key": 4, + "label": "Routing Slave" + }, + "generic": { + "key": 8, + "label": "Thermostat" + }, + "specific": { + "key": 6, + "label": "General Thermostat V2" + }, + "mandatorySupportedCCs": [32, 114, 64, 67, 134], + "mandatoryControlledCCs": [] + }, + "interviewStage": "Complete", + "deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x044e:0x0004:0x0001:10.20.1", + "statistics": { + "commandsTX": 69, + "commandsRX": 497, + "commandsDroppedRX": 0, + "commandsDroppedTX": 2, + "timeoutResponse": 0, + "rtt": 81 + }, + "highestSecurityClass": -1, + "isControllerNode": false, + "keepAwake": false +} diff --git a/tests/components/zwave_js/test_climate.py b/tests/components/zwave_js/test_climate.py index d3f38aaa307..753c107c2ee 100644 --- a/tests/components/zwave_js/test_climate.py +++ b/tests/components/zwave_js/test_climate.py @@ -18,6 +18,7 @@ from homeassistant.components.climate import ( ATTR_MAX_TEMP, ATTR_MIN_TEMP, ATTR_PRESET_MODE, + ATTR_PRESET_MODES, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, DOMAIN as CLIMATE_DOMAIN, @@ -41,6 +42,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from .common import ( + CLIMATE_AIDOO_HVAC_UNIT_ENTITY, CLIMATE_DANFOSS_LC13_ENTITY, CLIMATE_EUROTRONICS_SPIRIT_Z_ENTITY, CLIMATE_FLOOR_THERMOSTAT_ENTITY, @@ -694,3 +696,81 @@ async def test_thermostat_unknown_values( state = hass.states.get(CLIMATE_RADIO_THERMOSTAT_ENTITY) assert ATTR_HVAC_ACTION not in state.attributes + + +async def test_thermostat_dry_and_fan_both_hvac_mode_and_preset( + hass: HomeAssistant, + client, + climate_airzone_aidoo_control_hvac_unit, + integration, +) -> None: + """Test that dry and fan modes are both available as hvac mode and preset.""" + state = hass.states.get(CLIMATE_AIDOO_HVAC_UNIT_ENTITY) + assert state + assert state.attributes[ATTR_HVAC_MODES] == [ + HVACMode.OFF, + HVACMode.HEAT, + HVACMode.COOL, + HVACMode.FAN_ONLY, + HVACMode.DRY, + HVACMode.HEAT_COOL, + ] + assert state.attributes[ATTR_PRESET_MODES] == [ + PRESET_NONE, + "Fan", + "Dry", + ] + + +async def test_thermostat_warning_when_setting_dry_preset( + hass: HomeAssistant, + client, + climate_airzone_aidoo_control_hvac_unit, + integration, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test warning when setting Dry preset.""" + state = hass.states.get(CLIMATE_AIDOO_HVAC_UNIT_ENTITY) + assert state + + await hass.services.async_call( + CLIMATE_DOMAIN, + SERVICE_SET_PRESET_MODE, + { + ATTR_ENTITY_ID: CLIMATE_AIDOO_HVAC_UNIT_ENTITY, + ATTR_PRESET_MODE: "Dry", + }, + blocking=True, + ) + + assert ( + "Dry and Fan preset modes are deprecated and will be removed in a future release. Use the corresponding Dry and Fan HVAC modes instead" + in caplog.text + ) + + +async def test_thermostat_warning_when_setting_fan_preset( + hass: HomeAssistant, + client, + climate_airzone_aidoo_control_hvac_unit, + integration, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test warning when setting Fan preset.""" + state = hass.states.get(CLIMATE_AIDOO_HVAC_UNIT_ENTITY) + assert state + + await hass.services.async_call( + CLIMATE_DOMAIN, + SERVICE_SET_PRESET_MODE, + { + ATTR_ENTITY_ID: CLIMATE_AIDOO_HVAC_UNIT_ENTITY, + ATTR_PRESET_MODE: "Fan", + }, + blocking=True, + ) + + assert ( + "Dry and Fan preset modes are deprecated and will be removed in a future release. Use the corresponding Dry and Fan HVAC modes instead" + in caplog.text + )