Includes a Python package soliscontrol which has modules for controlling a Solis inverter using the Solis Cloud API. This can be used to view key inverter parameters and to set daily charge times (within a cheap rate period) or discharge times (within a peak rate period). It will also check that times are synchronised with the inverter and that charge currents do not exceed the configured maxima.
The project also includes solis_flux_times a Pyscript Home Assistant app for use with energy suppliers that offer cheap rate charging periods and peak rate discharging periods such as the Octopus Flux tariff (for details see below).
This project is based on the Solis API docs for monitoring and control (and on the solis_control project which has the practical details for constructing requests to the Solis API).
You should access the Solis Cloud API by following these
instructions.
Based on the values returned you will need to create a secrets.yaml
- replace xxxx in the following example:
key_id: "xxxx"
key_secret: "xxxx"
user_name: "xxxx"
password: "xxxx"
station_id: "xxxx"
On your inverter you will also need to enable Self Use mode and set Time of Use: Optimal Income to Run - see https://www.youtube.com/watch?v=h1A80cSOrhA
Put your secrets.yaml
in the soliscontrol folder then edit main.yaml
to suit - an example as follows:
battery_capacity: 7.1 # in kWh - nominal stored energy of battery at 100% SOC (eg 2 * Pylontech US3000C with Nominal Capacity of 3.55 kWh each)
battery_max_current: 74 # in amps (eg 2 * Pylontech US3000C with spec Recommend Charge Current of 37A each)
# Also see https://www.youtube.com/watch?v=h1A80cSOrhA to view battery Dis/Charging Current Limits
inverter_max_current: 62.5 # in amps - see inverter datasheet specs for 'Max. charge / discharge current' (eg 62.5A or 100A)
charge_period: # First period when energy can be imported from the grid at low rates
start: "02:05"
end: "04:55"
current: 50 # charge current setting in amps
sync: 'random' # if 'start', charging is tied to start of period or if 'end' it is tied to the end (otherwise it starts randomly)
discharge_period: # First period when energy can be exported to the grid at high rates
start: "16:05" # set both to "00:00" if no discharging
end: "18:55" # set both to "00:00" if no discharging
current: 50 # discharge current setting in amps
sync: 'start' # if 'start', discharging is tied to start of period or if 'end' it is tied to the end (otherwise it starts randomly)
#api_url: = 'https://www.soliscloud.com:13333' # default
Note there can be up to 3 charge_periods and 3 discharge periods with different start and end times. As well as charge_period and discharge_period you could also define charge_period2, charge_period3, discharge_period2 and discharge_period3 in the example above.
Use the solis_run.py
module. You should save your secrets.yaml
in the same folder.
To get help:
python solis_run.py -h
To get inverter status information:
python solis_run.py
To set inverter charge and discharge times for the periods above to one hour per day:
python solis_run.py -c1 60 -d1 60
To turn inverter charge and discharge times off:
python solis_run.py -c1 0 -d1 0
If _charge_period3 was configured, you could clear all existing settings and then set timeslot 3 to charge for one hour like this:
python solis_run.py -r -c3 60
The pyscript app sets inverter charge (and discharge) times daily just before the start of the
defined periods (it runs a defined number of
minutes (cron_before) these periods).
Each charge or discharge episode is restricted to within the appropriate period
but its duration takes into account the solar forecast and the
current battery charge level. You can use the sync setting of the appropriate period to choose whether
the charge/discharge episode is tied to the beginning or end of the period or takes place at a random point within it.
Within each defined period you should set the following value depending on your household usage:
- kwh_after
This is the target energy 'reserve' you want to have in place after this time period. The 'reserve' consists of the predicted solar yield for the rest of the day and the battery energy stored after charging (or remaining after discharging).
Set this to zero if you don't want any charging/discharging to take place or to a negative number if you don't want to take any action (for example if you have an existing charging schedule that you want to preserve)
You should also monitor the accuracy of solar forecast values for your home (they can be adjusted using the forecast_uplift multiplication factor in the configuration below).
First install a solar forecast integration either Forecast.Solar or Solcast (which I have found to be more accurate).
Next install Pyscript.
Now copy solis_flux_times.py
to the pyscript apps folder
and copy solis_common.py
and solis_control_req_mod.py
to the pyscript modules folder (and if necessary solis_s3_logger.py
see below).
Finally create config.yaml
and secrets.yaml
(see below) in the main pyscript folder.
Setup of pyscript is via the HA configuration.yaml
- an example as follows:
pyscript: !include pyscript/config.yaml
Configuration of solis_flux_times is via the pyscript config.yaml
- an example as follows:
allow_all_imports: true
hass_is_global: false
apps:
solis_flux_times:
forecast_remaining: 'solcast_pv_forecast_forecast_remaining_today' # entity id of Solcast remaining energy today (kWh) - in 'sensor' domain
# forecast_remaining: 'energy_production_today_remaining' # alternative entity id of Forecast.Solar remaining energy today (kWh) - in 'sensor' domain
forecast_uplift: 1.0 # multiplication factor for forecast values if they prove to be pessimistic or optimistic
cron_before: 20 # minutes before start of periods below to assess forecast and set charging/discharging times (can be overridden within each period)
solis_control:
key_secret: !secret solis_key_secret
key_id: !secret solis_key_id
user_name: !secret solis_user_name
password: !secret solis_password
station_id: !secret solis_station_id
#api_url: = 'https://www.soliscloud.com:13333' # default
battery_capacity: 7.1 # in kWh - nominal stored energy of battery at 100% SOC (eg 2 * Pylontech US3000C with Nominal Capacity of 3.55 kWh each)
battery_max_current: 74 # in amps (eg 2 * Pylontech US3000C with Recommend Charge Current of 37A each)
# Also see https://www.youtube.com/watch?v=h1A80cSOrhA to view battery Dis/Charging Current Limits
inverter_max_current: 62.5 # in amps - see inverter datasheet specs for 'Max. charge / discharge current' (eg 62.5A or 100A)
charge_period: # First period when energy can be imported from the grid at low rates
start: "02:05"
end: "04:55"
current: 50 # charge current setting in amps
sync: 'random' # if 'start', charging is tied to start of period or if 'end' it is tied to the end (otherwise it starts randomly)
kwh_after: 12.0 # ideal target kWh level for rest of the day (solar predicted + battery reserve) after this period
# zero means activity will be actively turned off each day (a negative number will disable any action)
# can also be the id of an entity which defines this value eg a helper = 'input_number.morning_reserve'
charge_period2: # 2nd period when energy can be imported from the grid eg top up to avoid importing during peak period
start: "14:30"
end: "15:30"
current: 50 # charge current setting in amps
sync: 'start' # if 'start', charging is tied to start of period or if 'end' it is tied to the end (otherwise it starts randomly)
kwh_after: 6.0 # target kWh level (solar predicted + battery stored) after 2nd charge period
discharge_period: # First period when energy can be exported to the grid at high rates
start: "16:05" # set both to "00:00" if no discharging
end: "18:55" # set both to "00:00" if no discharging
current: 50 # discharge current setting in amps
sync: 'random' # if 'start', discharging is tied to start of period or if 'end' it is tied to the end (otherwise it starts randomly)
kwh_after: 5.0 # ideal target kWh level for rest of the day (solar predicted + battery reserve) after this period
# zero means activity will be actively turned off each day (a negative number will disable any action)
# can also be the id of an entity which defines this value eg a helper = 'input_number.evening_reserve'
#Uncomment these lines if you have an S3 data logger that occasionally disconnects - checks access and if necessart restarts the logger
#s3_username: !secret solis_s3_username
#s3_password: !secret solis_s3_password
#s3_ip: !secret solis_s3_ip
Based on the settings above you will need to add the following lines to the pyscript secrets.yaml
replacing xxxx:
solis_key_id: "xxxx"
solis_key_secret: "xxxx"
solis_user_name: "xxxx"
solis_password: "xxxx"
solis_station_id: "xxxx"
#solis_s3_username: "xxxx" # see above
#solis_s3_password: "xxxx" # see above
#solis_s3_ip: "xxxx" # see above
Look in the logs for entries tagged solis_flux_times. In the example the charge times will be set cron_before ie 20 mins before the start of the cheap rate period at 01:45 and the discharge times will be set cron_before ie 20 mins before the start of the peak rate period at 15:45.
There is also a test_solis pyscript service which allows you to test different settings and view the results in the log (without taking any action).