marcelblijleven/goodwe

Error in reading ECO mode data on GW6000ES20 (ESN version ARM v8)

iroger opened this issue · 20 comments

Thanks for adding the ESN to also include eco mode v2! However it looks like the ESN version has a slightly different data encoding as it reports errors on the inverter_check.py on eco mode settings. I have been reversing the data with Solar Go and Wireshark, results below:

Goodwe GW6000ES20

  • Firmware: 04048-06-S06
  • ARM firmware: 02020-08-S01
  • Modbus version: 121
  • DSP1 version: 6
  • DSP2 version: 6
  • DSP svn version: 6606
  • Arm version: 8
  • ARM svn version: 362

`Self use mode / Advanced settings / Economic mode (ValueError: eco_mode_1: on_off value -7 out of range.)
ON-OFF switch
16:00 - 22:00 Discharge Power 20.0% Every day, every month, ON
47547: aa55f7030c10001600f97f00c800000fff20ca
16:00 - 22:00 Discharge Power 20.0% Every day, every month, OFF
47547: aa55f7030c10001600067f00c800000fff6fce

Charge power encoding
16:00 - 22:00 Charge Power 40.0% SOC 75% Every day, every month, ON
47547: aa55f7030c10001600f97ffe70004b0fffe519
Charge power = 4 byte encoding fe70 = -400 = Charge power 40.0%
Discharge power = 4 byte encoding 00C8 = 200 = Discharge power 20.0%

SOC encoding
16:00 - 22:00 Charge Power 20.0% SOC 50% Every day, every month, ON
47547: aa55f7030c10001600f97fff3800320fffd51f

Day of week coding 1byte - 7 bits = _SFTWTMS
16:00 - 22:00 Charge Power 20.0% SOC 75% Monday, Januari, ON
47549: aa55f70302f902b3c0
16:00 - 22:00 Charge Power 20.0% SOC 75% Tuesday, Wednesday, Thursday, Januari, ON
47549: aa55f70302f91c33c8

Month encoding 4 bytes = 0000DNOSAJJMAMFJ
16:00 - 22:00 Charge Power 20.0% SOC 75% Monday, Februari, ON
47547: aa55f7030c10001600f902ff38004b00026db0
16:00 - 22:00 Charge Power 20.0% SOC 75% Monday, March, ON
47547: aa55f7030c10001600f902ff38004b0004edb2

Peak shaving mode 00:00 - 13:08 import power 1.00 kW Reserved SOC for peakshaving 20%
47589: aa55f7030c00000d08fc7f006400140000a316
47602: aa55f703020001b191
Peak shaving mode off
47589: aa55f7030c00000d08037f000000000000ddde
47602: aa55f703020001b191

Deleted group sometimes as FF, sometimes 00 (ValueError: eco_mode_2: start_h value -1 out of range.)
aa55f7030cffffffff557f0000000100012af7
aa55f7030c0000000055000000000000002035
`

Errr, I'm slightly confused.
What is specifically wrong here ?
EcoMode or PeakShaving decoding is done here

class EcoModeV2(Sensor, EcoMode):

And there are also some unit tests.
What am I missing ?

Sorry for not being clearer, I'm not familiar with Python but I'll give it a try:

  1. ECO mode On_Off coding seems different in my case: 0xf9 / -7 = ON, 0x06 / 6 = OFF your code expects 0 or -1
  2. Charge / Discharge power is 4 byte coded -400 = -40.0% and 200 = +20.0% your code expects 2 bytes in the range of -100 to 100
  3. Deleted ECO group hour / min data can be FF or 00 as I have seen. Your range check throws an error on FF.

This of course also impacts the encode functions.

The rest seems the same as for the other inverters.

I see now.
Ad 1) yes it seems goodwe started to use more values for the on/off, probably because they are re-using the "eco mode" register for more things now. It used to be just 0, -1 now it seems to be this:
image
I need to adjust the code.
Ad 2) I am not sure, spec say it's 2 bytes only, but I will look at it, since there is already report of 200% value, so there indeed is something odd there

I tried enabling Smart charge mode but I don't see the on-off changing to 0xFA / 0x05 (strange)

Next to this I also see now:
2024-02-16 09:11:42,637 datagram_received(50) - DEBUG: Received: aa55f7030c00000600fa7f01f400000ffff161 2024-02-16 09:11:42,637 read_settings_data(571) - ERROR: Error reading setting peak_shaving_mode. ValueError: peak_shaving_mode: on_off value -6 out of range.

So seems also peak shaving is using the new ON-OFF values.

Thanks for the help, I've adjusted the code and made it more robust (v0.3.1)

