Skip to content

Commit

Permalink
Fix setup of BT inverters
Browse files Browse the repository at this point in the history
BT inverters do not respond to 47547 register read command with 'ILLEGAL DATA ADDRESS', but they do not respond at all.
Adjust the EcoModeV2 setup to consider this behavior.
  • Loading branch information
mletenay committed May 8, 2024
1 parent 81e889f commit e796f22
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
20 changes: 13 additions & 7 deletions goodwe/et.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
from typing import Tuple

from .exceptions import RequestRejectedException
from .exceptions import RequestFailedException, RequestRejectedException
from .inverter import Inverter
from .inverter import OperationMode
from .inverter import SensorKind as Kind
Expand Down Expand Up @@ -482,17 +482,23 @@ async def read_device_info(self):
self._settings.update({s.id_: s for s in self.__settings_arm_fw_19})
except RequestRejectedException as ex:
if ex.message == 'ILLEGAL DATA ADDRESS':
logger.debug("Cannot read EcoModeV2 settings, using to EcoModeV1.")
logger.debug("EcoModeV2 settings not supported, switching to EcoModeV1.")
self._has_eco_mode_v2 = False
except RequestFailedException as ex:
logger.debug("Cannot read EcoModeV2 settings, switching to EcoModeV1.")
self._has_eco_mode_v2 = False

# Check and add Peak Shaving settings added in (ETU fw 22)
try:
await self._read_from_socket(ModbusReadCommand(self.comm_addr, 47589, 6))
self._settings.update({s.id_: s for s in self.__settings_arm_fw_22})
except RequestRejectedException as ex:
if ex.message == 'ILLEGAL DATA ADDRESS':
logger.debug("Cannot read PeakShaving setting, disabling it.")
logger.debug("PeakShaving setting not supported, disabling it.")
self._has_peak_shaving = False
except RequestFailedException as ex:
logger.debug("Cannot read _has_peak_shaving settings, disabling it.")
self._has_peak_shaving = False

async def read_runtime_data(self) -> Dict[str, Any]:
response = await self._read_from_socket(self._READ_RUNNING_DATA)
Expand All @@ -505,7 +511,7 @@ async def read_runtime_data(self) -> Dict[str, Any]:
data.update(self._map_response(response, self._sensors_battery))
except RequestRejectedException as ex:
if ex.message == 'ILLEGAL DATA ADDRESS':
logger.warning("Cannot read battery values, disabling further attempts.")
logger.warning("Battery values not supported, disabling further attempts.")
self._has_battery = False
else:
raise ex
Expand All @@ -516,7 +522,7 @@ async def read_runtime_data(self) -> Dict[str, Any]:
self._map_response(response, self._sensors_battery2))
except RequestRejectedException as ex:
if ex.message == 'ILLEGAL DATA ADDRESS':
logger.warning("Cannot read battery 2 values, disabling further attempts.")
logger.warning("Battery 2 values not supported, disabling further attempts.")
self._has_battery2 = False
else:
raise ex
Expand All @@ -527,7 +533,7 @@ async def read_runtime_data(self) -> Dict[str, Any]:
data.update(self._map_response(response, self._sensors_meter))
except RequestRejectedException as ex:
if ex.message == 'ILLEGAL DATA ADDRESS':
logger.warning("Cannot read extended meter values, disabling further attempts.")
logger.warning("Extended meter values not supported, disabling further attempts.")
self._has_meter_extended = False
self._sensors_meter = tuple(filter(self._not_extended_meter, self._sensors_meter))
response = await self._read_from_socket(self._READ_METER_DATA)
Expand All @@ -545,7 +551,7 @@ async def read_runtime_data(self) -> Dict[str, Any]:
data.update(self._map_response(response, self._sensors_mppt))
except RequestRejectedException as ex:
if ex.message == 'ILLEGAL DATA ADDRESS':
logger.warning("Cannot read MPPT values, disabling further attempts.")
logger.warning("MPPT values not supported, disabling further attempts.")
self._has_mppt = False
else:
raise ex
Expand Down
1 change: 1 addition & 0 deletions tests/sample/et/GW5K-BT_device_info.hex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aa55f703420000138800fe393530303042545532303357303030304757354b2d425420202000030003007c000b009330343032392d30332d53313030323034312d31312d533030828f
25 changes: 25 additions & 0 deletions tests/test_et.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ async def _read_from_socket(self, command: ProtocolCommand) -> ProtocolResponse:
if filename is not None:
if 'ILLEGAL DATA ADDRESS' == filename:
raise RequestRejectedException('ILLEGAL DATA ADDRESS')
if 'NO RESPONSE' == filename:
raise RequestFailedException()
with open(root_dir + '/sample/et/' + filename, 'r') as f:
response = bytes.fromhex(f.read())
if not command.validator(response):
Expand Down Expand Up @@ -1196,3 +1198,26 @@ def test_GW29K9_ET_runtime_data(self):
self.assertSensor('apparent_power3', 0, 'VA', data)

self.assertFalse(self.sensor_map, f"Some sensors were not tested {self.sensor_map}")


class GW5K_BT_Test(EtMock):

def __init__(self, methodName='runTest'):
EtMock.__init__(self, methodName)
self.mock_response(self._READ_DEVICE_VERSION_INFO, 'GW5K-BT_device_info.hex')
self.mock_response(ModbusReadCommand(self.comm_addr, 47547, 6), 'NO RESPONSE')

def test_GW5K_BT_device_info(self):
self.loop.run_until_complete(self.read_device_info())
self.assertEqual('GW5K-BT', self.model_name)
self.assertEqual('95000BTU203W0000', self.serial_number)
self.assertEqual(5000, self.rated_power)
self.assertEqual(0, self.modbus_version)
self.assertEqual(254, self.ac_output_type)
self.assertEqual(3, self.dsp1_version)
self.assertEqual(3, self.dsp2_version)
self.assertEqual(124, self.dsp_svn_version)
self.assertEqual(11, self.arm_version)
self.assertEqual(147, self.arm_svn_version)
self.assertEqual('04029-03-S10', self.firmware)
self.assertEqual('02041-11-S00', self.arm_firmware)

0 comments on commit e796f22

Please sign in to comment.