-
-
Notifications
You must be signed in to change notification settings - Fork 37.5k
Add separate scale and offset for current temperature for modbus climates #150985
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
288bb62
3d222d0
6feb103
5061afb
ab50e43
29b3202
2fd3da3
818221d
148002c
57af459
ad3da15
33fec8d
a8da718
cf5662d
0cd6f6a
e45ce85
91366b5
c9ae098
30ef8e5
cab1082
2b650a2
010f556
82a53ed
7188f6c
de33a03
f7d30ef
bea9139
ae53aef
9032dbf
3496c7c
c56ef49
d60deca
4153de7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,6 @@ | |
| CONF_DELAY, | ||
| CONF_DEVICE_CLASS, | ||
| CONF_NAME, | ||
| CONF_OFFSET, | ||
| CONF_SCAN_INTERVAL, | ||
| CONF_SLAVE, | ||
| CONF_STRUCTURE, | ||
|
|
@@ -50,7 +49,6 @@ | |
| CONF_MIN_VALUE, | ||
| CONF_NAN_VALUE, | ||
| CONF_PRECISION, | ||
| CONF_SCALE, | ||
| CONF_SLAVE_COUNT, | ||
| CONF_STATE_OFF, | ||
| CONF_STATE_ON, | ||
|
|
@@ -62,6 +60,8 @@ | |
| CONF_VIRTUAL_COUNT, | ||
| CONF_WRITE_TYPE, | ||
| CONF_ZERO_SUPPRESS, | ||
| DEFAULT_OFFSET, | ||
| DEFAULT_SCALE, | ||
| SIGNAL_STOP_ENTITY, | ||
| DataType, | ||
| ) | ||
|
|
@@ -163,8 +163,6 @@ def __init__(self, hass: HomeAssistant, hub: ModbusHub, config: dict) -> None: | |
| self._swap = config[CONF_SWAP] | ||
| self._data_type = config[CONF_DATA_TYPE] | ||
| self._structure: str = config[CONF_STRUCTURE] | ||
| self._scale = config[CONF_SCALE] | ||
| self._offset = config[CONF_OFFSET] | ||
| self._slave_count = config.get(CONF_SLAVE_COUNT) or config.get( | ||
| CONF_VIRTUAL_COUNT, 0 | ||
| ) | ||
|
|
@@ -181,8 +179,6 @@ def __init__(self, hass: HomeAssistant, hub: ModbusHub, config: dict) -> None: | |
| self._precision = config.get(CONF_PRECISION, 2) | ||
| else: | ||
| self._precision = config.get(CONF_PRECISION, 0) | ||
| if self._precision > 0 or self._scale != int(self._scale): | ||
| self._value_is_int = False | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removing precision here, might be correct, but it seems it is not added to climate ??
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Climate never used |
||
|
|
||
| def _swap_registers(self, registers: list[int], slave_count: int) -> list[int]: | ||
| """Do swap as needed.""" | ||
|
|
@@ -206,7 +202,12 @@ def _swap_registers(self, registers: list[int], slave_count: int) -> list[int]: | |
| registers.reverse() | ||
| return registers | ||
|
|
||
| def __process_raw_value(self, entry: float | str | bytes) -> str | None: | ||
| def __process_raw_value( | ||
| self, | ||
| entry: float | bytes, | ||
| scale: float = DEFAULT_SCALE, | ||
| offset: float = DEFAULT_OFFSET, | ||
| ) -> str | None: | ||
|
illia-piskurov marked this conversation as resolved.
|
||
| """Process value from sensor with NaN handling, scaling, offset, min/max etc.""" | ||
| if self._nan_value is not None and entry in (self._nan_value, -self._nan_value): | ||
| return None | ||
|
|
@@ -215,7 +216,7 @@ def __process_raw_value(self, entry: float | str | bytes) -> str | None: | |
| if entry != entry: # noqa: PLR0124 | ||
| # NaN float detection replace with None | ||
| return None | ||
| val: float | int = self._scale * entry + self._offset | ||
| val: float | int = scale * entry + offset | ||
| if self._min_value is not None and val < self._min_value: | ||
| val = self._min_value | ||
| if self._max_value is not None and val > self._max_value: | ||
|
|
@@ -226,7 +227,12 @@ def __process_raw_value(self, entry: float | str | bytes) -> str | None: | |
| return str(round(val)) | ||
| return f"{float(val):.{self._precision}f}" | ||
|
|
||
| def unpack_structure_result(self, registers: list[int]) -> str | None: | ||
| def unpack_structure_result( | ||
| self, | ||
| registers: list[int], | ||
| scale: float = DEFAULT_SCALE, | ||
| offset: float = DEFAULT_OFFSET, | ||
| ) -> str | None: | ||
| """Convert registers to proper result.""" | ||
|
|
||
| if self._swap: | ||
|
|
@@ -250,15 +256,15 @@ def unpack_structure_result(self, registers: list[int]) -> str | None: | |
| # Apply scale, precision, limits to floats and ints | ||
| v_result = [] | ||
| for entry in val: | ||
| v_temp = self.__process_raw_value(entry) | ||
| v_temp = self.__process_raw_value(entry, scale, offset) | ||
| if self._data_type != DataType.CUSTOM: | ||
| v_result.append(str(v_temp)) | ||
| else: | ||
| v_result.append(str(v_temp) if v_temp is not None else "0") | ||
| return ",".join(map(str, v_result)) | ||
|
|
||
| # Apply scale, precision, limits to floats and ints | ||
| return self.__process_raw_value(val[0]) | ||
| return self.__process_raw_value(val[0], scale, offset) | ||
|
|
||
|
|
||
| class ModbusToggleEntity(ModbusBaseEntity, ToggleEntity, RestoreEntity): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ | |
| from homeassistant.const import ( | ||
| CONF_DEVICE_CLASS, | ||
| CONF_NAME, | ||
| CONF_OFFSET, | ||
| CONF_SENSORS, | ||
| CONF_UNIQUE_ID, | ||
| CONF_UNIT_OF_MEASUREMENT, | ||
|
|
@@ -25,7 +26,14 @@ | |
| ) | ||
|
|
||
| from . import get_hub | ||
| from .const import _LOGGER, CONF_SLAVE_COUNT, CONF_VIRTUAL_COUNT | ||
| from .const import ( | ||
| _LOGGER, | ||
| CONF_SCALE, | ||
| CONF_SLAVE_COUNT, | ||
| CONF_VIRTUAL_COUNT, | ||
| DEFAULT_OFFSET, | ||
| DEFAULT_SCALE, | ||
| ) | ||
| from .entity import ModbusStructEntity | ||
| from .modbus import ModbusHub | ||
|
|
||
|
|
@@ -73,9 +81,13 @@ def __init__( | |
| self._coordinator: DataUpdateCoordinator[list[float | None] | None] | None = ( | ||
| None | ||
| ) | ||
| self._scale = entry.get(CONF_SCALE, DEFAULT_SCALE) | ||
| self._offset = entry.get(CONF_OFFSET, DEFAULT_OFFSET) | ||
| self._attr_native_unit_of_measurement = entry.get(CONF_UNIT_OF_MEASUREMENT) | ||
| self._attr_state_class = entry.get(CONF_STATE_CLASS) | ||
| self._attr_device_class = entry.get(CONF_DEVICE_CLASS) | ||
| if self._precision > 0 or self._scale != int(self._scale): | ||
| self._value_is_int = False | ||
|
|
||
| async def async_setup_slaves( | ||
| self, hass: HomeAssistant, slave_count: int, entry: dict[str, Any] | ||
|
|
@@ -117,7 +129,9 @@ async def _async_update(self) -> None: | |
| self.async_write_ha_state() | ||
| return | ||
| self._attr_available = True | ||
| result = self.unpack_structure_result(raw_result.registers) | ||
| result = self.unpack_structure_result( | ||
| raw_result.registers, self._scale, self._offset | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unpack_structure_result types scale/offset as floats, but _scale/_offset are typed float | int !
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still a problem.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?? |
||
| ) | ||
| if self._coordinator: | ||
| result_array: list[float | None] = [] | ||
| if result: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you validate for target/current scale being configured to 0.
It does not make sense, but it is possible.