Skip to content

Commit

Permalink
Use arm firmware version specifi settings definitions
Browse files Browse the repository at this point in the history
Use arm firmware version specifi settings definitions.
Make reading settings values more robust, catch the ValueError and continue with other settings
  • Loading branch information
mletenay committed Feb 5, 2023
1 parent 72fb034 commit 7bf3b82
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 39 deletions.
34 changes: 23 additions & 11 deletions goodwe/et.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import logging
from typing import Tuple

from .exceptions import InverterError
Expand All @@ -9,6 +10,8 @@
from .protocol import ProtocolCommand, ModbusReadCommand, ModbusWriteCommand, ModbusWriteMultiCommand
from .sensor import *

logger = logging.getLogger(__name__)


class ET(Inverter):
"""Class representing inverter of ET/EH/BT/BH or GE's GEH families"""
Expand Down Expand Up @@ -263,21 +266,25 @@ class ET(Inverter):
# Byte("eco_mode_4_switch", 47530, "Eco Mode Power Group 4 Switch", "", Kind.BAT),
)

# Extra Modbus registers for EcoMode version 2 settings, offsets are modbus register addresses
__EcoModeV2_settings: Tuple[Sensor, ...] = (
# Settings added in ARM firmware 19
__settings_arm_fw_19: Tuple[Sensor, ...] = (
Integer("fast_charging", 47545, "Fast Charging Enabled", "", Kind.BAT),
Integer("fast_charging_soc", 47546, "Fast Charging SoC", "%", Kind.BAT),
EcoModeV2("eco_modeV2_1", 47547, "Eco Mode Version 2 Power Group 1"),
EcoModeV2("eco_modeV2_2", 47553, "Eco Mode Version 2 Power Group 2"),
EcoModeV2("eco_modeV2_3", 47559, "Eco Mode Version 2 Power Group 3"),
EcoModeV2("eco_modeV2_4", 47565, "Eco Mode Version 2 Power Group 4"),
EcoModeV2("eco_modeV2_5", 47571, "Eco Mode Version 2 Power Group 5"),
EcoModeV2("eco_modeV2_6", 47577, "Eco Mode Version 2 Power Group 6"),
EcoModeV2("eco_modeV2_7", 47583, "Eco Mode Version 2 Power Group 7"),
Integer("fast_charging_power", 47603, "Fast Charging Power", "%", Kind.BAT),
)

# Settings added in ARM firmware 22
__settings_arm_fw_22: Tuple[Sensor, ...] = (
# EcoModeV2("eco_modeV2_5", 47571, "Eco Mode Version 2 Power Group 5"),
# EcoModeV2("eco_modeV2_6", 47577, "Eco Mode Version 2 Power Group 6"),
# EcoModeV2("eco_modeV2_7", 47583, "Eco Mode Version 2 Power Group 7"),
PeakShavingMode("peak_shaving_mode", 47589, "Peak Shaving Mode"),

Integer("dod_holding", 47602, "DoD Holding", "", Kind.BAT),
Integer("fast_charging_power", 47603, "Fast Charging Power", "%", Kind.BAT),
)

def __init__(self, host: str, comm_addr: int = 0, timeout: int = 1, retries: int = 3):
Expand Down Expand Up @@ -348,9 +355,10 @@ async def read_device_info(self):
self._sensors = tuple(filter(self._single_phase_only, self.__all_sensors))
self._sensors_meter = tuple(filter(self._single_phase_only, self._sensors_meter))

if self._supports_eco_mode_v2():
# this inverter has eco mode version 2, adding EcoModeV2 to settings
self._settings = self.__all_settings + self.__EcoModeV2_settings
if self.arm_version >= 19:
self._settings = self._settings + self.__settings_arm_fw_19
if self.arm_version >= 22:
self._settings = self._settings + self.__settings_arm_fw_22

async def read_runtime_data(self, include_unknown_sensors: bool = False) -> Dict[str, Any]:
raw_data = await self._read_from_socket(self._READ_RUNNING_DATA)
Expand Down Expand Up @@ -388,8 +396,12 @@ async def write_setting(self, setting_id: str, value: Any):
async def read_settings_data(self) -> Dict[str, Any]:
data = {}
for setting in self.settings():
value = await self.read_setting(setting.id_)
data[setting.id_] = value
try:
value = await self.read_setting(setting.id_)
data[setting.id_] = value
except ValueError:
logger.exception("Error reading setting %s.", setting.id_)
data[setting.id_] = None
return data

async def get_grid_export_limit(self) -> int:
Expand Down
56 changes: 28 additions & 28 deletions goodwe/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,26 +310,26 @@ def __str__(self):
def read_value(self, data: io.BytesIO):
self.start_h = read_byte(data)
if (self.start_h < 0 or self.start_h > 23) and self.start_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: start_h value {self.start_h} out of range.")
self.start_m = read_byte(data)
if self.start_m < 0 or self.start_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: start_m value {self.start_m} out of range.")
self.end_h = read_byte(data)
if (self.end_h < 0 or self.end_h > 23) and self.end_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: end_h value {self.end_h} out of range.")
self.end_m = read_byte(data)
if self.end_m < 0 or self.end_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: end_m value {self.end_m} out of range.")
self.power = read_bytes2(data) # negative=charge, positive=discharge
if self.power < -100 or self.power > 100:
raise ValueError()
raise ValueError(f"{self.id_}: power value {self.power} out of range.")
self.on_off = read_byte(data)
if self.on_off not in (0, -1):
raise ValueError()
raise ValueError(f"{self.id_}: on_off value {self.on_off} out of range.")
self.day_bits = read_byte(data)
self.days = decode_day_of_week(self.day_bits)
if self.day_bits < 0:
raise ValueError()
raise ValueError(f"{self.id_}: day_bits value {self.day_bits} out of range.")
return self

def encode_value(self, value: Any) -> bytes:
Expand Down Expand Up @@ -393,29 +393,29 @@ def __str__(self):
def read_value(self, data: io.BytesIO):
self.start_h = read_byte(data)
if (self.start_h < 0 or self.start_h > 23) and self.start_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: start_h value {self.start_h} out of range.")
self.start_m = read_byte(data)
if self.start_m < 0 or self.start_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: start_m value {self.start_m} out of range.")
self.end_h = read_byte(data)
if (self.end_h < 0 or self.end_h > 23) and self.end_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: end_h value {self.end_h} out of range.")
self.end_m = read_byte(data)
if self.end_m < 0 or self.end_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: end_m value {self.end_m} out of range.")
self.on_off = read_byte(data)
if self.on_off not in (0, -1):
raise ValueError()
raise ValueError(f"{self.id_}: on_off value {self.on_off} out of range.")
self.day_bits = read_byte(data)
self.days = decode_day_of_week(self.day_bits)
if self.day_bits < 0:
raise ValueError()
raise ValueError(f"{self.id_}: day_bits value {self.day_bits} out of range.")
self.power = read_bytes2(data) # negative=charge, positive=discharge
if self.power < -100 or self.power > 100:
raise ValueError()
raise ValueError(f"{self.id_}: power value {self.power} out of range.")
self.max_charge = read_bytes2(data)
if self.max_charge < 0 or self.max_charge > 100:
raise ValueError()
raise ValueError(f"{self.id_}: max_charge value {self.max_charge} out of range.")
return self

def encode_value(self, value: Any) -> bytes:
Expand Down Expand Up @@ -480,29 +480,29 @@ def __str__(self):
def read_value(self, data: io.BytesIO):
self.start_h = read_byte(data)
if (self.start_h < 0 or self.start_h > 23) and self.start_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: start_h value {self.start_h} out of range.")
self.start_m = read_byte(data)
if self.start_m < 0 or self.start_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: start_m value {self.start_m} out of range.")
self.end_h = read_byte(data)
if (self.end_h < 0 or self.end_h > 23) and self.end_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: end_h value {self.end_h} out of range.")
self.end_m = read_byte(data)
if self.end_m < 0 or self.end_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: end_m value {self.end_m} out of range.")
self.on_off = read_byte(data)
if self.on_off not in (-4, 3):
raise ValueError()
raise ValueError(f"{self.id_}: on_off value {self.on_off} out of range.")
self.day_bits = read_byte(data)
self.days = decode_day_of_week(self.day_bits)
if self.day_bits < 0:
raise ValueError()
raise ValueError(f"{self.id_}: day_bits value {self.day_bits} out of range.")
self.import_power = read_decimal2(data, 100)
if self.import_power < 0 or self.import_power > 500:
raise ValueError()
raise ValueError(f"{self.id_}: import_power value {self.import_power} out of range.")
self.soc = read_bytes2(data)
if self.soc < 0 or self.soc > 100:
raise ValueError()
raise ValueError(f"{self.id_}: soc value {self.soc} out of range.")
return self

def encode_value(self, value: Any) -> bytes:
Expand Down Expand Up @@ -534,19 +534,19 @@ def __str__(self):
def read_value(self, data: io.BytesIO):
self.start_h = read_byte(data)
if (self.start_h < 0 or self.start_h > 23) and self.start_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: start_h value {self.start_h} out of range.")
self.start_m = read_byte(data)
if self.start_m < 0 or self.start_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: start_m value {self.start_m} out of range.")
self.end_h = read_byte(data)
if (self.end_h < 0 or self.end_h > 23) and self.end_h != 48:
raise ValueError()
raise ValueError(f"{self.id_}: end_h value {self.end_h} out of range.")
self.end_m = read_byte(data)
if self.end_m < 0 or self.end_m > 59:
raise ValueError()
raise ValueError(f"{self.id_}: end_m value {self.end_m} out of range.")
self.power = read_bytes2(data)
if self.power < 0 or self.power > 100:
raise ValueError()
raise ValueError(f"{self.id_}: power value {self.power} out of range.")
return self

def encode_value(self, value: Any) -> bytes:
Expand Down

0 comments on commit 7bf3b82

Please sign in to comment.