wimb0 / home-assistant-saj-r5-modbus

Home Assistant Component for reading data locally from SAJ R5 (and Zonneplan One) Inverters through modbus TCP.
MIT License
31 stars 14 forks source link

Add export limitation as service call #75

Closed tcoenraad closed 5 months ago

tcoenraad commented 8 months ago

To be able to automatically turn off the inverter (e.g. when dynamic prices are negative), I'd like to use the 801FH register (see page 20). Can you add that feature?

wimb0 commented 7 months ago

I will look in to this. Unfortunately I do not have an SAJ inverter anymore, so it will take some time to get this done. Maybe someone else can help adding this?

tcoenraad commented 6 months ago

I do have an SAJ inverter so I can help you test any implementation when needed.

OmegaAlfa7 commented 6 months ago

I will look in to this. Unfortunately I do not have an SAJ inverter anymore, so it will take some time to get this done. Maybe someone else can help adding this?

I second this request, because with dynamic prices, a controleable power slider / export limiter would be a super nice feature to have!

HindrikDeelstra commented 5 months ago

After spending several hours to try to get anything working, it looks like I finally made some progress! I am not a programmer, and I am largely unfamiliar with Python and Modbus in general, but I think I now know how to write a value into the "Power Limit" register of the SAJ R5 (Zonneplan One) inverter.

The register at address 0x801F (or 32799 in decimal notation) accepts an integer value, and the documentation comments it is a "percentage". The docs omit the "Scale factor", but it seems this is "-1", meaning that the value in the register is to be divided by 10 to get the actual percentage.

Eg.: a register value of "1000" means "100%", and a register value of "500" means "50%", etc.

This percentage is of the maximum rated power output of the inverter. Mine is a 4 kW version, so a percentage of 25% corresponds to a 1 kW output limit for my inverter.

One could issue the following to set the register value to (desired power percentage * 10):

I've tested this using "pymodbus.console" in my HA docker container. From this cli, one can simply omit anything but the first value from the "values" parameter, and this works (setting power limit to 50% of maximum in the below example):

client.write_registers address 0x801F values 500 slave 1

Calling the "modbus.write_register" (singular) service_call from within HomeAssistant in an automation for instance, does require the "value" to be an array (or python list object). This causes the code to issue a "write_registers" call, whereas it would issue a "write_register" call if there is only a single value. It may also contain just the one value, but it must be formatted as an array/list.

This is my currently working automation "action":

- service: modbus.write_register data: hub: saj_solar_inverter address: 32799 slave: 1 value: - '{{ states(''input_number.solar_power_output_wanted'')|int * 10 }}'

The "hub" value is the self-defined name in the "modbus:" section of HA's configuration.yaml (or the corresponding config-file loaded there).

The "input_number.solar_power_output_wanted" is a helper I created, that changes its value based on triggers for the energy price of the current hour...

Any changes to this input_number helper then trigger the abovementioned action/service call, limiting the export power to the correct percentage...

I hope this helps!

HindrikDeelstra commented 5 months ago

@wimb0 to recap for a possible implementation into the repo: the Modbus function to write to the 0x801F register needs to be the "write_registers"(plural) call, with the value(s) being an array/list containing 1 element, that has a value of (percentage * 10)|int ;)

mvn23 commented 5 months ago

I added the number entity and filed a PR. Please let me know if anyone has found a way to retrieve the current value from the inverter and I'll update the code.

HindrikDeelstra commented 5 months ago

I added the number entity and filed a PR. Please let me know if anyone has found a way to retrieve the current value from the inverter and I'll update the code.

I have not been able to find a way to read the current setting from the register. The docs mention it's a "Write Only" type register, so I'm assuming the manufacturer did not intend it to be retrievable, only writable.

I have tested your code (briefly!), and it seems to be doing exactly as intended! The slider allows for an export limit, and the numbers very nicely match the expected output limits (i.e. setting the slider to 10% adjusts the actual power output of my 4 kW inverter to roughly 400 W).

So, at first glance and quick test, your commit(s) seem to be doing precisely what was requested ;)

wimb0 commented 5 months ago

@mvn23 Thanks for the work on implementing this. I will merge your pull request and release it as beta version. If anyone wants to test version v2.0.0-beta, and let me know if it all works fine, I will make a final release.

HindrikDeelstra commented 5 months ago

@wimb0 I've checked out the 2.0.0-beta version, and restarted HomeAssistant.

Everything seems to be working just fine! All sensors and their states remain intact and are updated every scan_interval. The power limit slider is present under a "Controls" section of the device, which seems appropriate. It also still works of course ;)

I see no immediate and obvious problems/issues with this release, and no warnings or errors in the logs when (re)loading this integration.

TL;DR: All seems well!

tcoenraad commented 4 months ago

Works on our installation too 🥳