mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Add modbus option to manage different setPoint registers (#107600)
Co-authored-by: jan iversen <jancasacondor@gmail.com>
This commit is contained in:
parent
53944235d2
commit
1ded412061
@ -134,7 +134,9 @@ from .const import ( # noqa: F401
|
|||||||
from .modbus import ModbusHub, async_modbus_setup
|
from .modbus import ModbusHub, async_modbus_setup
|
||||||
from .validators import (
|
from .validators import (
|
||||||
check_config,
|
check_config,
|
||||||
|
check_hvac_target_temp_registers,
|
||||||
duplicate_fan_mode_validator,
|
duplicate_fan_mode_validator,
|
||||||
|
hvac_fixedsize_reglist_validator,
|
||||||
nan_validator,
|
nan_validator,
|
||||||
register_int_list_validator,
|
register_int_list_validator,
|
||||||
struct_validator,
|
struct_validator,
|
||||||
@ -239,7 +241,7 @@ BASE_SWITCH_SCHEMA = BASE_COMPONENT_SCHEMA.extend(
|
|||||||
CLIMATE_SCHEMA = vol.All(
|
CLIMATE_SCHEMA = vol.All(
|
||||||
BASE_STRUCT_SCHEMA.extend(
|
BASE_STRUCT_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
vol.Required(CONF_TARGET_TEMP): cv.positive_int,
|
vol.Required(CONF_TARGET_TEMP): hvac_fixedsize_reglist_validator,
|
||||||
vol.Optional(CONF_TARGET_TEMP_WRITE_REGISTERS, default=False): cv.boolean,
|
vol.Optional(CONF_TARGET_TEMP_WRITE_REGISTERS, default=False): cv.boolean,
|
||||||
vol.Optional(CONF_MAX_TEMP, default=35): vol.Coerce(float),
|
vol.Optional(CONF_MAX_TEMP, default=35): vol.Coerce(float),
|
||||||
vol.Optional(CONF_MIN_TEMP, default=5): vol.Coerce(float),
|
vol.Optional(CONF_MIN_TEMP, default=5): vol.Coerce(float),
|
||||||
@ -296,8 +298,9 @@ CLIMATE_SCHEMA = vol.All(
|
|||||||
duplicate_fan_mode_validator,
|
duplicate_fan_mode_validator,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
|
check_hvac_target_temp_registers,
|
||||||
)
|
)
|
||||||
|
|
||||||
COVERS_SCHEMA = BASE_COMPONENT_SCHEMA.extend(
|
COVERS_SCHEMA = BASE_COMPONENT_SCHEMA.extend(
|
||||||
|
@ -75,6 +75,17 @@ from .modbus import ModbusHub
|
|||||||
|
|
||||||
PARALLEL_UPDATES = 1
|
PARALLEL_UPDATES = 1
|
||||||
|
|
||||||
|
HVACMODE_TO_TARG_TEMP_REG_INDEX_ARRAY = {
|
||||||
|
HVACMode.AUTO: 0,
|
||||||
|
HVACMode.COOL: 1,
|
||||||
|
HVACMode.DRY: 2,
|
||||||
|
HVACMode.FAN_ONLY: 3,
|
||||||
|
HVACMode.HEAT: 4,
|
||||||
|
HVACMode.HEAT_COOL: 5,
|
||||||
|
HVACMode.OFF: 6,
|
||||||
|
None: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -117,7 +128,6 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
|||||||
CONF_TARGET_TEMP_WRITE_REGISTERS
|
CONF_TARGET_TEMP_WRITE_REGISTERS
|
||||||
]
|
]
|
||||||
self._unit = config[CONF_TEMPERATURE_UNIT]
|
self._unit = config[CONF_TEMPERATURE_UNIT]
|
||||||
|
|
||||||
self._attr_current_temperature = None
|
self._attr_current_temperature = None
|
||||||
self._attr_target_temperature = None
|
self._attr_target_temperature = None
|
||||||
self._attr_temperature_unit = (
|
self._attr_temperature_unit = (
|
||||||
@ -157,7 +167,6 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
|||||||
for value in values:
|
for value in values:
|
||||||
self._hvac_mode_mapping.append((value, hvac_mode))
|
self._hvac_mode_mapping.append((value, hvac_mode))
|
||||||
self._attr_hvac_modes.append(hvac_mode)
|
self._attr_hvac_modes.append(hvac_mode)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# No HVAC modes defined
|
# No HVAC modes defined
|
||||||
self._hvac_mode_register = None
|
self._hvac_mode_register = None
|
||||||
@ -305,21 +314,27 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
|||||||
if self._target_temperature_write_registers:
|
if self._target_temperature_write_registers:
|
||||||
result = await self._hub.async_pb_call(
|
result = await self._hub.async_pb_call(
|
||||||
self._slave,
|
self._slave,
|
||||||
self._target_temperature_register,
|
self._target_temperature_register[
|
||||||
|
HVACMODE_TO_TARG_TEMP_REG_INDEX_ARRAY[self._attr_hvac_mode]
|
||||||
|
],
|
||||||
[int(float(registers[0]))],
|
[int(float(registers[0]))],
|
||||||
CALL_TYPE_WRITE_REGISTERS,
|
CALL_TYPE_WRITE_REGISTERS,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result = await self._hub.async_pb_call(
|
result = await self._hub.async_pb_call(
|
||||||
self._slave,
|
self._slave,
|
||||||
self._target_temperature_register,
|
self._target_temperature_register[
|
||||||
|
HVACMODE_TO_TARG_TEMP_REG_INDEX_ARRAY[self._attr_hvac_mode]
|
||||||
|
],
|
||||||
int(float(registers[0])),
|
int(float(registers[0])),
|
||||||
CALL_TYPE_WRITE_REGISTER,
|
CALL_TYPE_WRITE_REGISTER,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result = await self._hub.async_pb_call(
|
result = await self._hub.async_pb_call(
|
||||||
self._slave,
|
self._slave,
|
||||||
self._target_temperature_register,
|
self._target_temperature_register[
|
||||||
|
HVACMODE_TO_TARG_TEMP_REG_INDEX_ARRAY[self._attr_hvac_mode]
|
||||||
|
],
|
||||||
[int(float(i)) for i in registers],
|
[int(float(i)) for i in registers],
|
||||||
CALL_TYPE_WRITE_REGISTERS,
|
CALL_TYPE_WRITE_REGISTERS,
|
||||||
)
|
)
|
||||||
@ -332,12 +347,15 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
|||||||
# async_track_time_interval
|
# async_track_time_interval
|
||||||
|
|
||||||
self._attr_target_temperature = await self._async_read_register(
|
self._attr_target_temperature = await self._async_read_register(
|
||||||
CALL_TYPE_REGISTER_HOLDING, self._target_temperature_register
|
CALL_TYPE_REGISTER_HOLDING,
|
||||||
|
self._target_temperature_register[
|
||||||
|
HVACMODE_TO_TARG_TEMP_REG_INDEX_ARRAY[self._attr_hvac_mode]
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
self._attr_current_temperature = await self._async_read_register(
|
self._attr_current_temperature = await self._async_read_register(
|
||||||
self._input_type, self._address
|
self._input_type, self._address
|
||||||
)
|
)
|
||||||
|
|
||||||
# Read the HVAC mode register if defined
|
# Read the HVAC mode register if defined
|
||||||
if self._hvac_mode_register is not None:
|
if self._hvac_mode_register is not None:
|
||||||
hvac_mode = await self._async_read_register(
|
hvac_mode = await self._async_read_register(
|
||||||
|
@ -8,6 +8,7 @@ from typing import Any
|
|||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.climate import HVACMode
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_ADDRESS,
|
CONF_ADDRESS,
|
||||||
CONF_COMMAND_OFF,
|
CONF_COMMAND_OFF,
|
||||||
@ -29,6 +30,7 @@ from .const import (
|
|||||||
CONF_FAN_MODE_REGISTER,
|
CONF_FAN_MODE_REGISTER,
|
||||||
CONF_FAN_MODE_VALUES,
|
CONF_FAN_MODE_VALUES,
|
||||||
CONF_HVAC_MODE_REGISTER,
|
CONF_HVAC_MODE_REGISTER,
|
||||||
|
CONF_HVAC_ONOFF_REGISTER,
|
||||||
CONF_INPUT_TYPE,
|
CONF_INPUT_TYPE,
|
||||||
CONF_SLAVE_COUNT,
|
CONF_SLAVE_COUNT,
|
||||||
CONF_SWAP,
|
CONF_SWAP,
|
||||||
@ -172,6 +174,26 @@ def struct_validator(config: dict[str, Any]) -> dict[str, Any]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def hvac_fixedsize_reglist_validator(value: Any) -> list:
|
||||||
|
"""Check the number of registers for target temp. and coerce it to a list, if valid."""
|
||||||
|
if isinstance(value, int):
|
||||||
|
value = [value] * len(HVACMode)
|
||||||
|
return list(value)
|
||||||
|
|
||||||
|
if len(value) == len(HVACMode):
|
||||||
|
_rv = True
|
||||||
|
for svalue in value:
|
||||||
|
if isinstance(svalue, int) is False:
|
||||||
|
_rv = False
|
||||||
|
break
|
||||||
|
if _rv is True:
|
||||||
|
return list(value)
|
||||||
|
|
||||||
|
raise vol.Invalid(
|
||||||
|
f"Invalid target temp register. Required type: integer, allowed 1 or list of {len(HVACMode)} registers"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def nan_validator(value: Any) -> int:
|
def nan_validator(value: Any) -> int:
|
||||||
"""Convert nan string to number (can be hex string or int)."""
|
"""Convert nan string to number (can be hex string or int)."""
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
@ -203,6 +225,34 @@ def duplicate_fan_mode_validator(config: dict[str, Any]) -> dict:
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def check_hvac_target_temp_registers(config: dict) -> dict:
|
||||||
|
"""Check conflicts among HVAC target temperature registers and HVAC ON/OFF, HVAC register, Fan Modes."""
|
||||||
|
|
||||||
|
if (
|
||||||
|
CONF_HVAC_MODE_REGISTER in config
|
||||||
|
and config[CONF_HVAC_MODE_REGISTER][CONF_ADDRESS] in config[CONF_TARGET_TEMP]
|
||||||
|
):
|
||||||
|
wrn = f"{CONF_HVAC_MODE_REGISTER} overlaps CONF_TARGET_TEMP register(s). {CONF_HVAC_MODE_REGISTER} is not loaded!"
|
||||||
|
_LOGGER.warning(wrn)
|
||||||
|
del config[CONF_HVAC_MODE_REGISTER]
|
||||||
|
if (
|
||||||
|
CONF_HVAC_ONOFF_REGISTER in config
|
||||||
|
and config[CONF_HVAC_ONOFF_REGISTER] in config[CONF_TARGET_TEMP]
|
||||||
|
):
|
||||||
|
wrn = f"{CONF_HVAC_ONOFF_REGISTER} overlaps CONF_TARGET_TEMP register(s). {CONF_HVAC_ONOFF_REGISTER} is not loaded!"
|
||||||
|
_LOGGER.warning(wrn)
|
||||||
|
del config[CONF_HVAC_ONOFF_REGISTER]
|
||||||
|
if (
|
||||||
|
CONF_FAN_MODE_REGISTER in config
|
||||||
|
and config[CONF_FAN_MODE_REGISTER][CONF_ADDRESS] in config[CONF_TARGET_TEMP]
|
||||||
|
):
|
||||||
|
wrn = f"{CONF_FAN_MODE_REGISTER} overlaps CONF_TARGET_TEMP register(s). {CONF_FAN_MODE_REGISTER} is not loaded!"
|
||||||
|
_LOGGER.warning(wrn)
|
||||||
|
del config[CONF_FAN_MODE_REGISTER]
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
def register_int_list_validator(value: Any) -> Any:
|
def register_int_list_validator(value: Any) -> Any:
|
||||||
"""Check if a register (CONF_ADRESS) is an int or a list having only 1 register."""
|
"""Check if a register (CONF_ADRESS) is an int or a list having only 1 register."""
|
||||||
if isinstance(value, int) and value >= 0:
|
if isinstance(value, int) and value >= 0:
|
||||||
|
@ -129,7 +129,7 @@ ENTITY_ID = f"{CLIMATE_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: [130, 131, 132, 133, 135, 128, 129],
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_HVAC_ONOFF_REGISTER: 12,
|
CONF_HVAC_ONOFF_REGISTER: 12,
|
||||||
@ -374,7 +374,7 @@ async def test_temperature_error(hass: HomeAssistant, expected, mock_do_cycle) -
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: [130, 131, 132, 133, 134, 135, 136],
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_SCAN_INTERVAL: 0,
|
CONF_SCAN_INTERVAL: 0,
|
||||||
@ -398,7 +398,7 @@ async def test_temperature_error(hass: HomeAssistant, expected, mock_do_cycle) -
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: 119,
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_SCAN_INTERVAL: 0,
|
CONF_SCAN_INTERVAL: 0,
|
||||||
@ -422,7 +422,7 @@ async def test_temperature_error(hass: HomeAssistant, expected, mock_do_cycle) -
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: 120,
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_SCAN_INTERVAL: 0,
|
CONF_SCAN_INTERVAL: 0,
|
||||||
@ -464,7 +464,7 @@ async def test_service_climate_update(
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: 116,
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_SCAN_INTERVAL: 0,
|
CONF_SCAN_INTERVAL: 0,
|
||||||
@ -488,7 +488,7 @@ async def test_service_climate_update(
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: 116,
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_SCAN_INTERVAL: 0,
|
CONF_SCAN_INTERVAL: 0,
|
||||||
@ -512,7 +512,7 @@ async def test_service_climate_update(
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: 116,
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_SCAN_INTERVAL: 0,
|
CONF_SCAN_INTERVAL: 0,
|
||||||
@ -641,7 +641,7 @@ async def test_service_climate_fan_update(
|
|||||||
CONF_CLIMATES: [
|
CONF_CLIMATES: [
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME,
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: [150, 151, 152, 153, 154, 155, 156],
|
||||||
CONF_ADDRESS: 117,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 10,
|
CONF_SLAVE: 10,
|
||||||
CONF_DATA_TYPE: DataType.INT16,
|
CONF_DATA_TYPE: DataType.INT16,
|
||||||
@ -767,6 +767,7 @@ async def test_service_set_hvac_mode(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test set HVAC mode."""
|
"""Test set HVAC mode."""
|
||||||
mock_modbus.read_holding_registers.return_value = ReadResult(result)
|
mock_modbus.read_holding_registers.return_value = ReadResult(result)
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
CLIMATE_DOMAIN,
|
CLIMATE_DOMAIN,
|
||||||
"set_hvac_mode",
|
"set_hvac_mode",
|
||||||
|
@ -50,9 +50,12 @@ from homeassistant.components.modbus.const import (
|
|||||||
CONF_FAN_MODE_REGISTER,
|
CONF_FAN_MODE_REGISTER,
|
||||||
CONF_FAN_MODE_VALUES,
|
CONF_FAN_MODE_VALUES,
|
||||||
CONF_HVAC_MODE_COOL,
|
CONF_HVAC_MODE_COOL,
|
||||||
|
CONF_HVAC_MODE_DRY,
|
||||||
CONF_HVAC_MODE_HEAT,
|
CONF_HVAC_MODE_HEAT,
|
||||||
|
CONF_HVAC_MODE_HEAT_COOL,
|
||||||
CONF_HVAC_MODE_REGISTER,
|
CONF_HVAC_MODE_REGISTER,
|
||||||
CONF_HVAC_MODE_VALUES,
|
CONF_HVAC_MODE_VALUES,
|
||||||
|
CONF_HVAC_ONOFF_REGISTER,
|
||||||
CONF_INPUT_TYPE,
|
CONF_INPUT_TYPE,
|
||||||
CONF_MSG_WAIT,
|
CONF_MSG_WAIT,
|
||||||
CONF_PARITY,
|
CONF_PARITY,
|
||||||
@ -80,7 +83,9 @@ from homeassistant.components.modbus.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.components.modbus.validators import (
|
from homeassistant.components.modbus.validators import (
|
||||||
check_config,
|
check_config,
|
||||||
|
check_hvac_target_temp_registers,
|
||||||
duplicate_fan_mode_validator,
|
duplicate_fan_mode_validator,
|
||||||
|
hvac_fixedsize_reglist_validator,
|
||||||
nan_validator,
|
nan_validator,
|
||||||
register_int_list_validator,
|
register_int_list_validator,
|
||||||
struct_validator,
|
struct_validator,
|
||||||
@ -137,6 +142,22 @@ async def mock_modbus_with_pymodbus_fixture(hass, caplog, do_config, mock_pymodb
|
|||||||
return mock_pymodbus
|
return mock_pymodbus
|
||||||
|
|
||||||
|
|
||||||
|
async def test_fixedRegList_validator() -> None:
|
||||||
|
"""Test fixed temp registers validator."""
|
||||||
|
|
||||||
|
for value in (
|
||||||
|
15,
|
||||||
|
[30, 31, 32, 33, 34, 35, 36],
|
||||||
|
):
|
||||||
|
assert isinstance(hvac_fixedsize_reglist_validator(value), list)
|
||||||
|
|
||||||
|
with pytest.raises(vol.Invalid):
|
||||||
|
hvac_fixedsize_reglist_validator([15, "ab", 17, 18, 19, 20, 21])
|
||||||
|
|
||||||
|
with pytest.raises(vol.Invalid):
|
||||||
|
hvac_fixedsize_reglist_validator([15, 17])
|
||||||
|
|
||||||
|
|
||||||
async def test_register_int_list_validator() -> None:
|
async def test_register_int_list_validator() -> None:
|
||||||
"""Test conf address register validator."""
|
"""Test conf address register validator."""
|
||||||
for value, vtype in (
|
for value, vtype in (
|
||||||
@ -536,7 +557,7 @@ async def test_check_config_sensor(do_config) -> None:
|
|||||||
CONF_NAME: TEST_ENTITY_NAME + " 2",
|
CONF_NAME: TEST_ENTITY_NAME + " 2",
|
||||||
CONF_ADDRESS: 118,
|
CONF_ADDRESS: 118,
|
||||||
CONF_SLAVE: 0,
|
CONF_SLAVE: 0,
|
||||||
CONF_TARGET_TEMP: 99,
|
CONF_TARGET_TEMP: [99],
|
||||||
CONF_FAN_MODE_REGISTER: {
|
CONF_FAN_MODE_REGISTER: {
|
||||||
CONF_ADDRESS: 120,
|
CONF_ADDRESS: 120,
|
||||||
CONF_FAN_MODE_VALUES: {
|
CONF_FAN_MODE_VALUES: {
|
||||||
@ -570,9 +591,9 @@ async def test_check_config_sensor(do_config) -> None:
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
CONF_NAME: TEST_ENTITY_NAME + " 2",
|
CONF_NAME: TEST_ENTITY_NAME + " 2",
|
||||||
CONF_ADDRESS: 118,
|
CONF_ADDRESS: 117,
|
||||||
CONF_SLAVE: 0,
|
CONF_SLAVE: 0,
|
||||||
CONF_TARGET_TEMP: 117,
|
CONF_TARGET_TEMP: [117],
|
||||||
CONF_FAN_MODE_REGISTER: {
|
CONF_FAN_MODE_REGISTER: {
|
||||||
CONF_ADDRESS: [121],
|
CONF_ADDRESS: [121],
|
||||||
CONF_FAN_MODE_VALUES: {
|
CONF_FAN_MODE_VALUES: {
|
||||||
@ -584,6 +605,61 @@ async def test_check_config_sensor(do_config) -> None:
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
CONF_NAME: TEST_MODBUS_NAME,
|
||||||
|
CONF_TYPE: TCP,
|
||||||
|
CONF_HOST: TEST_MODBUS_HOST,
|
||||||
|
CONF_PORT: TEST_PORT_TCP,
|
||||||
|
CONF_TIMEOUT: 3,
|
||||||
|
CONF_CLIMATES: [
|
||||||
|
{
|
||||||
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
|
CONF_ADDRESS: 117,
|
||||||
|
CONF_TARGET_TEMP: [130, 131, 132, 133, 134, 135, 136],
|
||||||
|
CONF_SLAVE: 0,
|
||||||
|
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: 122,
|
||||||
|
CONF_FAN_MODE_REGISTER: {
|
||||||
|
CONF_ADDRESS: 120,
|
||||||
|
CONF_FAN_MODE_VALUES: {
|
||||||
|
CONF_FAN_MODE_ON: 0,
|
||||||
|
CONF_FAN_MODE_HIGH: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CONF_NAME: TEST_ENTITY_NAME + " 2",
|
||||||
|
CONF_ADDRESS: 118,
|
||||||
|
CONF_TARGET_TEMP: [130, 131, 132, 133, 134, 135, 136],
|
||||||
|
CONF_SLAVE: 0,
|
||||||
|
CONF_HVAC_MODE_REGISTER: {
|
||||||
|
CONF_ADDRESS: 130,
|
||||||
|
CONF_HVAC_MODE_VALUES: {
|
||||||
|
CONF_HVAC_MODE_COOL: 0,
|
||||||
|
CONF_HVAC_MODE_HEAT: 2,
|
||||||
|
CONF_HVAC_MODE_DRY: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CONF_HVAC_ONOFF_REGISTER: 122,
|
||||||
|
CONF_FAN_MODE_REGISTER: {
|
||||||
|
CONF_ADDRESS: 120,
|
||||||
|
CONF_FAN_MODE_VALUES: {
|
||||||
|
CONF_FAN_MODE_ON: 0,
|
||||||
|
CONF_FAN_MODE_HIGH: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_check_config_climate(do_config) -> None:
|
async def test_check_config_climate(do_config) -> None:
|
||||||
@ -592,6 +668,59 @@ async def test_check_config_climate(do_config) -> None:
|
|||||||
assert len(do_config[0][CONF_CLIMATES]) == 1
|
assert len(do_config[0][CONF_CLIMATES]) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"do_config",
|
||||||
|
[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
|
CONF_ADDRESS: 1,
|
||||||
|
CONF_TARGET_TEMP: [117, 121, 119, 150, 151, 152, 156],
|
||||||
|
CONF_HVAC_MODE_REGISTER: {
|
||||||
|
CONF_ADDRESS: 119,
|
||||||
|
CONF_HVAC_MODE_VALUES: {
|
||||||
|
CONF_HVAC_MODE_COOL: 0,
|
||||||
|
CONF_HVAC_MODE_HEAT: 1,
|
||||||
|
CONF_HVAC_MODE_HEAT_COOL: 2,
|
||||||
|
CONF_HVAC_MODE_DRY: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CONF_HVAC_ONOFF_REGISTER: 117,
|
||||||
|
CONF_FAN_MODE_REGISTER: {
|
||||||
|
CONF_ADDRESS: 121,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
CONF_NAME: TEST_ENTITY_NAME,
|
||||||
|
CONF_ADDRESS: 1,
|
||||||
|
CONF_TARGET_TEMP: [117],
|
||||||
|
CONF_HVAC_MODE_REGISTER: {
|
||||||
|
CONF_ADDRESS: 117,
|
||||||
|
CONF_HVAC_MODE_VALUES: {
|
||||||
|
CONF_HVAC_MODE_COOL: 0,
|
||||||
|
CONF_HVAC_MODE_HEAT: 1,
|
||||||
|
CONF_HVAC_MODE_HEAT_COOL: 2,
|
||||||
|
CONF_HVAC_MODE_DRY: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CONF_HVAC_ONOFF_REGISTER: 117,
|
||||||
|
CONF_FAN_MODE_REGISTER: {
|
||||||
|
CONF_ADDRESS: 117,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_climate_conflict_addresses(do_config) -> None:
|
||||||
|
"""Test conflicts among the addresses of target temp and other climate addresses."""
|
||||||
|
check_hvac_target_temp_registers(do_config[0])
|
||||||
|
assert CONF_HVAC_MODE_REGISTER not in do_config[0]
|
||||||
|
assert CONF_HVAC_ONOFF_REGISTER not in do_config[0]
|
||||||
|
assert CONF_FAN_MODE_REGISTER not in do_config[0]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"do_config",
|
"do_config",
|
||||||
[
|
[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user