fboundy / pv_opt

Home Assistant PV Optimisation for Solis Inverters
MIT License
19 stars 4 forks source link

Support for Sunsynk inverter via Solarsynk2 add-on for Home Assistant #129

Open ElectricMolehill opened 4 months ago

ElectricMolehill commented 4 months ago

Hi fboundy

regards Mark

PV Opt can be updated to support additional models and brands of inverter. If you want to request this, please supply as much of the following information as possible:

Home Assistant Entities to Read

PV Opt reads data from a number of entities in Home Assistant. These will vary by inverter. Please document what your inverter provides. Examples are provided from the Solis Solax Modbus integration:

Battery minimum SOC: number.solis_battery_minimum_soc
Battery SOC:         sensor.solis_battery_soc
Either:
  Load power:        [sensor.solis_house_load, sensor.solis_bypass_load], or
  Load today:        sensor.solis_house_load_today
Either:
  Grid import power: sensor.solis_grid_import_power and
  Grid export power: sensor.solis_grid_export_power
Or:
  Grid import today: sensor.solis_grid_import_today and
  Grid export today: sensor.solis_grid_export_today

Inverter Control

PV Opt also needs to control your inverter. How this is done and what can be done varies hugely by brand, by model and by the integration you use with Home Assistant. Please provide as much detail under each heading. Examples are provided for the Solis inverter using the both the Solax Modbus Integration and the HA Core Modbus functionality. Please add your details below:

Examples

Solis Solax Modbus Solis Core HA Modbus
How do you enable forced charging? Only done via timed charge Only done via timed charge
How do you enable forced discharging? Only done via timed discharge Only done via distimed charge
Are forced charge and discharge controlled using Power or Current? Current Current
Does your inverter support timed charging slots? Yes Yes
Does your inverter support timed discharging slots? Yes Yes
How do you enabled timed charge? Set the following: number.timed_charge_start_hour, number.timed_charge_start_minute, number.timed_charge_end_hour, number.timed_charge_start_minute. Then press 'button.solis_update_charge_discharge_times. Set the required current to number.solis_timed_charge_current. Ensure select.solis_energy_storage_control_switch has Timed Grid Charging enabled. Use the modbus\write_register service to write start and end hours and minutes to the correct registers. Ensure the energy_storage_control_switch has Bits 2 and 5 enabled. Set the required current using the modbus\write_register service
How do you enabled timed charge? As for charging but all entities are discharge rather than charge As for charging but registers are different.
Can you set a target SOC for a timed charge period? No No
Can you set a target SOC for a timed discharge period? No No
What modes does you inverter have and how are they controlled? One register on the inverter Energy Control Switch which controls mode in a bit-wise sense. Only some modes can be selected vai the entity select.solis_energy_storage_control_switch One register on the inverter Energy Control Switch which controls mode in a bit-wise sense. The required number is set using the modbus\write_register service

Your Setup

What is the inverter brand?

Sunsynk

What is the inverter model?

ECCO 3.6kW hybrid inverter SYNK-3.6K-SG04LP1

What integration do you use in Home Assistant

Solarsynk2 add-on. There is another one Deye/Sunsynk Home Assistant add-on by kellerza but this requires a direct wired connection to the inverter

How do you enable forced charging?

Only done via a timer. Set a time slot x, tick grid time x to allow charging from grid, target SOC x (above current SOC) and power x. 6 slots are available

How do you enable forced discharging?

Only done via a timer. Set a time slot x, tick grid time x to allow charging from grid, target SOC x (below current SOC) and power x

Are forced charge and discharge controlled using Power or Current?

Power (W) and target SOC whichever is the smaller

Does your inverter support timed charging slots?

6 slots used for charge and discharge. Should be contiguous, sequential and cover the whole 24 hrs

Does your inverter support timed discharging slots?

Same timeslots as for charging but with a different target SOC

How do you enabled timed charge?

Set Use Timer = true To do this, populate helper inputtext.solarsynk{inverter serial no}_settings with json to update Sunsynk cloud api: {"peakAndVallery": "1"} (just possible this is a misspelling) Also required for slot x - Start time ("sellTime(x)": "02:00") Grid timer x ("time(x)on": true) Target SOC ("cap(x)": "80") if this is higher value than current SOC, batteries wil charge up to this value from the grid Power x ("sellTime(x)Pac": "3600") End time is defined implicitly by the start time of the next slot. An appdaemon process runs every 5 min to post the contents of this helper to the Sunsunk cloud api. This is not ideal because it's not online. Perhaps I could get the Solarsynk developer martinville to add a realtime update method

