springfall2008 / batpred

Home battery prediction and charging automation for Home Assistant, supporting many inverter types
https://springfall2008.github.io/batpred/
129 stars 44 forks source link

Solis inverter still charging when "hold charge" value is reached #852

Open FarmingMartin opened 8 months ago

FarmingMartin commented 8 months ago

I have noticed that if there is a charge window active and predbat runs a scan and changes the mode to "hold Charge" or "idle" it continues to keep charging the battery until the charge window end time is reached. solis error log.txt

i have attached part of my error log of when this occured.

springfall2008 commented 8 months ago

So the log says:

2024-03-14 23:40:14.404674 INFO pred_bat: Setting Solis Energy Control Switch to 3 from 35 to disable grid charging 2024-03-14 23:40:16.410348 INFO pred_bat: Inverter 0 Wrote select.solismod_energy_storage_control_switch to Timed Charge/Discharge - No Grid Charging successfully 2024-03-14 23:40:16.413909 INFO pred_bat: Current SOC 31% is greater than Target SOC 0. Grid Charge disabled. 2024-03-14 23:40:16.417499 INFO pred_bat: Adjust reserve to default as SOC 31 % is above target 30 % or charging active 2024-03-14 23:40:16.422131 INFO pred_bat: Inverter 0 Current Reserve is 80.0 % and new target is 15.0 % 2024-03-14 23:40:18.430631 INFO pred_bat: Inverter 0 Wrote 15.0 to reserve, successfully now 15.0 2024-03-14 23:40:18.465031 INFO pred_bat: Completed run status Hold charging

Does that write of 3 to energy control switch not do the right thing?

springfall2008 commented 8 months ago

Can you check what select.solismod_energy_storage_control_switch is actually set to during this time?

I wonder if it should have disabled timed as well?

FarmingMartin commented 8 months ago

It appears that the "charge from grid" switch either has no effect on normal battery charge, or only comes into effect when forced charge is triggered when the battery reaches the force charge level SOC. Turning the "timed charge" switch however does have an effect of stopping or starting the grid charging process.

springfall2008 commented 8 months ago

Could you test a potential fix on this branch: https://github.com/springfall2008/batpred/tree/solis?

springfall2008 commented 8 months ago

I've updated on the branch to ensure the timed flag is set when charging and not set when not charging

stevebuk1 commented 8 months ago

From discussions in the Solis Inverter Owners Facebook group on this issue, its clear that not all Solis inverters respond to the Grid charging control that is Bit 6 (LSB = Bit 0, MSB = Bit 7) in the Energy Storage register.

For my Solis inverter (RHI-3.6K-48ES-5G), Bit 6 is respected. If within the times of a charge window times as set on the inverter: 1) Setting the Energy Control Switch to 3 disables grid charging and holds the SOC by not supplying the house load. 2) Setting the Energy discharge switch to 33 disables timed charging but no longer holds the SOC, it goes back to the batteries supplying the house load.

As of v17.6.6, the code achieves hold SOC functionality within a charge window by setting the charge current to zero, which should work on any Solis inverter, means mode (1) above is not used or needed, and the above branch changes should work for all inverters.

FarmingMartin commented 8 months ago

Setting the charge value to zero does indeed work, however there is a small issue in the fact that setting the charge current to zero stops battery charging from all sources, I.E grid and solar, so if this is used during solar production then excess solar is exported back to the grid. I experance this yesterday where my battety was at 30% charges. And solar production was higher then house load, which resulted in excess solar being exported back to the grid, (for free as i am on FIT with deemed export) and not to my battery resulting in my battery dropping later to minimum charge level so house load was then drawn from the grid at peak price.

Setting a charge time window with a charge rate of 0 effectively turns the battery off, resulting in no charge or discharge to or from the battery.

stevebuk1 commented 8 months ago

The SOC hold functionality that I added by setting current to zero when battery SOC equals target SOC was designed for use within a charge window, i.e. the inverter is set to Timed Charge/Discharge and the inverter is between the start and stop times, and PredBat is in mode "Charging". Within a charge window we ideally want to charge at a constant current for the whole window and at a rate which means the inverter reaches its target SOC at the end of a window. If the inverter has been set to charge at a current, it cannot do anything other than charge the batteries at that rate - it simply doesn't have the ability to allow a higher charge rate just because some Solar happens to be available. The zero current mode was introduced to prevent continual oscillation between charging at the whatever the charge rate was previously set to and discharging the battery to support the house load (which given we are in a charge window, we don't want to do).

When PredBat is in status Idle, the house load is supported firstly by solar and then by batteries, this is SelfUse mode on the inverter and should now work fine, given the changes made above to clear the Timed flag, i.e. revert to SelfUse on the Solax HA integration rather than "Timed Charge/Discharge - no Grid Charging" that it did previously (that does not work on all Solis inverters).

The Predbat Status "Hold Charging" is a special case. In the Predbat documentation it is stated "Hold charging - A type of charge where the target SOC % is the same as the current SOC %, effectively the same as a charge freeze (but without being explicitly selected". "Charge freeze" is documented as: "The battery is charging but the current battery level (SoC) is is frozen (held). Think of it as a charge to the current battery level. The grid or solar covers any house load. If there is a shortfall of Solar power to meet house load, the excess house load is met from grid import, but if there is excess Solar power above house load, the excess solar will be used to charge the battery"

