Solaredge Modbus Configuration for Single Inverter and Battery

I would just leave that option turned off then.

It’s possible never closing the connection triggers a bug in the firmware version for your inverter like a memory leak or something with long connections.

Even with it off there seems to be an issue, although possibly not as bad. I’ll take a look at logs when I have time.

You should see a difference at least with retry attempts when it times out.

I’ve uploaded a new log file to the same link as previously. This covers a day with v2.4.11-pre.1 and Keep Modbus Open set to off. It’s worked throughout the day, but there have been some slow connection times and a number of times where data refresh attempts have hit 4. At present it seems to have survived with Keep Modbus Open set to off. I’ll keep an eye on things for now.

Thanks for the help.

I just uploaded Release v2.4.11-pre.2 to try and address another report about timeouts. This version reduces the size of some modbus reads.

I’ve installed v2.4.11-pre.4 now - I’ll keep an eye on it.

Pre-releases 2-6 turned out to be chasing the wrong issue.

Release 2.4.11-pre.7 goes back to .1 but removes the internal requirement to keep the modbus connection open for polling intervals less than 10 seconds.

It seems like all of these problems with timeouts can be traced back to the keep modbus connection open option and the inverter response becoming slower over time as the number of reads increases without closing the connection. I don’t see this problem personally, but my inverters are running firmware 4.0014.0229 so if this is a problem with newer inverter firmware versions I won’t see it.

So basically if anyone is having timeout issues make sure the “Keep Modbus Connection Open” is turned off. I recommend it be kept off anyway unless there is a specific problem that it helps with.

1 Like

Ok - I’ll try v2.4.11-pre.7 with Keep Open off and see what happens. I’ve continued to have issues with v2.4.11-pre.4 - better but still losing the connection after some time.

Hi! I was thinking for an automation for increase the “reserve” battery in winter, and not allow to be fully drained for too much time (if we swing from 50% to 0% it’s the same to swing from 100% to 50%, but increasing the life of the battery). I’ve seen some ideas here, but i was thinking for something automatic.
I was thinking to detect the prolonged usage at low battery levels in 2 ways:

  1. If average battery % of n days is under a value
    Or
  2. If average time spent of last n days at the minimum % is over a predefined amount.
    The system activate an automatism, that if the next day (after n days) is still under the percentage, it increase the % limit by 5%. Else decrease it.
    In this way the average battery % (or time spent at low %) increase, and the system “autocalibrate”.
    If 1. Or 2. Are not met for 7 consecutive days, the day counter will reset, and the depth of discharge is reset to it’s defualt value.

Seem a good logic?

1 Like

Quick update - still getting lost connections, not as frequently, but still happening. I’ve put the latest logs on the Shared folder if they help at all.

The config is currently as:

When I get this repair, when I click though I always get issue repaired.
image

Even when the inverter is offline.
image

Is it possible for the repair dialog to verify that it has restored communications?

The repair dialog only pushes a settings update to Home Assistant, it doesn’t do anything to restore a connection.

1 Like

HI,

I successfully added the integration, where i can find some details about the meaning
especially for the highlighted sensors?

image

is the Status mapped by the DEVICE_STATUSSES?

DEVICE_STATUSSES = {
1: “Off”,
2: “Sleeping (auto-shutdown) – Night mode”,
3: “Grid Monitoring/wake-up”,
4: “Inverter is ON and producing power”,
5: “Production (curtailed)”,
6: “Shutting down”,
7: “Fault”,
8: “Maintenance/setup”,
}

is the Status Vendor mapped by the I_Status_Vendor?

or

Is status mapped on Battery Status and
Status Vendor mapped on Status Internal as described in the documentation?

image

second, as I have a single phase, I disabled all of these sensors, did I missed something?

I use the SolarEdge Inverter SE6000H with the Tesla PowerWall2, so I’m more interested on invertert status and optimizer stats

Hi!
I have the @wilcodeforcats solaredge modbus multi integration installed. And it works to change the storage command mode from the UI to all available alternative.

But i get error when trying to change the storage command mode from tautomation made by the UI! Have stripped the automation to a test automation only changing storage command tiimeout (as discrebed by others) and the storage command mode.

Help would be much appreciated.

Getting this error in the log:

Logger: homeassistant.components.automation.auto_test_storage_command_timeout
Källa: helpers/script.py:485
integration: Automation (dokumentation, ärenden)
Inträffade först: 17:02:41 (2 händelser)
Senast loggade: 17:25:45

