hass-core/tests/components/modbus/test_climate.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1181 lines
36 KiB
Python
Raw Normal View History

"""The tests for the Modbus climate component."""
import pytest
from homeassistant.components.climate import (
ATTR_FAN_MODE,
ATTR_FAN_MODES,
ATTR_HVAC_MODE,
ATTR_HVAC_MODES,
ATTR_SWING_MODE,
ATTR_SWING_MODES,
DOMAIN as CLIMATE_DOMAIN,
FAN_AUTO,
FAN_DIFFUSE,
FAN_FOCUS,
FAN_HIGH,
FAN_LOW,
FAN_MEDIUM,
FAN_MIDDLE,
FAN_OFF,
FAN_ON,
FAN_TOP,
SWING_BOTH,
SWING_HORIZONTAL,
SWING_OFF,
SWING_ON,
SWING_VERTICAL,
HVACMode,
)
from homeassistant.components.modbus.const import (
CONF_CLIMATES,
CONF_DATA_TYPE,
CONF_DEVICE_ADDRESS,
CONF_FAN_MODE_AUTO,
CONF_FAN_MODE_HIGH,
CONF_FAN_MODE_LOW,
CONF_FAN_MODE_MEDIUM,
CONF_FAN_MODE_OFF,
CONF_FAN_MODE_ON,
CONF_FAN_MODE_REGISTER,
CONF_FAN_MODE_TOP,
CONF_FAN_MODE_VALUES,
CONF_HVAC_MODE_AUTO,
CONF_HVAC_MODE_COOL,
CONF_HVAC_MODE_DRY,
CONF_HVAC_MODE_FAN_ONLY,
CONF_HVAC_MODE_HEAT,
CONF_HVAC_MODE_HEAT_COOL,
CONF_HVAC_MODE_OFF,
CONF_HVAC_MODE_REGISTER,
CONF_HVAC_MODE_VALUES,
CONF_HVAC_ONOFF_REGISTER,
CONF_MAX_TEMP,
CONF_MIN_TEMP,
CONF_SWING_MODE_REGISTER,
CONF_SWING_MODE_SWING_BOTH,
CONF_SWING_MODE_SWING_HORIZ,
CONF_SWING_MODE_SWING_OFF,
CONF_SWING_MODE_SWING_ON,
CONF_SWING_MODE_SWING_VERT,
CONF_SWING_MODE_VALUES,
CONF_TARGET_TEMP,
CONF_TARGET_TEMP_WRITE_REGISTERS,
CONF_WRITE_REGISTERS,
MODBUS_DOMAIN,
2021-10-15 07:09:59 +02:00
DataType,
)
from homeassistant.const import (
ATTR_TEMPERATURE,
CONF_ADDRESS,
CONF_NAME,
CONF_SCAN_INTERVAL,
CONF_SLAVE,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant, State
from homeassistant.setup import async_setup_component
from .conftest import TEST_ENTITY_NAME, ReadResult
ENTITY_ID = f"{CLIMATE_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
2021-08-17 20:43:27 +02:00
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
}
],
},
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_DEVICE_ADDRESS: 10,
}
],
},
{
CONF_CLIMATES: [
{
2021-08-17 20:43:27 +02:00
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 20,
CONF_DATA_TYPE: DataType.INT32,
}
],
},
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_ONOFF_REGISTER: 12,
}
],
},
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_ONOFF_REGISTER: 12,
CONF_TARGET_TEMP_WRITE_REGISTERS: True,
CONF_WRITE_REGISTERS: True,
}
],
},
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: [130, 131, 132, 133, 135, 128, 129],
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_ONOFF_REGISTER: 12,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 11,
CONF_HVAC_MODE_VALUES: {
"state_off": 0,
"state_heat": 1,
"state_cool": 2,
"state_heat_cool": 3,
"state_dry": 4,
"state_fan_only": 5,
"state_auto": 6,
},
},
}
],
},
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_ONOFF_REGISTER: 12,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 11,
CONF_WRITE_REGISTERS: True,
CONF_HVAC_MODE_VALUES: {
"state_off": 0,
"state_heat": 1,
"state_cool": 2,
"state_heat_cool": 3,
"state_dry": 4,
"state_fan_only": 5,
"state_auto": 6,
},
},
}
],
},
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_MIN_TEMP: 23,
CONF_MAX_TEMP: 57,
}
],
},
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_MIN_TEMP: -57,
CONF_MAX_TEMP: -23,
}
],
},
],
)
async def test_config_climate(hass: HomeAssistant, mock_modbus) -> None:
"""Run configuration test for climate."""
assert CLIMATE_DOMAIN in hass.config.components
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 11,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_OFF: 0,
CONF_HVAC_MODE_HEAT: 1,
CONF_HVAC_MODE_COOL: 2,
CONF_HVAC_MODE_HEAT_COOL: 3,
CONF_HVAC_MODE_AUTO: 4,
CONF_HVAC_MODE_FAN_ONLY: 5,
},
},
}
],
},
],
)
async def test_config_hvac_mode_register(hass: HomeAssistant, mock_modbus) -> None:
"""Run configuration test for HVAC mode register."""
state = hass.states.get(ENTITY_ID)
assert HVACMode.OFF in state.attributes[ATTR_HVAC_MODES]
assert HVACMode.HEAT in state.attributes[ATTR_HVAC_MODES]
assert HVACMode.COOL in state.attributes[ATTR_HVAC_MODES]
assert HVACMode.HEAT_COOL in state.attributes[ATTR_HVAC_MODES]
assert HVACMode.AUTO in state.attributes[ATTR_HVAC_MODES]
assert HVACMode.FAN_ONLY in state.attributes[ATTR_HVAC_MODES]
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_FAN_MODE_REGISTER: {
CONF_ADDRESS: 11,
CONF_FAN_MODE_VALUES: {
CONF_FAN_MODE_ON: 0,
CONF_FAN_MODE_OFF: 1,
CONF_FAN_MODE_AUTO: 2,
CONF_FAN_MODE_LOW: 3,
CONF_FAN_MODE_MEDIUM: 4,
CONF_FAN_MODE_HIGH: 5,
},
},
}
],
},
],
)
async def test_config_fan_mode_register(hass: HomeAssistant, mock_modbus) -> None:
"""Run configuration test for Fan mode register."""
state = hass.states.get(ENTITY_ID)
assert FAN_ON in state.attributes[ATTR_FAN_MODES]
assert FAN_OFF in state.attributes[ATTR_FAN_MODES]
assert FAN_AUTO in state.attributes[ATTR_FAN_MODES]
assert FAN_LOW in state.attributes[ATTR_FAN_MODES]
assert FAN_MEDIUM in state.attributes[ATTR_FAN_MODES]
assert FAN_HIGH in state.attributes[ATTR_FAN_MODES]
assert FAN_TOP not in state.attributes[ATTR_FAN_MODES]
assert FAN_MIDDLE not in state.attributes[ATTR_FAN_MODES]
assert FAN_DIFFUSE not in state.attributes[ATTR_FAN_MODES]
assert FAN_FOCUS not in state.attributes[ATTR_FAN_MODES]
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: 11,
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_ON: 0,
CONF_SWING_MODE_SWING_OFF: 1,
CONF_SWING_MODE_SWING_BOTH: 2,
CONF_SWING_MODE_SWING_HORIZ: 3,
CONF_SWING_MODE_SWING_VERT: 4,
},
},
}
],
},
],
)
async def test_config_swing_mode_register(hass: HomeAssistant, mock_modbus) -> None:
"""Run configuration test for Fan mode register."""
state = hass.states.get(ENTITY_ID)
assert SWING_ON in state.attributes[ATTR_SWING_MODES]
assert SWING_OFF in state.attributes[ATTR_SWING_MODES]
assert SWING_BOTH in state.attributes[ATTR_SWING_MODES]
assert SWING_HORIZONTAL in state.attributes[ATTR_SWING_MODES]
assert SWING_VERTICAL in state.attributes[ATTR_SWING_MODES]
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_ONOFF_REGISTER: 11,
}
],
},
],
)
async def test_config_hvac_onoff_register(hass: HomeAssistant, mock_modbus) -> None:
"""Run configuration test for On/Off register."""
state = hass.states.get(ENTITY_ID)
assert HVACMode.OFF in state.attributes[ATTR_HVAC_MODES]
assert HVACMode.AUTO in state.attributes[ATTR_HVAC_MODES]
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_SLAVE: 1,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_DATA_TYPE: DataType.INT32,
},
],
},
],
)
@pytest.mark.parametrize(
("register_words", "expected"),
[
(
[0x00, 0x00],
"auto",
),
],
)
async def test_temperature_climate(
hass: HomeAssistant, expected, mock_do_cycle
) -> None:
"""Run test for given config."""
assert hass.states.get(ENTITY_ID).state == expected
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_SLAVE: 1,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_DATA_TYPE: DataType.INT32,
},
],
},
],
)
@pytest.mark.parametrize(
("register_words", "expected"),
[
(
None,
"unavailable",
),
],
)
async def test_temperature_error(hass: HomeAssistant, expected, mock_do_cycle) -> None:
"""Run test for given config."""
assert hass.states.get(ENTITY_ID).state == expected
@pytest.mark.parametrize(
("do_config", "result", "register_words"),
[
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: [130, 131, 132, 133, 134, 135, 136],
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_COOL: 0,
CONF_HVAC_MODE_HEAT: 1,
CONF_HVAC_MODE_DRY: 2,
},
},
},
]
},
HVACMode.COOL,
[0x00],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 119,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_COOL: 0,
CONF_HVAC_MODE_HEAT: 1,
CONF_HVAC_MODE_DRY: 2,
},
},
},
]
},
HVACMode.HEAT,
[0x01],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 120,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_COOL: 0,
CONF_HVAC_MODE_HEAT: 2,
CONF_HVAC_MODE_DRY: 3,
},
},
CONF_HVAC_ONOFF_REGISTER: 119,
},
]
},
HVACMode.OFF,
[0x00],
),
],
)
async def test_service_climate_update(
2024-04-17 19:10:09 +02:00
hass: HomeAssistant, mock_modbus_ha, result, register_words
) -> None:
"""Run test for service homeassistant.update_entity."""
2024-04-17 19:10:09 +02:00
mock_modbus_ha.read_holding_registers.return_value = ReadResult(register_words)
await hass.services.async_call(
2021-06-30 14:34:33 +02:00
"homeassistant", "update_entity", {"entity_id": ENTITY_ID}, blocking=True
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).state == result
@pytest.mark.parametrize(
("do_config", "result", "register_words"),
[
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_FAN_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_FAN_MODE_VALUES: {
CONF_FAN_MODE_LOW: 0,
CONF_FAN_MODE_MEDIUM: 1,
CONF_FAN_MODE_HIGH: 2,
},
},
},
]
},
FAN_LOW,
[0x00],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_FAN_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_FAN_MODE_VALUES: {
CONF_FAN_MODE_LOW: 0,
CONF_FAN_MODE_MEDIUM: 1,
CONF_FAN_MODE_HIGH: 2,
},
},
},
]
},
FAN_MEDIUM,
[0x01],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_FAN_MODE_REGISTER: {
CONF_ADDRESS: [118],
CONF_FAN_MODE_VALUES: {
CONF_FAN_MODE_LOW: 0,
CONF_FAN_MODE_MEDIUM: 1,
CONF_FAN_MODE_HIGH: 2,
},
},
CONF_HVAC_ONOFF_REGISTER: 119,
},
]
},
FAN_HIGH,
[0x02],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_FAN_MODE_REGISTER: {
CONF_ADDRESS: [118],
CONF_FAN_MODE_VALUES: {
CONF_FAN_MODE_LOW: 0,
CONF_FAN_MODE_MEDIUM: 1,
CONF_FAN_MODE_HIGH: 2,
CONF_FAN_MODE_TOP: 3,
},
},
},
]
},
FAN_TOP,
[0x03],
),
],
)
async def test_service_climate_fan_update(
2024-04-17 19:10:09 +02:00
hass: HomeAssistant, mock_modbus_ha, result, register_words
) -> None:
"""Run test for service homeassistant.update_entity."""
2024-04-17 19:10:09 +02:00
mock_modbus_ha.read_holding_registers.return_value = ReadResult(register_words)
await hass.services.async_call(
"homeassistant", "update_entity", {"entity_id": ENTITY_ID}, blocking=True
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).attributes[ATTR_FAN_MODE] == result
@pytest.mark.parametrize(
("do_config", "result", "register_words"),
[
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: [118],
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_OFF: 0,
CONF_SWING_MODE_SWING_ON: 1,
CONF_SWING_MODE_SWING_BOTH: 2,
},
},
},
]
},
SWING_BOTH,
[0x02],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: [118],
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_OFF: 0,
CONF_SWING_MODE_SWING_ON: 1,
CONF_SWING_MODE_SWING_VERT: 2,
},
},
},
]
},
SWING_ON,
[0x01],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: [118],
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_OFF: 0,
CONF_SWING_MODE_SWING_ON: 1,
CONF_SWING_MODE_SWING_HORIZ: 3,
},
},
CONF_HVAC_ONOFF_REGISTER: 119,
},
]
},
SWING_HORIZONTAL,
[0x03],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_OFF: 0,
CONF_SWING_MODE_SWING_ON: 1,
CONF_SWING_MODE_SWING_VERT: 2,
CONF_SWING_MODE_SWING_BOTH: 3,
},
},
},
]
},
SWING_OFF,
[0x00],
),
(
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 116,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SCAN_INTERVAL: 0,
CONF_DATA_TYPE: DataType.INT32,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_OFF: 0,
CONF_SWING_MODE_SWING_ON: 1,
CONF_SWING_MODE_SWING_VERT: 2,
CONF_SWING_MODE_SWING_BOTH: 3,
},
},
},
]
},
STATE_UNKNOWN,
[0x05],
),
],
)
async def test_service_climate_swing_update(
2024-04-17 19:10:09 +02:00
hass: HomeAssistant, mock_modbus_ha, result, register_words
) -> None:
"""Run test for service homeassistant.update_entity."""
2024-04-17 19:10:09 +02:00
mock_modbus_ha.read_holding_registers.return_value = ReadResult(register_words)
await hass.services.async_call(
"homeassistant", "update_entity", {"entity_id": ENTITY_ID}, blocking=True
)
await hass.async_block_till_done()
assert hass.states.get(ENTITY_ID).attributes[ATTR_SWING_MODE] == result
@pytest.mark.parametrize(
("temperature", "result", "do_config"),
[
(
31,
[0x00],
{
CONF_CLIMATES: [
{
2021-08-17 20:43:27 +02:00
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
2021-10-15 07:09:59 +02:00
CONF_DATA_TYPE: DataType.INT16,
}
]
},
),
(
32,
[0x00, 0x00],
{
CONF_CLIMATES: [
{
2021-08-17 20:43:27 +02:00
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
2021-10-15 07:09:59 +02:00
CONF_DATA_TYPE: DataType.INT32,
}
]
},
),
(
33.5,
[0x00, 0x00],
{
CONF_CLIMATES: [
{
2021-08-17 20:43:27 +02:00
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
2021-10-15 07:09:59 +02:00
CONF_DATA_TYPE: DataType.FLOAT32,
}
]
},
),
(
"34",
[0x00, 0x00, 0x00, 0x00],
{
CONF_CLIMATES: [
{
2021-08-17 20:43:27 +02:00
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
2021-10-15 07:09:59 +02:00
CONF_DATA_TYPE: DataType.FLOAT64,
}
]
},
),
(
25,
[0x00],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: [150, 151, 152, 153, 154, 155, 156],
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_DATA_TYPE: DataType.INT16,
CONF_TARGET_TEMP_WRITE_REGISTERS: True,
}
]
},
),
],
)
async def test_service_climate_set_temperature(
2024-04-17 19:10:09 +02:00
hass: HomeAssistant, temperature, result, mock_modbus_ha
) -> None:
"""Test set_temperature."""
2024-04-17 19:10:09 +02:00
mock_modbus_ha.read_holding_registers.return_value = ReadResult(result)
await hass.services.async_call(
CLIMATE_DOMAIN,
"set_temperature",
{
"entity_id": ENTITY_ID,
ATTR_TEMPERATURE: temperature,
},
blocking=True,
)
@pytest.mark.parametrize(
("hvac_mode", "result", "do_config"),
[
(
HVACMode.COOL,
[0x00],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_COOL: 1,
CONF_HVAC_MODE_HEAT: 2,
},
},
}
]
},
),
(
HVACMode.HEAT,
[0x00],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_COOL: 1,
CONF_HVAC_MODE_HEAT: 2,
},
},
CONF_HVAC_ONOFF_REGISTER: 119,
}
]
},
),
(
HVACMode.HEAT,
[0x00],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_COOL: 1,
CONF_HVAC_MODE_HEAT: 2,
},
CONF_WRITE_REGISTERS: True,
},
CONF_HVAC_ONOFF_REGISTER: 119,
}
]
},
),
(
HVACMode.OFF,
[0x00],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_HVAC_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_HVAC_MODE_VALUES: {
CONF_HVAC_MODE_COOL: 1,
CONF_HVAC_MODE_HEAT: 2,
},
},
CONF_HVAC_ONOFF_REGISTER: 119,
CONF_WRITE_REGISTERS: True,
}
]
},
),
],
)
async def test_service_set_hvac_mode(
2024-04-17 19:10:09 +02:00
hass: HomeAssistant, hvac_mode, result, mock_modbus_ha
) -> None:
"""Test set HVAC mode."""
2024-04-17 19:10:09 +02:00
mock_modbus_ha.read_holding_registers.return_value = ReadResult(result)
await hass.services.async_call(
CLIMATE_DOMAIN,
"set_hvac_mode",
{
"entity_id": ENTITY_ID,
ATTR_HVAC_MODE: hvac_mode,
},
blocking=True,
)
@pytest.mark.parametrize(
("fan_mode", "result", "do_config"),
[
(
FAN_OFF,
[0x02],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_FAN_MODE_REGISTER: {
CONF_ADDRESS: [118],
CONF_FAN_MODE_VALUES: {
CONF_FAN_MODE_ON: 1,
CONF_FAN_MODE_OFF: 2,
},
},
}
]
},
),
(
FAN_ON,
[0x01],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_FAN_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_FAN_MODE_VALUES: {
CONF_FAN_MODE_ON: 1,
CONF_FAN_MODE_OFF: 2,
},
},
}
]
},
),
],
)
async def test_service_set_fan_mode(
2024-04-17 19:10:09 +02:00
hass: HomeAssistant, fan_mode, result, mock_modbus_ha
) -> None:
"""Test set Fan mode."""
2024-04-17 19:10:09 +02:00
mock_modbus_ha.read_holding_registers.return_value = ReadResult(result)
await hass.services.async_call(
CLIMATE_DOMAIN,
"set_fan_mode",
{
"entity_id": ENTITY_ID,
ATTR_FAN_MODE: fan_mode,
},
blocking=True,
)
@pytest.mark.parametrize(
("swing_mode", "result", "do_config"),
[
(
SWING_OFF,
[0x00],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: [118],
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_ON: 1,
CONF_SWING_MODE_SWING_OFF: 0,
},
},
}
]
},
),
(
SWING_ON,
[0x01],
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
CONF_SWING_MODE_REGISTER: {
CONF_ADDRESS: 118,
CONF_SWING_MODE_VALUES: {
CONF_SWING_MODE_SWING_ON: 1,
CONF_SWING_MODE_SWING_OFF: 0,
},
},
}
]
},
),
],
)
async def test_service_set_swing_mode(
2024-04-17 19:10:09 +02:00
hass: HomeAssistant, swing_mode, result, mock_modbus_ha
) -> None:
"""Test set Swing mode."""
2024-04-17 19:10:09 +02:00
mock_modbus_ha.read_holding_registers.return_value = ReadResult(result)
await hass.services.async_call(
CLIMATE_DOMAIN,
"set_swing_mode",
{
"entity_id": ENTITY_ID,
ATTR_SWING_MODE: swing_mode,
},
blocking=True,
)
2021-06-30 14:34:33 +02:00
test_value = State(ENTITY_ID, 35)
test_value.attributes = {ATTR_TEMPERATURE: 37}
@pytest.mark.parametrize(
"mock_test_state",
[(test_value,)],
indirect=True,
)
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
2021-08-17 20:43:27 +02:00
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SCAN_INTERVAL: 0,
}
],
},
],
)
async def test_restore_state_climate(
hass: HomeAssistant, mock_test_state, mock_modbus
) -> None:
"""Run test for sensor restore state."""
2021-06-30 14:34:33 +02:00
state = hass.states.get(ENTITY_ID)
2022-04-26 09:18:00 +02:00
assert state.state == HVACMode.AUTO
assert state.attributes[ATTR_TEMPERATURE] == 37
@pytest.mark.parametrize(
"do_config",
[
{
CONF_CLIMATES: [
{
CONF_NAME: TEST_ENTITY_NAME,
CONF_TARGET_TEMP: 117,
CONF_ADDRESS: 117,
CONF_SLAVE: 10,
}
],
},
],
)
@pytest.mark.parametrize(
("config_addon", "register_words"),
[
(
{
CONF_DATA_TYPE: DataType.INT16,
},
[7, 9],
),
(
{
CONF_DATA_TYPE: DataType.INT32,
},
[7],
),
],
)
async def test_wrong_unpack_climate(hass: HomeAssistant, mock_do_cycle) -> None:
"""Run test for sensor."""
assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE
async def test_no_discovery_info_climate(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test setup without discovery info."""
assert CLIMATE_DOMAIN not in hass.config.components
assert await async_setup_component(
hass,
CLIMATE_DOMAIN,
{CLIMATE_DOMAIN: {"platform": MODBUS_DOMAIN}},
)
await hass.async_block_till_done()
assert CLIMATE_DOMAIN in hass.config.components