From your description above, that is what you are expecting the inverter to do in 'Hold Charging'. The problem is is that 'Charge Freeze' is not a mode that Solis inverters support, as evidenced by the setting "support_charge_freeze": False" at line 909. As far as I can tell, it was intended that Predbat would then set 'Backup/Reserve' on the Solax integration and use 'Backup SOC' to control this, but despite the positive messages that Predbat generates regarding setting the Backup SOC, I found it was not being set because writes to this register are only successful if one is in Backup/Reserve mode already. The Predbat documentation acknowledges the unfinished nature of this: "If you want to use the Reserve functionality within PredBat you will need to select Backup/Reserve (code 51) instead but be aware that this is not fully tested. In due course these mode settings will be incorporated into the code.". It was for this reason that I disabled use of Backup SOC and Backup Reserve mode, and instead relied on charge windows and charge current.

My understanding of GivEnergy inverters is that they have a target SOC value and a charge rate value, and when in a charging window, once the target SOC is reached by charging from grid at the charge rate value, they stop charging, continue to ensure the house load is supplied by grid, but if any Solar is available then top the battery up with that. This is pretty much the definition of 'Charge Freeze'. However, Solis inverters in Backup/Reserve mode will charge at full power to reach the target SOC, then switch back to SelfUse whilst the SOC remains above the target (which it will do on a sunny day). This does mean that any available Solar will charge the battery, but it does also mean that if the sun goes in the battery will discharge to supply the house load and on rainy days the hold charge slot will contain periods of full rate charging. Incidentally on my Solis inverter it may be possible to prevent grid charging using Bit 6, but we've already worked out that doesnt work on RHI inverters.

In other words, whatever we do with a Solis in 'Hold Charging' will be a compromise because it simply doesn't support freeze charge. Its a case of retaining SOC but exporting/throwing away excess solar, or accepting battery discharge to meet house load interlaced with full rate charge bursts. As IOG charge periods are always at night and I've never seen a Hold Charging status, I went for the former.

From what you've seen, do you think going with the latter will correct the problem, as I suspect Freeze Charge /Hold Charge period calculations will assume any house load not covered by solar will be coming from the grid rather than the battery?

FarmingMartin commented 8 months ago

Thank you for your detailed explanation. I will monitor how predbat works with my inverter over the next few weeks.

gcoan commented 8 months ago

My understanding of GivEnergy inverters is that they have a target SOC value and a charge rate value, and when in a charging window, once the target SOC is reached by charging from grid at the charge rate value, they stop charging, continue to ensure the house load is supplied by grid, but if any Solar is available then top the battery up with that.

Just to confirm that you're correct, this is the way the GivEnergy inverters work.

stevebuk1 commented 8 months ago

Just to confirm that you're correct, this is the way the GivEnergy inverters work.

Thanks! Its quite a natty mode, I wish the Solis inverters were similar!

springfall2008 commented 7 months ago

Could you test a potential fix on this branch: https://github.com/springfall2008/batpred/tree/solis?

Do we want this change or not, sorry I lost track?

FarmingMartin commented 7 months ago

I have tried the fix and unfortunatly it stalls predbat. Resulting in predbat not updating its charging plan as batpred is still stuck on the same time. I have tried it 3 times with the same result. I will have another check over the weekend incase I have missed somthing with in the code edits.

springfall2008 commented 7 months ago

I have tried the fix and unfortunatly it stalls predbat. Resulting in predbat not updating its charging plan as batpred is still stuck on the same time.

I have tried it 3 times with the same result. I will have another check over the weekend incase I have missed somthing with in the code edits.

Did you copy the .py file directly from the branch?

FarmingMartin commented 7 months ago

Yes, I think I did. I opened the edited file on my laptop, which also had my HA page open, and opened the original file in file editor. I then copied the amendments and pasted them into the original file. As I said, I will try it again as it was getting late when I tried it and so I could have missed something. I'll report back here with my findings.

FarmingMartin commented 7 months ago

I have again amended the .py files to the edited version and again im experancing the same problem as stated above. there is no plan displayed even after a restart. i have added a copy of the log from the restart (19:35) it also shows the log from when i restored the original files (19:45) error log.txt

FarmingMartin commented 7 months ago

Screen after edits 20240323_194425

Screen after restoring original files 20240323_194533

stevebuk1 commented 7 months ago

Ive just replaced the entire file with the one in the branch and all seems fine, the Solax integration has now gone to "SelfUse - no grid charging" in Idle mode which means the timed flag is cleared. My Predbat plan has updated.

Can i ask that if this branch is ported back into main, then use of the timed flag in addition to the grid flag is made an option in apps.yaml? Reason is I'm in the process of adding Solis fixes to ensure the house battery isn't discharged when the EV is charging in IOG slots and there aren't any charge slots scheduled. Setting Discharge to 0 doesn't do anything if there is no start and end time uploaded to the inverter, so the new code sets these when Predbat is in status "Hold car", for which I'll need to be in Timed Charge/Discharge mode. I can also do an inverter mode change for this but thats much more complicated as the car logic is in advance of "alt_charge_discharge_enable" which would overwrite it.