Auto_test_storage_command_timeout: Error executing script. Unexpected error for device at pos 2: 'NoneType' object has no attribute 'write'
Auto_test_change_storage_command_mode: Error executing script. Unexpected error for device at pos 2: 'NoneType' object has no attribute 'write'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 485, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 739, in _async_device_step
    await device_action.async_call_action_from_config(
  File "/usr/src/homeassistant/homeassistant/components/device_automation/action.py", line 71, in async_call_action_from_config
    await platform.async_call_action_from_config(hass, config, variables, context)
  File "/usr/src/homeassistant/homeassistant/components/select/device_action.py", line 121, in async_call_action_from_config
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 2319, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2356, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 905, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 975, 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/solaredge_modbus_multi/select.py", line 291, in async_select_option
    await self._platform.write_registers(address=57357, payload=new_mode)
  File "/config/custom_components/solaredge_modbus_multi/hub.py", line 1358, in write_registers
    await self.hub.write_registers(self.inverter_unit_id, address, payload)
  File "/config/custom_components/solaredge_modbus_multi/hub.py", line 543, in write_registers
    result = await self._client.write_registers(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pymodbus/client/base.py", line 167, in async_execute
    self.send(packet)
  File "/usr/local/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 391, in send
    self.transport.write(data)  # type: ignore[attr-defined]
    ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'write'
Logger: homeassistant.components.automation.auto_test_storage_command_timeout
Källa: components/automation/__init__.py:666
integration: Automation (dokumentation, ärenden)
Inträffade först: 17:02:41 (2 händelser)
Senast loggade: 17:25:45

While executing automation automation.auto_test_storage_command_timeout
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/automation/__init__.py", line 666, in async_trigger
    return await self.action_script.async_run(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1600, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 435, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 487, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 512, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 485, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 739, in _async_device_step
    await device_action.async_call_action_from_config(
  File "/usr/src/homeassistant/homeassistant/components/device_automation/action.py", line 71, in async_call_action_from_config
    await platform.async_call_action_from_config(hass, config, variables, context)
  File "/usr/src/homeassistant/homeassistant/components/select/device_action.py", line 121, in async_call_action_from_config
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 2319, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2356, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 905, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 975, 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/solaredge_modbus_multi/select.py", line 291, in async_select_option
    await self._platform.write_registers(address=57357, payload=new_mode)
  File "/config/custom_components/solaredge_modbus_multi/hub.py", line 1358, in write_registers
    await self.hub.write_registers(self.inverter_unit_id, address, payload)
  File "/config/custom_components/solaredge_modbus_multi/hub.py", line 543, in write_registers
    result = await self._client.write_registers(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pymodbus/client/base.py", line 167, in async_execute
    self.send(packet)
  File "/usr/local/lib/python3.12/site-packages/pymodbus/transport/transport.py", line 391, in send
    self.transport.write(data)  # type: ignore[attr-defined]
    ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'write'

After some fiddling around and internet search found a solution by instead of using the function “change something on entitiy” as above, I used the function "input_select:select_option
with destionation I1 inverter
and option to whatever.

That works. Have no idea why this would make the difference, but someone else might have?

Anyone can help me here?
Integration is working, but the sensor status shows the numbers and not the corresponding meaning. That’s the expected behavior?

I see that there is the attribute description that is doing what i’m looking for

You should try my integration instead, it shows the state name instead of a number.

Hello you all,

I’m looking for a “nice” way to keep the discharge limit over the nightly disconnects. Currently if I set discharge limit to maybe 1000 W, during the nightly disconnect it gets reset to 5000 W.

I know a way how to do it. I could simply make booleans for fixed discharge limits (one for 500 W, one for 1000 W) and build automations, that check every reconnection, if one of these is on and set the discharge limit to the according limit again.

However I would like to have a solution that works with flexible Discharge limits. So I need a way to read the currently set discharge limit the moment the Inverter becomes unavailable, save this value somewhere and re-apply it, once the inverter comes back after a few seconds.

I could work with a helper (input.number) that syncs automatically with the value in the integration. That way, the value would still be available once the inverter becomes unavailable. But I don’t know how to save that value and re-apply it after the inverter becomes available again and the discharge limit is set back to 5000 W.

I hope you understand what I mean and someone can give me a hint…

Thanks in advance!

Hi, great work on this custom integration. Thank you for all the hard work. I have been using this for the best part of the last year and it’s been working mostly without any problems. Recently I found my automation randomly not working. I’ve set it to charge from the grid at night and returning back to TOU settings using the Storage Control Mode & Storage Default Mode. It fails and I have copied the logs here if anyone can help. Many thanks and much appreciated

Setup: 2 inverters & 2 batteries

Log Details (ERROR)

Logger: homeassistant.components.automation.23_30_io_batt_charge
Source: helpers/script.py:507
integration: Automation (documentation, issues)
First occurred: 9 April 2024 at 23:30:03 (1 occurrences)
Last logged: 9 April 2024 at 23:30:03

++ 23:30 Batt Charge: Error executing script. Unexpected error for device at pos 1: ‘NoneType’ object has no attribute ‘write’

Traceback (most recent call last): File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 507, in _async_step await getattr(self, handler)() File “/usr/src/homeassistant/homeassistant/helpers/script.py”, line 753, in _async_device_step await device_action.async_call_action_from_config( File “/usr/src/homeassistant/homeassistant/components/device_automation/action.py”, line 72, in async_call_action_from_config await platform.async_call_action_from_config(hass, config, variables, context) File “/usr/src/homeassistant/homeassistant/components/select/device_action.py”, line 122, in async_call_action_from_config await hass.services.async_call( File “/usr/src/homeassistant/homeassistant/core.py”, line 2543, in async_call response_data = await coro ^^^^^^^^^^ File “/usr/src/homeassistant/homeassistant/core.py”, line 2580, in _execute_service return await target(service_call) ^^^^^^^^^^^^^^^^^^^^^^^^^^ File “/usr/src/homeassistant/homeassistant/helpers/service.py”, line 971, in entity_service_call single_response = await _handle_entity_call( ^^^^^^^^^^^^^^^^^^^^^^^^^^ File “/usr/src/homeassistant/homeassistant/helpers/service.py”, line 1043, 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/solaredge_modbus_multi/select.py”, line 145, in async_select_option await self._platform.write_registers(address=57348, payload=new_mode) File “/config/custom_components/solaredge_modbus_multi/hub.py”, line 1358, in write_registers await self.hub.write_registers(self.inverter_unit_id, address, payload) File “/config/custom_components/solaredge_modbus_multi/hub.py”, line 543, in write_registers result = await self._client.write_registers( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File “/usr/local/lib/python3.12/site-packages/pymodbus/client/base.py”, line 167, in async_execute self.send(packet) File “/usr/local/lib/python3.12/site-packages/pymodbus/transport/transport.py”, line 391, in send self.transport.write(data) # type: ignore[attr-defined] ^^^^^^^^^^^^^^^^^^^^ AttributeError: ‘NoneType’ object has no attribute ‘write’