Thanks, just tested and seems the read function is OK now. After entering group 1 - 4 then deleting group 3,4,5 I read below as expected:
eco_mode_1: Eco Mode Group 1 = 0:0-23:59 Sun,Mon,Tue,Wed,Thu,Fri,Sat -5% (SoC 100%) On eco_mode_1_switch: Eco Mode Group 1 Switch = -7 eco_mode_2: Eco Mode Group 2 = -1:-1--1:-1 Sun,Mon,Tue,Wed,Thu,Fri,Sat Jan 0% (SoC 1%) Unset eco_mode_2_switch: Eco Mode Group 2 Switch = 85 eco_mode_3: Eco Mode Group 3 = -1:-1--1:-1 Sun,Mon,Tue,Wed,Thu,Fri,Sat Jan 0% (SoC 1%) Unset eco_mode_3_switch: Eco Mode Group 3 Switch = 85 eco_mode_4: Eco Mode Group 4 = -1:-1--1:-1 Sun,Mon,Tue,Wed,Thu,Fri,Sat Jan 0% (SoC 1%) Unset eco_mode_4_switch: Eco Mode Group 4 Switch = 85

When switching to "ECO discharge" or "ECO charge" (in Home Assistant) an error is thrown and the settings do not change.
"Failed to call service select/select_option. unknown error"

When switching to "Backup mode" the ECO group settings do change:
eco_mode_1: Eco Mode Group 1 = 0:0-23:59 -50% (SoC 100%) Unset eco_mode_1_switch: Eco Mode Group 1 Switch = 85 eco_mode_2: Eco Mode Group 2 = -1:-1--1:-1 Jan 0% (SoC 1%) Unset eco_mode_2_switch: Eco Mode Group 2 Switch = 85 eco_mode_3: Eco Mode Group 3 = -1:-1--1:-1 Jan 0% (SoC 1%) Unset eco_mode_3_switch: Eco Mode Group 3 Switch = 85 eco_mode_4: Eco Mode Group 4 = -1:-1--1:-1 Jan 0% (SoC 1%) Unset eco_mode_4_switch: Eco Mode Group 4 Switch = 85

But neither "ECO mode" or "Peak shaving mode" have effect it seems (this is after setting Peak shaving mode) but still not active and start-stop time is not affected:
peak_shaving_mode: Peak Shaving Mode = 0:0-6:0 0% (SoC 0%) Unset

After setting 25% discharge and switching modes to regular and ECO mode I again see this error:
2024-02-18 12:57:25,869 read_settings_data(586) - ERROR: Error reading setting eco_mode_1.
ValueError: eco_mode_1: power value -250 out of range.
and this is the raw data: aa55f7030c0000173b5500ff0600640fff2f2b

Encoding seems correct but it is now interpreted as ECO mode (not ECO mode 745) due to the "85" switch setting?

def detect_schedule_type(cls, value: int) -> ScheduleType:
"""Detect schedule type from its on/off value"""
if value in (0, -1, 85):
return ScheduleType.ECO_MODE
elif value in (1, -2):
return ScheduleType.DRY_CONTACT_LOAD
elif value in (2, -3):
return ScheduleType.DRY_CONTACT_SMART_LOAD
elif value in (3, -4):
return ScheduleType.PEAK_SHAVING
elif value in (4, -5):
return ScheduleType.BACKUP_MODE
elif value in (5, -6):
return ScheduleType.SMART_CHARGE_MODE
elif value in (6, -7):
return ScheduleType.ECO_MODE_745
else:
raise ValueError(f"{value}: on_off value {value} out of range.")

I think my problem of selecting eco charge/discharge modes for GW15K-ET is related to this issue.

Code expects 0 to 100 power but receives 200 (20%).

    elif operation_mode in (OperationMode.ECO_CHARGE, OperationMode.ECO_DISCHARGE):
        if eco_mode_power < 0 or eco_mode_power > 100:
            raise ValueError()
        if eco_mode_soc < 0 or eco_mode_soc > 100:
            raise ValueError()
        eco_mode: EcoMode | Sensor = self._settings.get('eco_mode_1')
        await self._read_setting(eco_mode)
        if operation_mode == OperationMode.ECO_CHARGE:
            await self.write_setting('eco_mode_1', eco_mode.encode_charge(eco_mode_power, eco_mode_soc))
        else:
            await self.write_setting('eco_mode_1', eco_mode.encode_discharge(eco_mode_power))
        await self.write_setting('eco_mode_2_switch', 0)
        await self.write_setting('eco_mode_3_switch', 0)
        await self.write_setting('eco_mode_4_switch', 0)
        await self.write_setting('work_mode', 3)
        await self._set_offline(False)

