diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 095fa6d..c9a8ad6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,14 +4,6 @@ repos: hooks: - id: pyupgrade args: [--py37-plus] - - repo: https://github.com/psf/black - rev: 24.10.0 - hooks: - - id: black - args: - - --safe - - --quiet - files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$ - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: @@ -31,7 +23,7 @@ repos: - --configfile=tests/bandit.yaml files: ^(homeassistant|script|tests)/.+\.py$ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.4 + rev: v0.9.1 hooks: # Run the linter. - id: ruff diff --git a/custom_components/askoheat/api.py b/custom_components/askoheat/api.py index f1a6d3f..f81e135 100644 --- a/custom_components/askoheat/api.py +++ b/custom_components/askoheat/api.py @@ -13,7 +13,6 @@ cast, ) -import numpy as np from homeassistant.exceptions import HomeAssistantError from numpy import number from pymodbus.client import AsyncModbusTcpClient @@ -358,7 +357,9 @@ def __map_data( ) -def _read_register_input(data: ModbusPDU, desc: RegisterInputDescriptor) -> Any: # noqa: PLR0912 +def _read_register_input( # noqa: PLR0912 + data: ModbusPDU, desc: RegisterInputDescriptor +) -> Any: result: Any = None match desc: case FlagRegisterInputDescriptor(starting_register, bit): @@ -552,7 +553,7 @@ def _prepare_str(value: object) -> list[int]: return result -def _read_byte(register_value: int) -> np.byte | None: +def _read_byte(register_value: int) -> int | None: """Read register value as byte.""" value = AsyncModbusTcpClient.convert_from_registers( [register_value], AsyncModbusTcpClient.DATATYPE.INT16 @@ -562,7 +563,7 @@ def _read_byte(register_value: int) -> np.byte | None: "Cannot read register value %s as byte, wrong result %r", value, type(value) ) return None - return np.byte(value) + return int(value) def _prepare_byte(value: object) -> list[int]: @@ -582,7 +583,7 @@ def _prepare_byte(value: object) -> list[int]: ) -def _read_int16(register_value: int) -> np.int16 | None: +def _read_int16(register_value: int) -> int | None: """Read register value as int16.""" value = AsyncModbusTcpClient.convert_from_registers( [register_value], AsyncModbusTcpClient.DATATYPE.INT16 @@ -595,7 +596,7 @@ def _read_int16(register_value: int) -> np.int16 | None: ) return None - return np.int16(value) + return int(value) def _prepare_int16(value: object) -> list[int]: @@ -612,7 +613,7 @@ def _prepare_int16(value: object) -> list[int]: ) -def _read_uint16(register_value: int) -> np.uint16 | None: +def _read_uint16(register_value: int) -> int | None: """Read register value as uint16.""" value = AsyncModbusTcpClient.convert_from_registers( [register_value], AsyncModbusTcpClient.DATATYPE.UINT16 @@ -625,7 +626,7 @@ def _read_uint16(register_value: int) -> np.uint16 | None: ) return None - return np.uint16(value) + return int(value) def _prepare_uint16(value: object) -> list[int]: @@ -643,7 +644,7 @@ def _prepare_uint16(value: object) -> list[int]: ) -def _read_uint32(register_values: list[int]) -> np.uint32 | None: +def _read_uint32(register_values: list[int]) -> int | None: """Read register value as uint32.""" value = AsyncModbusTcpClient.convert_from_registers( register_values, AsyncModbusTcpClient.DATATYPE.UINT32 @@ -655,7 +656,7 @@ def _read_uint32(register_values: list[int]) -> np.uint32 | None: type(value), ) return None - return np.uint32(value) + return int(value) def _prepare_uint32(value: object) -> list[int]: @@ -673,7 +674,7 @@ def _prepare_uint32(value: object) -> list[int]: ) -def _read_float32(register_values: list[int]) -> np.float16 | None: +def _read_float32(register_values: list[int]) -> float | None: """Read register value as uint16.""" value = AsyncModbusTcpClient.convert_from_registers( register_values, AsyncModbusTcpClient.DATATYPE.FLOAT32 @@ -685,7 +686,7 @@ def _read_float32(register_values: list[int]) -> np.float16 | None: type(value), ) return None - return np.float16(value) + return float(value) def _prepare_float32(value: object) -> list[int]: diff --git a/custom_components/askoheat/api_conf_desc.py b/custom_components/askoheat/api_conf_desc.py index 44f4a71..6bcd4ab 100644 --- a/custom_components/askoheat/api_conf_desc.py +++ b/custom_components/askoheat/api_conf_desc.py @@ -1,4 +1,5 @@ """Configuration block Api descriptor classes.""" + # http://www.download.askoma.com/askofamily_plus/modbus/askoheat-modbus.html#Configuration_Block from __future__ import annotations diff --git a/custom_components/askoheat/api_ema_desc.py b/custom_components/askoheat/api_ema_desc.py index e16556c..783e9df 100644 --- a/custom_components/askoheat/api_ema_desc.py +++ b/custom_components/askoheat/api_ema_desc.py @@ -1,4 +1,5 @@ """Energymanager block Api descriptor classes.""" + # http://www.download.askoma.com/askofamily_plus/modbus/askoheat-modbus.html#EM_Block from __future__ import annotations diff --git a/custom_components/askoheat/config_flow.py b/custom_components/askoheat/config_flow.py index 0f071a0..3a7cc3d 100644 --- a/custom_components/askoheat/config_flow.py +++ b/custom_components/askoheat/config_flow.py @@ -115,16 +115,18 @@ def _step_user_data_schema( ), vol.Required( CONF_POWER_INVERT, - default=False - if ( - x := _get_section_entry_or_none( - data, - CONF_FEED_IN, - CONF_POWER_INVERT, + default=( + False + if ( + x := _get_section_entry_or_none( + data, + CONF_FEED_IN, + CONF_POWER_INVERT, + ) ) - ) - is None - else x, + is None + else x + ), ): cv.boolean, } ), @@ -135,55 +137,63 @@ def _step_user_data_schema( { vol.Required( CONF_LEGIONELLA_PROTECTION_UNIT, - default=True - if ( - x := _get_section_entry_or_none( - data, - CONF_DEVICE_UNITS, - CONF_LEGIONELLA_PROTECTION_UNIT, + default=( + True + if ( + x := _get_section_entry_or_none( + data, + CONF_DEVICE_UNITS, + CONF_LEGIONELLA_PROTECTION_UNIT, + ) ) - ) - is None - else x, + is None + else x + ), ): bool, vol.Required( CONF_HEATPUMP_UNIT, - default=False - if ( - x := _get_section_entry_or_none( - data, - CONF_DEVICE_UNITS, - CONF_HEATPUMP_UNIT, + default=( + False + if ( + x := _get_section_entry_or_none( + data, + CONF_DEVICE_UNITS, + CONF_HEATPUMP_UNIT, + ) ) - ) - is None - else x, + is None + else x + ), ): cv.boolean, vol.Required( CONF_ANALOG_INPUT_UNIT, - default=False - if ( - x := _get_section_entry_or_none( - data, - CONF_DEVICE_UNITS, - CONF_ANALOG_INPUT_UNIT, + default=( + False + if ( + x := _get_section_entry_or_none( + data, + CONF_DEVICE_UNITS, + CONF_ANALOG_INPUT_UNIT, + ) ) - ) - is None - else x, + is None + else x + ), ): cv.boolean, vol.Required( CONF_MODBUS_MASTER_UNIT, - default=False - if ( - x := _get_section_entry_or_none( - data, - CONF_DEVICE_UNITS, - CONF_MODBUS_MASTER_UNIT, + default=( + False + if ( + x := _get_section_entry_or_none( + data, + CONF_DEVICE_UNITS, + CONF_MODBUS_MASTER_UNIT, + ) ) - ) - is None - else x, + is None + else x + ), ): cv.boolean, } ), diff --git a/custom_components/askoheat/select.py b/custom_components/askoheat/select.py index f658686..9cc12a5 100644 --- a/custom_components/askoheat/select.py +++ b/custom_components/askoheat/select.py @@ -1,4 +1,4 @@ -"""Askoheat time entity.""" +"""Askoheat time entity.""" # noqa: A005 from functools import cached_property diff --git a/custom_components/askoheat/sensor.py b/custom_components/askoheat/sensor.py index 63aed69..510c8b6 100644 --- a/custom_components/askoheat/sensor.py +++ b/custom_components/askoheat/sensor.py @@ -136,8 +136,8 @@ def _handle_coordinator_update(self) -> None: if self.entity_description.factor is not None: float_value *= self.entity_description.factor if self.entity_description.native_precision is not None: - float_value = round( - float_value, self.entity_description.native_precision + float_value = float_value.__round__( + self.entity_description.native_precision ) self._attr_native_value = float_value else: diff --git a/custom_components/askoheat/time.py b/custom_components/askoheat/time.py index bd798b5..ad73bed 100644 --- a/custom_components/askoheat/time.py +++ b/custom_components/askoheat/time.py @@ -1,4 +1,4 @@ -"""Askoheat time entity.""" +"""Askoheat time entity.""" # noqa: A005 from datetime import time diff --git a/requirements.txt b/requirements.txt index 47f26b2..2553f33 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ colorlog==6.9.0 homeassistant==2024.10.3 pip>=21.3.1 -ruff==0.8.6 +ruff==0.9.1 pymodbus==3.8.3 diff --git a/tests/test_binary_sensor.py b/tests/test_binary_sensor.py index db0c4a1..49c38f4 100644 --- a/tests/test_binary_sensor.py +++ b/tests/test_binary_sensor.py @@ -93,6 +93,6 @@ async def test_read_binary_sensor_states( key = f"binary_sensor.test_{entity_descriptor.key}" state = hass.states.get(key) assert state - assert ( - state.state is expected - ), f"Expect state {expected} for entity {entity_descriptor.key}, but received {state.state}." # noqa: E501 + assert state.state is expected, ( + f"Expect state {expected} for entity {entity_descriptor.key}, but received {state.state}." # noqa: E501 + ) diff --git a/tests/test_sensor.py b/tests/test_sensor.py index aaafb1e..ca6d16f 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -83,11 +83,11 @@ def __generate_test_data(entity_descriptor: AskoheatSensorEntityDescription) -> case Float32RegisterInputDescriptor(): return __random_float(entity_descriptor) case UnsignedInt16RegisterInputDescriptor(): - return __random_int(entity_descriptor, np.iinfo(np.uint8)) - case UnsignedInt32RegisterInputDescriptor(): return __random_int(entity_descriptor, np.iinfo(np.uint16)) + case UnsignedInt32RegisterInputDescriptor(): + return __random_int(entity_descriptor, np.iinfo(np.uint32)) case SignedInt16RegisterInputDescriptor(): - return __random_int(entity_descriptor, np.iinfo(np.int8)) + return __random_int(entity_descriptor, np.iinfo(np.int16)) case StringRegisterInputDescriptor(_, number_of_words): return __randomword(trunc(number_of_words / 2)) @@ -183,15 +183,18 @@ async def test_read_sensor_states( assert state expected = ( - str(0) + 0 if sensor_test_data[entity_descriptor.key] is None - else str(sensor_test_data[entity_descriptor.key]) + else sensor_test_data[entity_descriptor.key] ) + if entity_descriptor.factor is not None: + expected *= entity_descriptor.factor + # for entity descriptors provided a precision we expect a rounded value if entity_descriptor.native_precision is not None: - expected = str(round(float(expected), entity_descriptor.native_precision)) + expected = expected.__round__(entity_descriptor.native_precision) - assert ( - state.state == expected - ), f"Expect state {expected}({type(expected)}) for entity {entity_descriptor.key}, but received {state.state}({type(state.state)})." # noqa: E501 + assert state.state == str(expected), ( + f"Expect state {expected}({type(expected)}) for entity {entity_descriptor.key}, but received {state.state}({type(state.state)})." # noqa: E501 + )