How do you enabled timed discharge?

As for charging but set target SOC low

Can you set a target SOC for a timed charge period?

Yes - this would be the usual manual method

Can you set a target SOC for a timed discharge period?

Yes

What modes does you inverter have and how are they controlled?

There are some settings which limit export to load or grid. Details to be confirmed but probably should be set manually

Any other useful information

See attached doc sunsynk inverter class for pv_opt.odt

ElectricMolehill commented 4 months ago

Forgot to add HA entities to read:

Battery minimum SOC: sensor.solarsynk_{inverter sn}_battery_shutdown_cap (%)
Battery SOC:         sensor.solarsynk_{inverter sn}_battery_soc (%)
Either:
  Load power:        sensor.solarsynk_{inverter sn}_load_power (kW), or
  Load today:        sensor.solarsynk_{inverter sn}_day_load_energy (i.e kWh)
Either:
  Grid import power: sensor.solarsynk_{inverter sn}_grid_power (this is probably total import and export)
  Grid export power: 
Or:
  Grid import today: sensor.solarsynk_{inverter sn}_day_grid_import (kWh) and
  Grid export today: sensor.solarsynk_{inverter sn}_day_grid_export (kWh)
fboundy commented 4 months ago

I can certainly try to get something working for you. It may take a while - need to solve a few other bugs 1st.

ElectricMolehill commented 4 months ago

That's great, thankyou. The installation's only been in for a week and we're not certified to export yet. Then I'll need to familiarise myself with programming it manually. What do you think about the update settings method provided by the Solarsynk add-on? It takes up to 5 min to send to the cloud, then maybe another 5 min until the results are readable from HA sensors. Is that fast enough?

regards Mark

fboundy commented 4 months ago

OK - I've had a very preliminary start at this. It will is v4.0.0-alpha-1 pre-release so you will need to enable Beta versions in HACS and manually select it. You will also need the config_sunsynk.yaml file from the GitHub release or the branch associated with this Issue (rename it to config.yaml

If you are very lucky it might work in Read Only mode! Either way please send me the logs. In the meantime I will try to have a look at the documentation for the integration.

ElectricMolehill commented 4 months ago

Thanks I'll give it a go! I'll try to clarify the working modes for the inverter tomorrow - they control whether the inverter gives priority to essential load / non-essential load / battery / grid export. I've also discovered another check we should do - the inverter will support battery types which use voltage instead of SOC to control charge / discharge so we should check that the battery is compatible with SOC. Also, I think my documentation is wrong about ticking 'Grid' for a discharge, it looks like it should be unticked. I'll update the documentation

ElectricMolehill commented 4 months ago

Sorry my mistake - {inverter sn} should be {sunsynk_serial} as defined in solarsynk addon. Also - cosmetic change - could you change the spelling of solarsync2 to solarsynk2 please. I don't know how far I can get with testing because we're not certified for export yet so we haven't changed tariff from the fixed rate Flexible Octopus to some thing smart such as Agile or Flux. Unless there's a way to bypass it for testing purposes?

ElectricMolehill commented 4 months ago

I think there are 2 typos in sunsynk.py: image

fboundy commented 4 months ago

Is there any way of extracting {sunsynk_serial} from the addon? If not I might prefer to keep {inverter_sn} as a generic parameter across brands. Will fix the typos now and re-release as alpha-2

fboundy commented 4 months ago

alpha-2 available. You will need to manually copy config-sunsynk.yaml

ElectricMolehill commented 4 months ago

[sunsynk_serial} is in the config for the Solarsynk add-on but I can't see a sensor for it

fboundy commented 4 months ago

OK - then it shouldn't matter if we call it something else in the config file. I suspect other brand/integrations may need something similar so I'd rather keep it generic where possible