HA log:
2024-02-20 11:17:37.860 DEBUG (MainThread) [custom_components.goodwe.select] Settin operation mode to eco_charge, power 200, max SoC 90
2024-02-20 11:17:37.860 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [140495691466048]
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 240, in handle_call_service
response = await hass.services.async_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2279, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2316, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 892, in entity_service_call
single_response = await _handle_entity_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 962, in _handle_entity_call
result = await task
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/select/init.py", line 195, in async_handle_select_option
await self.async_select_option(option)
File "/config/custom_components/goodwe/select.py", line 136, in async_select_option
await self._inverter.set_operation_mode(
File "/usr/local/lib/python3.12/site-packages/goodwe/et.py", line 641, in set_operation_mode
raise ValueError()
ValueError

2024-02-20 11:20:13.530 DEBUG (MainThread) [custom_components.goodwe.select] Settin operation mode to eco_discharge, power 200, max SoC 90
2024-02-20 11:20:13.530 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [140495691466048]
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 240, in handle_call_service
response = await hass.services.async_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2279, in async_call
response_data = await coro
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/core.py", line 2316, in _execute_service
return await target(service_call)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 892, in entity_service_call
single_response = await _handle_entity_call(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 962, in _handle_entity_call
result = await task
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/select/init.py", line 195, in async_handle_select_option
await self.async_select_option(option)
File "/config/custom_components/goodwe/select.py", line 136, in async_select_option
await self._inverter.set_operation_mode(
File "/usr/local/lib/python3.12/site-packages/goodwe/et.py", line 641, in set_operation_mode
raise ValueError()
ValueError

EDIT: This only applies if the power value is untouched in HA. The default power read from inverter is 200 (20%) and if I select Eco charge or discharge this value is used even though power slider is set to 100 in HA. If I move the power slider to 80 in HA and select Eco charge or discharge the modes are setup correctly using power 80.

I have debugged this and made code changes so most things are working with GW15K-ET (745 platform) but it is not possible to select ECO mode since I cannot know if it should be ECO_MODE or ECO_MODE_745. We need a reliable way to determine if the inverter is the new 745 platform or not.

@mletenay
EDIT: Can you provide a link to the register description you posted above?

@Brumhilde link is here #62 (comment)

Thanks! I have asked Goodwe if there is a newer one.
Register 47000 in that map states:
0 Selfuse
1 Off grid
2 Backup
3 Eco

My GW15K-ET has:
0 General
1 Off grid
2 Backup
3 Eco
4 Peakshaving
5 Selfuse

I have also asked if there is any difference between General and Selfuse.

Goodwe has confirmed that Selfuse and General are the same so clearly my followup question was "why 2 different settings and does both ETU and ETT have 5 Selfuse"

Goodwe also confirmed that new 745 platform is ETT (15K-30K) and ETU (5K-10K) is platform 205.

So we can use serial number to decide platform.

@mletenay Here 925f37d you just moved away from using serial number to decide functionality. Was there any problems with that way or are you open to using it again? It is the only way we can know if we should use the new Eco mode or the old and I think we should keep it consistent, using serial number and ARM version.

I gave it a shot yesterday and it looks quite good except one box that doesn't get checked.

IMG_0844

The marked box above does not get checked when I set any of the Eco modes. The time group is created and enabled in solargo. Also solargo working mode says "Economic mode" but it is not charging/discharging according to time group. If I check this box in solargo it starts charging/discharging.

I read back work mode and it is 3 as expected and on_off bits are F9 as expected.

Neither work mode nor on_off bits change when I check the box in solargo.

Found some additional register for setting mode:
Screenshot 2024-03-06 at 11 03 19
47605, 47609 and 47612. Now the question is how these registers should be added? ETT only? For all? From a specific arm version?

Pull request: #73

Is there any improvement on this subject?
I have a GW 20K-ET.

I want to sell my energy when it is expensive.... but have no chance of doing this whitout the the functionallity of charging/discharging when I want.

I've just release v0.9.917 which I hope will address most of the problems with EcoMode.
I've partially incorporated (most of) changes from your PR, thanks @Brumhilde .
I am not sure what to do with the additional checkbox which is present on 745 platforms.
Maybe it survives the mode changes ?
I cannot test it locally on my ET10K and I did not dare to turn it on by default on all 745 inverters.
In case it is needed, there is now new setting "eco_mode_enable" which you can turn on/off by calling service.
(If you investigate it further and provide reliable steps, I can adjust the code in next release.)

Thanks for the update @mletenay I tried it and still gives some issues:

  1. It looks like the "eco_mode_enable" is required on my GW6000 to set the blue marked checkbox below.
  2. When reading the settings the Eco mode power reads 600% while it is set to 60.0% (2nd screenshot)
  3. For some reason the "goodwe_inverter_operation_mode" entity is no longer exposed to home assistant

IMG_4830
image

I've just release v0.9.917 which I hope will address most of the problems with EcoMode. I've partially incorporated (most of) changes from your PR, thanks @Brumhilde . I am not sure what to do with the additional checkbox which is present on 745 platforms. Maybe it survives the mode changes ? I cannot test it locally on my ET10K and I did not dare to turn it on by default on all 745 inverters. In case it is needed, there is now new setting "eco_mode_enable" which you can turn on/off by calling service. (If you investigate it further and provide reliable steps, I can adjust the code in next release.)

Got some info from goodwe and a new register map as of February 2024.

IMG_1113 IMG_1114

GoodWe BESS Modbus protocol Map V1.2 20240202(1).pdf

Unfortunately my et15k is placed behind a gateway so I cannot access it anymore. Only sems...

Best regards

@marcelblijleven looks like the latest version is working fine on my GW6000. Thanks a lot, will try more functions but General, Self use abd ECO discharge is working fine now including limiting the power.