image

image

stevebuk1 commented 7 months ago

I have again amended the .py files to the edited version and again im experancing the same problem as stated above. there is no plan displayed even after a restart. i have added a copy of the log from the restart (19:35) it also shows the log from when i restored the original files (19:45) error log.txt

If you are running HA on a Raspberrry PI then I'd try installing Samba as an HA add-on (see screenshot below), then you can add the file system on the Pi as a drive on your PC (right click, choose "Map network drive"). Then its a case of just replacing predbat.py on your Pi with the one stored on this branch. No restart is needed, Appdaemon recognizes the change and just recalculates everything.

image

FarmingMartin commented 7 months ago

I'm not using a pi but have it on a Nuc. You mentioned replacing the .py file with the one in this branch. I may be missing something as I am editing my original .py files with the highlighted edits shown. Is there a whole copy I just need to replace my existing. Py file with and if so how do I find it?

stevebuk1 commented 7 months ago

Editing should work but one slight error and the whole lot falls in a heap.

Source file from this branch is here, this is the only file that has changed: https://github.com/springfall2008/batpred/blob/solis/apps/predbat/predbat.py

And hit the "download raw file" button: image

The path to predbat.py on your NUC should be something like this: /homeassistant/appdaemon/apps/batpred/predbat.py

FarmingMartin commented 7 months ago

thanks just done that. seems to be working now so i must of got something wrong before.

stevebuk1 commented 7 months ago

thanks just done that. seems to be working now so i must of got something wrong before.

Great, hope the code change solves your problem.

Trefor - please note my request on apps.yaml switch for timed = off in Idle mode, hopefully only temporarily.

springfall2008 commented 7 months ago

Now merged to MAIN.

Have you seen this ticket, just wondering if I should push this update but it will break older versions of the plugin? https://github.com/springfall2008/batpred/issues/877

springfall2008 commented 7 months ago

in, then use of the timed flag in addition to the grid flag is made an option in apps.yaml? Reason is I'm in the process of adding Solis fixes to ensure the house battery isn't discharged when the EV is charging in IOG slots and there aren't any charge slots scheduled. Setting Discharge to 0 doesn't do anything if there is no start and end time uploaded to the inverter, so the new code sets these when Predbat is in status "Hold car", for which I'll need to be in Timed Charge/Discharge mode.

I'm not sure I understand, I think the logic should go into predbat.py and not be something users have to fiddle with in apps.yaml?

stevebuk1 commented 7 months ago

in, then use of the timed flag in addition to the grid flag is made an option in apps.yaml? Reason is I'm in the process of adding Solis fixes to ensure the house battery isn't discharged when the EV is charging in IOG slots and there aren't any charge slots scheduled. Setting Discharge to 0 doesn't do anything if there is no start and end time uploaded to the inverter, so the new code sets these when Predbat is in status "Hold car", for which I'll need to be in Timed Charge/Discharge mode.

I'm not sure I understand, I think the logic should go into predbat.py and not be something users have to fiddle with in apps.yaml?

It was just that doing an inverter mode change for 'Hold car' is complex. I was hoping to introduce "Hold Car" changes for RHI models first (that respect the grid flag and thus don't need mode changes prior to this merge), then PHI models (that don't respect the grid flag, that do need mode changes, and which I can't test). Separating the two with a switch in apps.yaml allows a phased approach. The default could still be using both grid and timed, so the only person who would initially need to set it as 'grid only' would be me, and then anyone else using an RHI who wanted to do EV charging, noting "Hold car" doesn't work on any Solis inverter right now.

stevebuk1 commented 7 months ago

Have you seen this ticket, just wondering if I should push this update but it will break older versions of the plugin? #877

I think your code does Bit-wise operations on Bit 1 (Timed) and Bit 5 (grid), calculates the decimal value and then performs a lookup on the right text to pass to the entity "select.solis_energy_storage_control_switch". (if only this was a number!).

Looking at the changes:

To maintain backwards compatibility, the entity exposes the various options under the "options" attribute. Would it be possible ro read these, do a match against two lists of SOLAX_SOLIS_MODES and set against the match?

image

Noodleyman commented 7 months ago

Just wanted to add, that I am seeing the same issue as reported by @FarmingMartin on SolarEdge inverters as well with regards to hold charge status.

Hold charge puts the inverter into "Charge from Solar power and Grid" mode, which continues to pull power from the grid, even if it's exceeded the target SOC. It then seems to get into some kind of loop until the battery is 100% charged, at which point it flips to idle.

I wanted to share in case it's a more general issue.

FarmingMartin commented 7 months ago

Hold charging is still not working correctly in my opinion. I have noticed when holding charge is active all charging stops including charge from solar, is this correct? My battety was 70% charged and solar was producing excess so exporting to Grid instead of going to cgarge the battery. Please can you advise if this is correct and if do what the hold charge function is actually for. Thanks