From f370c7b51a92ada07c4e6161ca0dc2a6a6042918 Mon Sep 17 00:00:00 2001 From: mle Date: Fri, 5 Jul 2024 17:33:42 +0200 Subject: [PATCH] Add read_sensor so inverter API --- goodwe/dt.py | 23 +++++++++++++++++++---- goodwe/es.py | 4 ++++ goodwe/et.py | 35 +++++++++++++++++++++++++---------- goodwe/inverter.py | 8 ++++++++ pylintrc | Bin 0 -> 44706 bytes tests/inverter_check.py | 5 +++++ 6 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 pylintrc diff --git a/goodwe/dt.py b/goodwe/dt.py index d6ca6bf..1b248b0 100644 --- a/goodwe/dt.py +++ b/goodwe/dt.py @@ -149,6 +149,7 @@ def __init__(self, host: str, port: int, comm_addr: int = 0, timeout: int = 1, r self._sensors = self.__all_sensors self._sensors_meter = self.__all_sensors_meter self._settings: dict[str, Sensor] = {s.id_: s for s in self.__all_settings} + self._sensors_map: dict[str, Sensor] | None = None self._has_meter: bool = True @staticmethod @@ -205,25 +206,34 @@ async def read_runtime_data(self) -> dict[str, Any]: return data + async def read_sensor(self, sensor_id: str) -> Any: + sensor: Sensor = self._get_sensor(sensor_id) + if sensor: + return await self._read_sensor(sensor) + if sensor_id.startswith("modbus"): + response = await self._read_from_socket(self._read_command(int(sensor_id[7:]), 1)) + return int.from_bytes(response.read(2), byteorder="big", signed=True) + raise ValueError(f'Unknown sensor "{sensor_id}"') + async def read_setting(self, setting_id: str) -> Any: setting = self._settings.get(setting_id) if setting: - return await self._read_setting(setting) + return await self._read_sensor(setting) if setting_id.startswith("modbus"): response = await self._read_from_socket(self._read_command(int(setting_id[7:]), 1)) return int.from_bytes(response.read(2), byteorder="big", signed=True) raise ValueError(f'Unknown setting "{setting_id}"') - async def _read_setting(self, setting: Sensor) -> Any: + async def _read_sensor(self, setting: Sensor) -> Any: try: count = (setting.size_ + (setting.size_ % 2)) // 2 response = await self._read_from_socket(self._read_command(setting.offset, count)) return setting.read_value(response) except RequestRejectedException as ex: if ex.message == ILLEGAL_DATA_ADDRESS: - logger.debug("Unsupported setting %s", setting.id_) + logger.debug("Unsupported sensor/setting %s", setting.id_) self._settings.pop(setting.id_, None) - raise ValueError(f'Unknown setting "{setting.id_}"') + raise ValueError(f'Unknown sensor/setting "{setting.id_}"') return None async def write_setting(self, setting_id: str, value: Any): @@ -279,6 +289,11 @@ async def get_ongrid_battery_dod(self) -> int: async def set_ongrid_battery_dod(self, dod: int) -> None: raise InverterError("Operation not supported, inverter has no batteries.") + def _get_sensor(self, sensor_id: str) -> Sensor | None: + if self._sensors_map is None: + self._sensors_map = {s.id_: s for s in self.sensors()} + return self._sensors_map.get(sensor_id) + def sensors(self) -> tuple[Sensor, ...]: result = self._sensors if self._has_meter: diff --git a/goodwe/es.py b/goodwe/es.py index 1043f73..d9ef7fc 100644 --- a/goodwe/es.py +++ b/goodwe/es.py @@ -206,6 +206,10 @@ async def read_runtime_data(self) -> dict[str, Any]: data = self._map_response(response, self.__sensors) return data + async def read_sensor(self, sensor_id: str) -> Any: + data = await self.read_runtime_data() + return data[sensor_id] + async def read_setting(self, setting_id: str) -> Any: if setting_id == 'time': # Fake setting, just to enable write_setting to work (if checked as pair in read as in HA) diff --git a/goodwe/et.py b/goodwe/et.py index 84d066e..275bca0 100644 --- a/goodwe/et.py +++ b/goodwe/et.py @@ -492,6 +492,7 @@ def __init__(self, host: str, port: int, comm_addr: int = 0, timeout: int = 1, r self._sensors_meter = self.__all_sensors_meter self._sensors_mppt = self.__all_sensors_mppt self._settings: dict[str, Sensor] = {s.id_: s for s in self.__all_settings} + self._sensors_map: dict[str, Sensor] | None = None @staticmethod def _single_phase_only(s: Sensor) -> bool: @@ -641,25 +642,34 @@ async def read_runtime_data(self) -> dict[str, Any]: return data + async def read_sensor(self, sensor_id: str) -> Any: + sensor: Sensor = self._get_sensor(sensor_id) + if sensor: + return await self._read_sensor(sensor) + if sensor_id.startswith("modbus"): + response = await self._read_from_socket(self._read_command(int(sensor_id[7:]), 1)) + return int.from_bytes(response.read(2), byteorder="big", signed=True) + raise ValueError(f'Unknown sensor "{sensor_id}"') + async def read_setting(self, setting_id: str) -> Any: - setting = self._settings.get(setting_id) + setting: Sensor = self._settings.get(setting_id) if setting: - return await self._read_setting(setting) + return await self._read_sensor(setting) if setting_id.startswith("modbus"): response = await self._read_from_socket(self._read_command(int(setting_id[7:]), 1)) return int.from_bytes(response.read(2), byteorder="big", signed=True) raise ValueError(f'Unknown setting "{setting_id}"') - async def _read_setting(self, setting: Sensor) -> Any: + async def _read_sensor(self, sensor: Sensor) -> Any: try: - count = (setting.size_ + (setting.size_ % 2)) // 2 - response = await self._read_from_socket(self._read_command(setting.offset, count)) - return setting.read_value(response) + count = (sensor.size_ + (sensor.size_ % 2)) // 2 + response = await self._read_from_socket(self._read_command(sensor.offset, count)) + return sensor.read_value(response) except RequestRejectedException as ex: if ex.message == ILLEGAL_DATA_ADDRESS: - logger.debug("Unsupported setting %s", setting.id_) - self._settings.pop(setting.id_, None) - raise ValueError(f'Unknown setting "{setting.id_}"') + logger.debug("Unsupported sensor/setting %s", sensor.id_) + self._settings.pop(sensor.id_, None) + raise ValueError(f'Unknown sensor/setting "{sensor.id_}"') return None async def write_setting(self, setting_id: str, value: Any): @@ -766,7 +776,7 @@ async def set_operation_mode(self, operation_mode: OperationMode, eco_mode_power eco_mode: EcoMode | Sensor = self._settings.get('eco_mode_1') # Load the current values to try to detect schedule type try: - await self._read_setting(eco_mode) + await self._read_sensor(eco_mode) except ValueError: pass eco_mode.set_schedule_type(ScheduleType.ECO_MODE, is_745_platform(self)) @@ -787,6 +797,11 @@ async def set_ongrid_battery_dod(self, dod: int) -> None: if 0 <= dod <= 100: await self.write_setting('battery_discharge_depth', 100 - dod) + def _get_sensor(self, sensor_id: str) -> Sensor | None: + if self._sensors_map is None: + self._sensors_map = {s.id_: s for s in self.sensors()} + return self._sensors_map.get(sensor_id) + def sensors(self) -> tuple[Sensor, ...]: result = self._sensors + self._sensors_meter if self._has_battery: diff --git a/goodwe/inverter.py b/goodwe/inverter.py index eba6a8c..1bfdfc3 100644 --- a/goodwe/inverter.py +++ b/goodwe/inverter.py @@ -151,6 +151,14 @@ async def read_runtime_data(self) -> dict[str, Any]: """ raise NotImplementedError() + @abstractmethod + async def read_sensor(self, sensor_id: str) -> Any: + """ + Read the value of specific inverter sensor. + Sensor must be in list provided by sensors() method, otherwise ValueError is raised. + """ + raise NotImplementedError() + @abstractmethod async def read_setting(self, setting_id: str) -> Any: """ diff --git a/pylintrc b/pylintrc new file mode 100644 index 0000000000000000000000000000000000000000..d84c303892f255960a49f0decc62e661fd174a8a GIT binary patch literal 44706 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 literal 0 HcmV?d00001 diff --git a/tests/inverter_check.py b/tests/inverter_check.py index a1191f3..39dbce1 100644 --- a/tests/inverter_check.py +++ b/tests/inverter_check.py @@ -64,6 +64,11 @@ if sensor.id_ in response: print(f"{sensor.id_}: \t\t {sensor.name} = {response[sensor.id_]} {sensor.unit}") +# ------------- +# Read sensorr +# ------------- +# print(asyncio.run(inverter.read_sensor('vpv1'))) + # ------------- # Read settings # -------------