From: Mark W (UK) @.> Sent: 24 February 2024 09:58 To: fboundy/pv_opt @.> Cc: fboundy @.>; Comment @.> Subject: Re: [fboundy/pv_opt] Support for Sunsynk inverter via Solarsynk2 add-on for Home Assistant (Issue #129)

[sunsynk_serial} is in the config for the Solarsynk add-on but I can't see a sensor for it

— Reply to this email directly, view it on GitHubhttps://github.com/fboundy/pv_opt/issues/129#issuecomment-1962315589, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABHJ7POK2BADLACPAGPJUUTYVG2TRAVCNFSM6AAAAABDONK3YGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNRSGMYTKNJYHE. You are receiving this because you commented.Message ID: @.***>

ElectricMolehill commented 4 months ago

Sorry but I think there's another typo: image

ElectricMolehill commented 4 months ago

Also I think the underline character is missing in {inverter_sn} on all of the sensors above

ElectricMolehill commented 4 months ago

Updated my documentation for the inverter. There are a couple of problems, such as

Apart from that I think it should work! sunsynk inverter class for pv_opt v2.odt

fboundy commented 4 months ago

That's great - I will have a proper read of this now and have a think about how to implement it

ElectricMolehill commented 4 months ago

Here are the logs from running v4.0.0 alpha2 error.log main.log pv_opt.log

fboundy commented 4 months ago

Cheers

Away on holiday this week. Will have a look when I’m back. On 4 Mar 2024 at 16:00 +0100, Mark W (UK) @.***>, wrote:

Here are the logs from running v4.0.0 alpha2 error.log main.log pv_opt.log — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

ElectricMolehill commented 3 months ago

Hope you're having a nice holiday. I made some progress by hard coding the inverter serial number in config.yaml (inverter serial number redacted manually - 10 digits, also my Octopus account has an e instead of an m):

image image

Now pv_opt gets further: error.log main.log pv_opt.log

You'll see I'm on the Octopus Flux tariff for import but don't yet have an export tariff. I have submitted the MCS certificate and permission from the DNO but I think it can take weeks to get an export MPAN number

alz41 commented 3 months ago

following developments

fboundy commented 3 months ago

I've synced this branch up with the main branch so it should now handle the lack of an export contract OK which was the point of failure before. Also added the inverter_sn to the redaction list. Released as 4.0.0-alpha3

ElectricMolehill commented 3 months ago

Hope you had a good holiday! We got our export MPAN this morning but Octopus don't seem to have taken any readings yet. Perhaps overnight. I reloaded the Octopus integration in HA and the export sensors appeared. I installed pv_opt 4.0.0-alpha4 and ran again. I reverted to the config_sunsynk.yaml from GitHub and used this to overwrite my config.yaml because pv_opt doesn't seem to be picking up some values correctly. I edited it to add the correct value of {inverter_sn}. From the logs it looks like pv_opt isn't picking up {device_name} or {inverter_sn}. Also I think there are a couple of typos in config.yaml:

fboundy commented 3 months ago

Thanks for this. In 4.0.0-alpha-5 I have removed config-sunsynk.yaml and merged all the changes in to the main config.yaml. You should just need to un-comment the final block of parameters in this file.

I've also updated the regex pattern for the MPAN.

Hopefully with the correction of SOLARSYNC2 to SOLARSYNK2 it should get a bit further. Let me know how you get on.

ElectricMolehill commented 3 months ago

Thanks - got a lot further this time but still seems to be ending with an error: ValueError: cannot reindex on an axis with duplicate labels Redaction mostly working but there are a couple of lines in pv_opt.log still containing inverter serial number and account_MPAN number One of the defaults in config.yaml still looks wrong : image Think this should read id_grid_export_today: sensor.{devicename}{inverter_sn}_day_grid_export instead of id_grid_export_today: sensor.{devicename}{inverter_sn}_day_grid_import error.log main.log pv_opt.log

alz41 commented 3 months ago

would really like to get this working

fboundy commented 3 months ago

OK - apologies for the delay. Please can you try pre-release 4.0.0-sunsynk-alpha-7 which should address the issues above and also includes various patches made to the production release.

ElectricMolehill commented 3 months ago

Thanks I'll give it a go. Actually I wasn't ready until today - SSD failed and it's taken me a week to get a replacement and recover Home Assistant from backup. We've also got some persistent connectivity problems with Solarsynk as a result of which my updates from a couple of HA automations don't seem to be working. It seems to be affecting all users of Solarsynk so it might be the cloud app that is at fault. On the plus side I'm now exporting to the grid and getting paid for it. As a result I've found out more about the Sunsynk inverter's eccentricities. For example, charge current is not controlled by the timers. Also, to discharge the batteries to the grid I need to change the Work Mode from 'Limited to Home' = 2 to 'Selling First' = 0 in real time because otherwise I can't discharge the battery to Home at other times without exporting as well. I've also found a different Sunsynk HA integration by MorneSaunders360 which also works via the cloud API but has an HA service to update the inverter which might be more appropriate for pv_opt. I'll have a look at that. In the meantime I have updated my documentation - sorry if I've misled you so far! sunsynk inverter class for pv_opt v3.odt

alz41 commented 3 months ago

OK - apologies for the delay. Please can you try pre-release 4.0.0-sunsynk-alpha-7 which should address the issues above and also includes various patches made to the production release.

Currently unable to test properly due to ongoing problems with Solarsynk.

Sunsynk.py still has references to "SUNSYNK_SOLARSYNC2" should be "SUNSYNK_SOLARSYNK2" (Lines 72, 86, 117)

error.log main.log pv_opt.log

fboundy commented 3 months ago

4.0.0-sunsynk-alpha-8 should fix the typos and also bring the underlying code up to date with the latest production release

ElectricMolehill commented 3 months ago

I think I've got the latest version but it's reporting

When I start the application it is stuck at 'Initialising PV model'. There is a warning in error.log:

fboundy commented 3 months ago

Sorry about that. Fixed both of those so the latest is still 4.0.0-sunsynk-alpha-8

ElectricMolehill commented 3 months ago

Got a lot further this time - stopped at Optimising Charge Plan with an error error.log main.log pv_opt.log

fboundy commented 3 months ago

The error is because the SOC is nan at 20:02:22.

It should just be interpolating any non-numeric states to prevent this. I did fix this code in the production version so maybe that didn’t get merged into this branch properly. I’ll check it tomorrow and if necessary add a bit more logging to diagnose further. On 28 Mar 2024 at 20:15 +0000, Mark W (UK) @.***>, wrote:

Got a lot further this time - stopped at Optimising Charge Plan with an error error.log main.log pv_opt.log — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

alz41 commented 3 months ago

sunsynk.py - lines;- 7,34,35,36,37,38 require changing from {inverter sn} to {inverter_sn}

fboundy commented 3 months ago

sunsynk.py - lines;- 7,34,35,36,37,38 require changing from {inverter sn} to {inverter_sn}

Fixed this and added some checks to the SOC in 4.0.0-sunsynk-alpha-9

ElectricMolehill commented 3 months ago

Error during initialize() for pv_opt:

error.log main.log pv_opt.log

fboundy commented 3 months ago

fixed in 4.0.0-sunsynk-alpha-10

ElectricMolehill commented 3 months ago

I think it's published as alpha-19 It completes a plan!

It probably doesn't help that I lost a week's history when my SSD failed, and also the Solarsynk add-on is still suffering intermittent (but frequent) connectivity problems. Several users of Solarsynk have reported the same symptoms so probably cause is with the add-on or the Sunsynk cloud. This not only causes gaps in the history but any inverter updates are missed. This is fatal at the moment because it is hard to check whether a command has been successful. There's an open issue for this.

One problem I can see with the inverter class for pv_opt is that we are using the Battery Shutdown Capacity (set by the installer to 15 on mine) to define the minimum DOD. Ideally it would be the 'Low Batt' setting (set by my installer to 20) to avoid the battery actually shutting down. Unfortunately this is not mapped to a sensor in Solarsynk. Can I set a hard value in config.yaml?

fboundy commented 3 months ago

Yes hard value will work On 29 Mar 2024 at 16:48 +0000, Mark W (UK) @.***>, wrote:

I think it's published as alpha-19 It completes a plan! It probably doesn't help that I lost a week's history when my SSD failed, and also the Solarsynk add-on is still suffering intermittent (but frequent) connectivity problems. Several users of Solarsynk have reported the same symptoms so probably cause is with the add-on or the Sunsynk cloud. This not only causes gaps in the history but any inverter updates are missed. This is fatal at the moment because it is hard to check whether a command has been successful. There's an open issue for this. One problem I can see with the inverter class for pv_opt is that we are using the Battery Shutdown Capacity (set by the installer to 15 on mine) to define the minimum DOD. Ideally it would be the 'Low Batt' setting (set by my installer to 20) to avoid the battery actually shutting down. Unfortunately this is not mapped to a sensor in Solarsynk. Can I set a hard value in config.yaml? — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

ElectricMolehill commented 3 months ago

Just discovered another eccentricity of the Sunsynk cloud api - in order to enable Grid charging in a timeslot you also have to specify Gen charge ({"time2on": true, "genTime2on": false} instead of {"time2on": true}. If you only specify one, the api responds 'Success' but doesn't do anything. I'll update my document but trying to avoid too many versions in a day! By the way, thanks for all the time you've put into this so far. It must be more or less impossible to test without a Sunsynk inverter. I was delighted when my dashboard graphs sprang into life!

fboundy commented 3 months ago

One problem I can see with the inverter class for pv_opt is that we are using the Battery Shutdown Capacity (set by the installer to 15 on mine) to define the minimum DOD. Ideally it would be the 'Low Batt' setting (set by my installer to 20) to avoid the battery actually shutting down. Unfortunately this is not mapped to a sensor in Solarsynk. Can I set a hard value in config.yaml?

You can either map it to a fixed number or an input_number helper entity that you set up yourself.

fboundy commented 3 months ago

When you've got a minute can you upload a copy of the logs just to make sure there are no funnies.

It is tricky without the same inverter. What's even more confusing is that I'm trying to get a Solax inverter going at the same time. Fortunately the way I've set it up with separate plugins by brand makes it easier to manage.

ElectricMolehill commented 3 months ago

error.log main.log pv_opt.log pv_opt.log.1.txt sunsynk inverter class for pv_opt v4.odt

fboundy commented 3 months ago

There's clearly an issue where data is periodically unavailable. You can see this if you search the log for soc_now. At 16:20 it is 92.0 but at 16:30 it is blank. I guess this is down to the issues with the Solarsynk add-on that you've highlighted. I'll add some code to get it to re-try if it fails to get a number.

fboundy commented 3 months ago

Try 4.0.0-sunsynk-alpha-11

fboundy commented 3 months ago

Just had to patch to 4.0.0-sunsynk-alpha-12 to fix a bug associated with the clock change

ElectricMolehill commented 3 months ago

Here are the logs from alpha 12 The data coming from Solarsynk is pretty ropey at the moment I'm sure it wasn't like this to start with so perhaps fixable. Difficult to make much progress until Solarsynk is fixed though: image error.log main.log pv_opt.log

fboundy commented 3 months ago

That's pretty poor. For history it's OK as PV_Opt interpolates any gaps but the problem comes when reading current states. Fortunately the optimiser only really needs the current SOC. In alpha-13 I'm setting it to use the last value from the history if it can't get the current state from HA.

Controlling the inverter needs reliable access to the current states and also the ability to write reliably. This, combined with the 5 minute interval you mentioned before could make things tricky. One option would be to control the inverter directly through the sunsynk API rather than solarsynk. What do you think?

fboundy commented 3 months ago

Hold off on alpha-13 it has a bug

alz41 commented 3 months ago

Mark

I have been looking at this https://smarthomeintegrations.co.za/product/smartdeyedonglev4-intl-shipment/

It gives direct access to the inverter for read/write

ElectricMolehill commented 3 months ago

I agree Solarsynk is not looking too promising at the moment. I imagine the connectivity problem will get fixed but the 5 min delay and lack of response to commands are serious weaknesses which can't easily be fixed because the whole add-on runs as a 5 minute batch process. I'm a bit reluctant to connect directly to modbus though. The only easily accessible port on the inverter is already occupied by an e-Linter data logger which is used by Sunsynk and my installer for support as well as feeding the Sunsynk app. I'm not sure it's a good idea to have 2 parallel sources of commands connected at the same time. Also I think using the Sunsynk API might be somewhat safer (though I can believe it would be possible to ruin an inverter by sending a wrong API call), @alz41 I'm wondering whether the MorneSaunders360 integration would be a better bet. Sounds like you might have tried it so what do you think?