Correct set_temperature in modbus climate (#52923)
This commit is contained in:
parent
a14bde8187
commit
8c43e5c736
2 changed files with 74 additions and 9 deletions
|
@ -33,7 +33,12 @@ from .const import (
|
||||||
CONF_MIN_TEMP,
|
CONF_MIN_TEMP,
|
||||||
CONF_STEP,
|
CONF_STEP,
|
||||||
CONF_TARGET_TEMP,
|
CONF_TARGET_TEMP,
|
||||||
DEFAULT_STRUCT_FORMAT,
|
DATA_TYPE_INT16,
|
||||||
|
DATA_TYPE_INT32,
|
||||||
|
DATA_TYPE_INT64,
|
||||||
|
DATA_TYPE_UINT16,
|
||||||
|
DATA_TYPE_UINT32,
|
||||||
|
DATA_TYPE_UINT64,
|
||||||
MODBUS_DOMAIN,
|
MODBUS_DOMAIN,
|
||||||
)
|
)
|
||||||
from .modbus import ModbusHub
|
from .modbus import ModbusHub
|
||||||
|
@ -145,16 +150,28 @@ class ModbusThermostat(BaseStructPlatform, RestoreEntity, ClimateEntity):
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
if ATTR_TEMPERATURE not in kwargs:
|
if ATTR_TEMPERATURE not in kwargs:
|
||||||
return
|
return
|
||||||
target_temperature = int(
|
target_temperature = (
|
||||||
(kwargs.get(ATTR_TEMPERATURE) - self._offset) / self._scale
|
float(kwargs.get(ATTR_TEMPERATURE)) - self._offset
|
||||||
)
|
) / self._scale
|
||||||
byte_string = struct.pack(self._structure, target_temperature)
|
if self._data_type in [
|
||||||
struct_string = f">{DEFAULT_STRUCT_FORMAT[self._data_type]}"
|
DATA_TYPE_INT16,
|
||||||
register_value = struct.unpack(struct_string, byte_string)[0]
|
DATA_TYPE_INT32,
|
||||||
|
DATA_TYPE_INT64,
|
||||||
|
DATA_TYPE_UINT16,
|
||||||
|
DATA_TYPE_UINT32,
|
||||||
|
DATA_TYPE_UINT64,
|
||||||
|
]:
|
||||||
|
target_temperature = int(target_temperature)
|
||||||
|
as_bytes = struct.pack(self._structure, target_temperature)
|
||||||
|
raw_regs = [
|
||||||
|
int.from_bytes(as_bytes[i : i + 2], "big")
|
||||||
|
for i in range(0, len(as_bytes), 2)
|
||||||
|
]
|
||||||
|
registers = self._swap_registers(raw_regs)
|
||||||
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,
|
||||||
register_value,
|
registers,
|
||||||
CALL_TYPE_WRITE_REGISTERS,
|
CALL_TYPE_WRITE_REGISTERS,
|
||||||
)
|
)
|
||||||
self._available = result is not None
|
self._available = result is not None
|
||||||
|
|
|
@ -3,7 +3,15 @@ import pytest
|
||||||
|
|
||||||
from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
|
from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
|
||||||
from homeassistant.components.climate.const import HVAC_MODE_AUTO
|
from homeassistant.components.climate.const import HVAC_MODE_AUTO
|
||||||
from homeassistant.components.modbus.const import CONF_CLIMATES, CONF_TARGET_TEMP
|
from homeassistant.components.modbus.const import (
|
||||||
|
CONF_CLIMATES,
|
||||||
|
CONF_DATA_TYPE,
|
||||||
|
CONF_TARGET_TEMP,
|
||||||
|
DATA_TYPE_FLOAT32,
|
||||||
|
DATA_TYPE_FLOAT64,
|
||||||
|
DATA_TYPE_INT16,
|
||||||
|
DATA_TYPE_INT32,
|
||||||
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_TEMPERATURE,
|
ATTR_TEMPERATURE,
|
||||||
CONF_ADDRESS,
|
CONF_ADDRESS,
|
||||||
|
@ -110,6 +118,46 @@ async def test_service_climate_update(hass, mock_pymodbus):
|
||||||
assert hass.states.get(ENTITY_ID).state == "auto"
|
assert hass.states.get(ENTITY_ID).state == "auto"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"data_type, temperature, result",
|
||||||
|
[
|
||||||
|
(DATA_TYPE_INT16, 35, [0x00]),
|
||||||
|
(DATA_TYPE_INT32, 36, [0x00, 0x00]),
|
||||||
|
(DATA_TYPE_FLOAT32, 37.5, [0x00, 0x00]),
|
||||||
|
(DATA_TYPE_FLOAT64, "39", [0x00, 0x00, 0x00, 0x00]),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_service_climate_set_temperature(
|
||||||
|
hass, data_type, temperature, result, mock_pymodbus
|
||||||
|
):
|
||||||
|
"""Run test for service homeassistant.update_entity."""
|
||||||
|
config = {
|
||||||
|
CONF_CLIMATES: [
|
||||||
|
{
|
||||||
|
CONF_NAME: CLIMATE_NAME,
|
||||||
|
CONF_TARGET_TEMP: 117,
|
||||||
|
CONF_ADDRESS: 117,
|
||||||
|
CONF_SLAVE: 10,
|
||||||
|
CONF_DATA_TYPE: data_type,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
mock_pymodbus.read_holding_registers.return_value = ReadResult(result)
|
||||||
|
await prepare_service_update(
|
||||||
|
hass,
|
||||||
|
config,
|
||||||
|
)
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
"set_temperature",
|
||||||
|
{
|
||||||
|
"entity_id": ENTITY_ID,
|
||||||
|
ATTR_TEMPERATURE: temperature,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
test_value = State(ENTITY_ID, 35)
|
test_value = State(ENTITY_ID, 35)
|
||||||
test_value.attributes = {ATTR_TEMPERATURE: 37}
|
test_value.attributes = {ATTR_TEMPERATURE: 37}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue