mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 06:37:52 +00:00
Coverage 100% of Modbus climate (#67396)
* Coverage 100% of climate.py * Allow 100% test.
This commit is contained in:
parent
bc2aaedcec
commit
306498378c
@ -706,7 +706,6 @@ omit =
|
|||||||
homeassistant/components/mjpeg/camera.py
|
homeassistant/components/mjpeg/camera.py
|
||||||
homeassistant/components/mjpeg/util.py
|
homeassistant/components/mjpeg/util.py
|
||||||
homeassistant/components/mochad/*
|
homeassistant/components/mochad/*
|
||||||
homeassistant/components/modbus/climate.py
|
|
||||||
homeassistant/components/modem_callerid/button.py
|
homeassistant/components/modem_callerid/button.py
|
||||||
homeassistant/components/modem_callerid/sensor.py
|
homeassistant/components/modem_callerid/sensor.py
|
||||||
homeassistant/components/moehlenhoff_alpha2/__init__.py
|
homeassistant/components/moehlenhoff_alpha2/__init__.py
|
||||||
|
@ -336,6 +336,8 @@ def get_hub(hass: HomeAssistant, name: str) -> ModbusHub:
|
|||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
"""Set up Modbus component."""
|
"""Set up Modbus component."""
|
||||||
|
if DOMAIN not in config:
|
||||||
|
return True
|
||||||
return await async_modbus_setup(
|
return await async_modbus_setup(
|
||||||
hass,
|
hass,
|
||||||
config,
|
config,
|
||||||
|
@ -28,7 +28,6 @@ from . import get_hub
|
|||||||
from .base_platform import BaseStructPlatform
|
from .base_platform import BaseStructPlatform
|
||||||
from .const import (
|
from .const import (
|
||||||
CALL_TYPE_REGISTER_HOLDING,
|
CALL_TYPE_REGISTER_HOLDING,
|
||||||
CALL_TYPE_WRITE_REGISTER,
|
|
||||||
CALL_TYPE_WRITE_REGISTERS,
|
CALL_TYPE_WRITE_REGISTERS,
|
||||||
CONF_CLIMATES,
|
CONF_CLIMATES,
|
||||||
CONF_MAX_TEMP,
|
CONF_MAX_TEMP,
|
||||||
@ -103,8 +102,6 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
|||||||
|
|
||||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
if ATTR_TEMPERATURE not in kwargs:
|
|
||||||
return
|
|
||||||
target_temperature = (
|
target_temperature = (
|
||||||
float(kwargs[ATTR_TEMPERATURE]) - self._offset
|
float(kwargs[ATTR_TEMPERATURE]) - self._offset
|
||||||
) / self._scale
|
) / self._scale
|
||||||
@ -124,20 +121,12 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
|||||||
]
|
]
|
||||||
registers = self._swap_registers(raw_regs)
|
registers = self._swap_registers(raw_regs)
|
||||||
|
|
||||||
if isinstance(registers, list):
|
result = await self._hub.async_pymodbus_call(
|
||||||
result = await self._hub.async_pymodbus_call(
|
self._slave,
|
||||||
self._slave,
|
self._target_temperature_register,
|
||||||
self._target_temperature_register,
|
[int(float(i)) for i in registers],
|
||||||
[int(float(i)) for i in registers],
|
CALL_TYPE_WRITE_REGISTERS,
|
||||||
CALL_TYPE_WRITE_REGISTERS,
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
result = await self._hub.async_pymodbus_call(
|
|
||||||
self._slave,
|
|
||||||
self._target_temperature_register,
|
|
||||||
target_temperature,
|
|
||||||
CALL_TYPE_WRITE_REGISTER,
|
|
||||||
)
|
|
||||||
self._attr_available = result is not None
|
self._attr_available = result is not None
|
||||||
await self.async_update()
|
await self.async_update()
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ from homeassistant.components.modbus.const import (
|
|||||||
CONF_DATA_TYPE,
|
CONF_DATA_TYPE,
|
||||||
CONF_LAZY_ERROR,
|
CONF_LAZY_ERROR,
|
||||||
CONF_TARGET_TEMP,
|
CONF_TARGET_TEMP,
|
||||||
|
MODBUS_DOMAIN,
|
||||||
DataType,
|
DataType,
|
||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
@ -16,10 +17,12 @@ from homeassistant.const import (
|
|||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_SCAN_INTERVAL,
|
CONF_SCAN_INTERVAL,
|
||||||
CONF_SLAVE,
|
CONF_SLAVE,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
)
|
)
|
||||||
from homeassistant.core import State
|
from homeassistant.core import State
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from .conftest import TEST_ENTITY_NAME, ReadResult
|
from .conftest import TEST_ENTITY_NAME, ReadResult, do_next_cycle
|
||||||
|
|
||||||
ENTITY_ID = f"{CLIMATE_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
|
ENTITY_ID = f"{CLIMATE_DOMAIN}.{TEST_ENTITY_NAME}".replace(" ", "_")
|
||||||
|
|
||||||
@ -222,3 +225,91 @@ async def test_restore_state_climate(hass, mock_test_state, mock_modbus):
|
|||||||
state = hass.states.get(ENTITY_ID)
|
state = hass.states.get(ENTITY_ID)
|
||||||
assert state.state == HVAC_MODE_AUTO
|
assert state.state == HVAC_MODE_AUTO
|
||||||
assert state.attributes[ATTR_TEMPERATURE] == 37
|
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,
|
||||||
|
CONF_LAZY_ERROR: 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"register_words,do_exception,start_expect,end_expect",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
[0x8000],
|
||||||
|
True,
|
||||||
|
"17",
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_lazy_error_climate(hass, mock_do_cycle, start_expect, end_expect):
|
||||||
|
"""Run test for sensor."""
|
||||||
|
hass.states.async_set(ENTITY_ID, 17)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
now = mock_do_cycle
|
||||||
|
assert hass.states.get(ENTITY_ID).state == start_expect
|
||||||
|
now = await do_next_cycle(hass, now, 11)
|
||||||
|
assert hass.states.get(ENTITY_ID).state == start_expect
|
||||||
|
now = await do_next_cycle(hass, now, 11)
|
||||||
|
assert hass.states.get(ENTITY_ID).state == end_expect
|
||||||
|
|
||||||
|
|
||||||
|
@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, mock_do_cycle):
|
||||||
|
"""Run test for sensor."""
|
||||||
|
assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
|
async def test_no_discovery_info(hass, caplog):
|
||||||
|
"""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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user