"""Tests for Comelit SimpleHome humidifier platform.""" from typing import Any from unittest.mock import AsyncMock, patch from aiocomelit.api import ComelitSerialBridgeObject from aiocomelit.const import CLIMATE, WATT from freezegun.api import FrozenDateTimeFactory import pytest from syrupy.assertion import SnapshotAssertion from homeassistant.components.comelit.const import DOMAIN, SCAN_INTERVAL from homeassistant.components.humidifier import ( ATTR_HUMIDITY, ATTR_MODE, DOMAIN as HUMIDIFIER_DOMAIN, MODE_AUTO, MODE_NORMAL, SERVICE_SET_HUMIDITY, SERVICE_SET_MODE, SERVICE_TURN_OFF, SERVICE_TURN_ON, ) from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er from . import setup_integration from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform ENTITY_ID = "humidifier.climate0_humidifier" async def test_all_entities( hass: HomeAssistant, snapshot: SnapshotAssertion, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, entity_registry: er.EntityRegistry, ) -> None: """Test all entities.""" with patch( "homeassistant.components.comelit.BRIDGE_PLATFORMS", [Platform.HUMIDIFIER] ): await setup_integration(hass, mock_serial_bridge_config_entry) await snapshot_platform( hass, entity_registry, snapshot, mock_serial_bridge_config_entry.entry_id, ) @pytest.mark.parametrize( ("val", "mode", "humidity"), [ ( [ [100, 0, "U", "M", 210, 0, 0, "U"], [650, 0, "U", "M", 500, 0, 0, "U"], [0, 0], ], STATE_ON, 50.0, ), ( [ [100, 1, "U", "A", 210, 1, 0, "O"], [650, 1, "U", "A", 500, 1, 0, "O"], [0, 0], ], STATE_ON, 50.0, ), ( [ [100, 0, "O", "A", 210, 0, 0, "O"], [650, 0, "O", "A", 500, 0, 0, "O"], [0, 0], ], STATE_OFF, 50.0, ), ], ) async def test_humidifier_data_update( hass: HomeAssistant, freezer: FrozenDateTimeFactory, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, val: list[list[Any]], mode: str, humidity: float, ) -> None: """Test humidifier data update.""" await setup_integration(hass, mock_serial_bridge_config_entry) assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 mock_serial_bridge.get_all_devices.return_value[CLIMATE] = { 0: ComelitSerialBridgeObject( index=0, name="Climate0", status=0, human_status="off", type="climate", val=val, protected=0, zone="Living room", power=0.0, power_unit=WATT, ), } freezer.tick(SCAN_INTERVAL) async_fire_time_changed(hass) await hass.async_block_till_done() assert (state := hass.states.get(ENTITY_ID)) assert state.state == mode assert state.attributes[ATTR_HUMIDITY] == humidity async def test_humidifier_data_update_bad_data( hass: HomeAssistant, freezer: FrozenDateTimeFactory, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, ) -> None: """Test humidifier data update.""" await setup_integration(hass, mock_serial_bridge_config_entry) assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 mock_serial_bridge.get_all_devices.return_value[CLIMATE] = { 0: ComelitSerialBridgeObject( index=0, name="Climate0", status=0, human_status="off", type="climate", val="bad_data", # type: ignore[arg-type] protected=0, zone="Living room", power=0.0, power_unit=WATT, ), } freezer.tick(SCAN_INTERVAL) async_fire_time_changed(hass) await hass.async_block_till_done() assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 async def test_humidifier_set_humidity( hass: HomeAssistant, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, ) -> None: """Test humidifier set humidity service.""" await setup_integration(hass, mock_serial_bridge_config_entry) assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 # Test set humidity await hass.services.async_call( HUMIDIFIER_DOMAIN, SERVICE_SET_HUMIDITY, {ATTR_ENTITY_ID: ENTITY_ID, ATTR_HUMIDITY: 23}, blocking=True, ) mock_serial_bridge.set_humidity_status.assert_called() assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 23.0 async def test_humidifier_set_humidity_while_off( hass: HomeAssistant, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, ) -> None: """Test humidifier set humidity service while off.""" await setup_integration(hass, mock_serial_bridge_config_entry) assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 # Switch humidifier off await hass.services.async_call( HUMIDIFIER_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, blocking=True, ) mock_serial_bridge.set_humidity_status.assert_called() assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_OFF # Try setting humidity with pytest.raises(HomeAssistantError) as exc_info: await hass.services.async_call( HUMIDIFIER_DOMAIN, SERVICE_SET_HUMIDITY, {ATTR_ENTITY_ID: ENTITY_ID, ATTR_HUMIDITY: 23}, blocking=True, ) assert exc_info.value.translation_domain == DOMAIN assert exc_info.value.translation_key == "humidity_while_off" async def test_humidifier_set_mode( hass: HomeAssistant, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, ) -> None: """Test humidifier set mode service.""" await setup_integration(hass, mock_serial_bridge_config_entry) assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 assert state.attributes[ATTR_MODE] == MODE_NORMAL await hass.services.async_call( HUMIDIFIER_DOMAIN, SERVICE_SET_MODE, {ATTR_ENTITY_ID: ENTITY_ID, ATTR_MODE: MODE_AUTO}, blocking=True, ) mock_serial_bridge.set_humidity_status.assert_called() assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_MODE] == MODE_AUTO async def test_humidifier_set_status( hass: HomeAssistant, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, ) -> None: """Test humidifier set status service.""" await setup_integration(hass, mock_serial_bridge_config_entry) assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 # Test turn off await hass.services.async_call( HUMIDIFIER_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, blocking=True, ) mock_serial_bridge.set_humidity_status.assert_called() assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_OFF # Test turn on await hass.services.async_call( HUMIDIFIER_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID}, blocking=True, ) mock_serial_bridge.set_humidity_status.assert_called() assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON async def test_humidifier_dehumidifier_remove_stale( hass: HomeAssistant, mock_serial_bridge: AsyncMock, mock_serial_bridge_config_entry: MockConfigEntry, ) -> None: """Test removal of stale humidifier/dehumidifier entities.""" await setup_integration(hass, mock_serial_bridge_config_entry) assert (state := hass.states.get(ENTITY_ID)) assert state.state == STATE_ON assert state.attributes[ATTR_HUMIDITY] == 50.0 mock_serial_bridge.get_all_devices.return_value[CLIMATE] = { 0: ComelitSerialBridgeObject( index=0, name="Climate0", status=0, human_status="off", type="climate", val=[ [221, 0, "U", "M", 50, 0, 0, "U"], [0, 0, "O", "A", 0, 0, 0, "N"], [0, 0], ], protected=0, zone="Living room", power=0.0, power_unit=WATT, ), } await hass.config_entries.async_reload(mock_serial_bridge_config_entry.entry_id) await hass.async_block_till_done() assert (state := hass.states.get(ENTITY_ID)) is None