This app is designed to optimally manage the battery charging for your Solar/PV/Battery system, when used with the Octopus Smart tariffs. The idea is that it will analyse upcoming prices for Agile, Cosy, Go, etc, and then apply an opinionated strategy to manage your battery based on the cheapest periods.
If you don't already use Octopus, but like the sound of this app and want to sign up to an Octopus tariff, please use my referral link, and we'll both get £50!
PLEASE NOTE: This application is provided as-is, with no guarantees; I accept no liability for any issues that arise with your electricity bill, inverter, battery, or any other system, as a result of using this application. Your choice to run the app is entirely at your own risk.
Warning: This application should never be exposed to the internet via port-forwarding or other public access. Solis Agile Manager does not have any authentication, which means that a malicious hacker could easily control your Inverter.
If you want to be able to access the application remotely, please ensure you only do so via a VPN or a reverse proxy.
SolisManager runs as a server-based app, and is designed to run 24/7, in the background, with minimal interaction from the user. If it's working well, you shouldn't have to do anything once it's set up.
To run it, go to the latest release on GitHub,
and download the appropriate package for the operating systtem you're going to use (Mac/Linux/Windows/RPi).
Extract the zip into a folder and then run the main executable. Note that the config file and logs etc
will be written to a folder called Config
in the current working directory. If you'd rather they were
written somewhere else, pass your chosen folder as the first command-line parameter.
Once the server is running, navigate to the UI via your browser. It will be at http://localhost:5169
.
You will need to pull the webreaper/solisagilemanager
container, and map the internal port 5169
to the port
you want the web-UI exposed on from your host. You will also need to map a volume /appdata
to a writeable
local folder on your host, so that the config, and log files are written outside the container (otherwise
when you pull a new version or recreate the container, you'll have to set up from scratch again).
Here's a sample docker-compose
entry:
solismanager:
container_name: solismanager
image: webreaper/solisagilemanager:latest
ports:
- '5169:5169'
restart: unless-stopped
volumes:
- /volume1/dockerdata/solismanager:/appdata
Multiplatform Docker Images are available for:
These images should work for Linux, Mac, Windows and Raspberry Pi.
The first time you load the UI, you'll be prompted to input basic information, such as your Solis API key and secret, your inverter serial number, and the Octopus Product details of the current tariff you're on.
The app will connect to your Octopus account and find the current tariff that you're using.
Once the API key and account are configured, the application will query every 4 hours to check if your tariff has changed, and update accordingly. So if you change tariff (e.g., switch from Agile to Cosy) you should start seeing the new tariff prices flow into the app within 4 hours.
If you don't want to use your Octopus account to infer the current tariff, you can enter the product and tariff product code manually. Just leave the Octopus API key and Account number blank and enter the product and tariff codes yourself.
AGILE-24-10-01
).links
section to find your region-specific
product code. For example: https://api.octopus.energy/v1/products/AGILE-24-10-01/E-1R-AGILE-24-10-01-A
) into the Solis Manager settings.Note that in the most common cases, selecting AGILE-24-10-01
and E-1R-AGILE-24-10-01-A
, and just altering
the last A
to the correct Region Code will do exactly what you
need. Solis Manager doesn't do anything with the standing charge, so it doesn't matter if you're on an older
tariff.
You'll also need to set some other config settings that control the way the charging plan works:
Max Charge Rate in Amps - set to the level that your battery can charge/discharge at. You should refer to your inverter/installer to check what is the max safe charging rate for your system's battery.
Charge slots for full battery - which tells the app how many slots of charging will be needed to go from empty to full. This will depend on your battery size and charging rate. Eventually the app will calculate this based on historical charging data, but for now, it's a manual setting.
Battery Boost Threshold
- the percentage at which you'd like to boost charge if prices are a bit lower
than average
The Always charge below
rate. For example, if you set this to 10p/kWh, then any slot lower than that
price will always be set to charge, regardless of anything else. Can be useful to ensure you prioritise
export, for example.
This can be useful for some tariffs - e.g. if you are on Cosy, which has alternating periods of high and
low prices, set is value to just above the cheap price and it will guarantee that your battery always
charges in the pricing 'troughs'. I set it to 15p/kWh when I'm on Cosy.
The Charge if SOC below %
- this setting will maintain a particular minimum battery level. So for example,
if you set it to 35%, then any time the battery falls below 35% at the start of a slot, that slot will be
marked to Charge, regardless of price or PV availability.
Note - currently this is only checked once every 30 minutes (at the start of each slot). This will be made
more granular in future.
Battery %age for peak period
: set this is an approximation of how much battery you need to get you
through the peak period of 4pm-7pm. If you have a small battery and use a lot of power in the afternoon,
you might want this to be 100% - so it'll allow enough charging to get to 100% before the peak time starts.
For me, we usually only use about 5-6kWh between 3pm and 7pm; our battery is 14kWh, so I have it set to 60%. The idea of this setting is that you want enough power to get through the peak period, but it doesn't necessarily need to be fully-charged.
Simulate-only - if checked, the app will run and simulate what it would have done without actually making any changes to the behaviour.
Octopus Intelligent Go is an advanced tariff that manages your Electric Vehicle (EV) charging automatically. One advantage it provides is that if you need to charge your EV at any time of day to prepare for a journey, you can call for an 'IOG Dispatch' which will charge the vehicle at the cheap rate (7p/kWh or so) at any time of day.
So even if you're in the normal peak period of 4pm-7pm, you get a charge slot at a significantly reduced rates - and because of the way smart-meters work, this means that the electricity for the entire house is also provided at that cheap rate for the duration of the IOG Dispatch.
Solis Manager now detects these cheap slots and can be configured to always charge the house battery while they are in progress - giving you a cheap boost to your battery at the reduced IOG rate. During the IOG Dispatch period, Solis Manager checks the state every 5 minutes to ensure the cheap charge rate is still available, and will cancel the house charge if it ends (because, for example, the EV reaches 100% charge, or you unplug your EV from the charger).
First, check the 'Intelligent Go Charging' checkbox in the Settings screen, and save the settings.
Then if Octopus sends you a smart-charge slot you'll see something like this in the logs:
Found 2 IOG Smart-Charge slots (out of a total of 2 planned and 3 completed dispatches)"
Time: 16:34 - 17:26, Type: smart-charge, Delta: -7"
Time: 18:22 - 18:55, Type: smart-charge, Delta: -9"
In the above case, you'd see the slots in the Charging plan change to a car icon for:
and the inverter should charge the house battery for that period. Note that smart-charge slots don't seem to be reliably sent to the API, so it's possible you might find yourself charging your EV in a cheap slot during the day, but SolisManager doesn't get notified of them, so isn't able to take advantage of them and charge your home battery. Unfortunately, that seems to be a foible of some chargers/cars, and is beyond my control!
The application has a setting that will, every day at 2am, update the inverter time to match internet time. This can fix the natural time-drift of the inverter's clock, and ensure your charging happens at the right times.
If you'd rather not have this feature, you can disable it in the config.
A scheduled action allows you to specify a particular action that will always be applied for a particular
time of day (i.e., for a particular slot). You can add multiple scheduled actions, and they will take
precedence over all other rules except for the Charge if SOC less than %
option.
An example use case for this is as follows:
Discharge
at 20:30, 21:00 and 21:30 - to export any unusage battery
charge to the grid, earning 15p/kWhEach scheduled action can use an SOC threshold to govern when it's applied. For example, you can set an action
to charge while the SOC is below a specific percentage, or discharge while SOC is above a percentage - allowing you
to create a rule that says at 8pm each night, discharge my battery if it has more than 30% charge
. You can also
override the default/global settings for charge/discharge Amps, so scheduled actions can charge/discharge at a different
rate.
Note: For this app to work, you'll need to have raised a ticket with Solis to get access to control the inverter via the SolisCloud app. To do this:
API Request - Owner
. In the notes, ask for API access too.For people who like to tariff-hop to ensure they get the best price, the app now has a comparison tool that will show a chart of upcoming prices for your current tariff, versus other Octopus products.
Once you've filled these in, the server will start running.
As it runs, the last 30 days' worth of charging decisions will be logged to SolisManagerExecutionHistory.csv
so you can monitor the decisions it's taking to ensure they're as you require. There's also a History page that
allows you to convienently check what it did, and why it did it:
Yes! The latest version has been updated to work with all Octopus Smart Tariffs. For example, the screenshot
below shows the charging plan for Cosy - with the Always Charge Above
config setting set to 15p/kWh.
At first launch SolisManager will load the next set of Agile Tariff data, along with some information about your inverter. It will then estimate the best charging strategy based on a number of rules, as set out below. Note that this strategy is based on my needs for battery-management, but should apply to many other people too.
This application is based on a number of assumptions, the primary one of which is that the person running it is a high-consumption power user, probably with an Air Source Heat Pump or EV, and wants to optimise their battery charging to charge at the cheapest times. The goal of the app is to charge the battery at the cheapest times possible, without too much unnecessary battery cycling. If you are a lower-useage household, you may find that Rob Tweed's Agility app is better suited to your needs.
Charge
Do Nothing
- i.e., don't charge.Charge
.BelowAverage
. For those slots, if the battery is low, we'll take the opportunity to charge as
they're a bit cheaper-than-average, so set their action to Charge If Low Battery
.n
slots and even if they're
BelowAverage
, set them to Do Nothing
.Charge If Low Battery
, update them to 'charge' if the battery SOC is,
indeed, low. Only do this for enough slots to fully charge the battery.Lastly, find runs of slots that have negative prices. For any groups that are more than long enough to charge the battery fully, discharge the battery for all the slots that aren't needed to recharge the battery. For example, we might end up with a run of 3 negative prices, and later another group of 8 negative prices. If our battery takes 3 hours to fully charge, the first two negative slots of that group of 8 will be set to discharge the battery. See the chart below:
There are also manual overrides which can be set vie the tools screen. For example:
n
slots, regardless of cost, to completely
charge the batteryn
slots to completely discharge the batteryx
next to any charge/discharge slot, you can apply an override which will cancel
the charge action and return that slot to Do Nothing
.To test the app and ensure it functions correctly, simulation mode shows what would have happened, without actually writing changes to the inverter. This allows you to see how the charging plan changes with the strategy as different information comes in.
Simulation mode is interactive; the first time the app loads it initialises the simulation using the current inverter state, and the loaded Agile prices. As you advance through the simulation, it shows what will happen (and the logs will show the commands that would have been sent to the inverter).
Once you run out of slots at the end of the simulation, click reset to start again.
The application can use a Hobbyist Rooftop account from Solcast to estimate the likely PV yield from your system over the next day or so.
To configure this add settings for:
Currently the Solcast data is only used for display purposes, but will eventually be used to optimise the algorithm (e.g., by skipping overnight charging if the forecast is for a decent PV yield.
Solcast can often over-estimate the forecast for the PV yield, because it may under-estimate the cloud impact, or may not take into account panel shading, and string efficiency. Therefore, the config settings have a field for Solcast Damping Factor. So for example, if your Solcast forecast is generally 2x your actual PV yield, then set the damping factor to 50%. The damping factor is applied immediately to all of the Solcast figures in the UI, so you can adjust this up/down until it matches reality.
In future, the application will look at historic PV yields from the inverter, and compare this to the Solcast forecast, and then auto-adjust to match reality.
I spent quite a lot of time researching PredBat. It looks awesome, and I would love to run it. However, Solis support for Predbat is quite limited, which makes it unsuitable for my needs. Specifically, there is no current way to run PredBat with a Solis Inverter, solely using the Solis API. This means that there are only two alternatives:
There is another factor: Home Assistant can be an unwieldy platform to install and maintain. It's amazing in terms of what it can do, and the community is extremely spirited, but hassle of keeping an instance updated (there's no auto-updates for integrations and plugins) combined with the unfriendliness of configuration of many components, means that while I run HA, I'm not a fan of it. In particular, for less technical users the idea of just installing an EXE or docker image and running it without complex setup and configuration is very appealing.
Solcast API calls are rate-limited to 10 API calls per day - after which the call will fail and no data is returned. To avoid blowing through this limit the strategy is:
Solcast-latest.json
in the config folder.This avoids the API throttling in most cases. Also, Solcast recommend not doing it on the hour (because otherwise everyone hits their API on the hour....) so the app actually makes the request at the somewhat arbitrary times of 02:13, 06:13 and 12:13.
Currently this data is only used for display purposes. I haven't worked out how I'll use the data yet (there isn't enough PV to make a difference at the moment). Probably:
If you have other ideas or suggestions, let me know!
A couple of people have raised concerns about the number of writes a half-hourly process will make to the SolisCloud API, and consequently the Inverter EEPROM. Excessive writes could result in a reduced longevity of the EEPROM (which generally have a limit on the total number of writes they can manage).
To avoid this, the app applies Charging, Discharging and 'no charge' instructions in batches. So for example, if the charging plan is as follows:
Then the actual calls are conflated to the following:
This optimisation means that the absolute minimum number of control
API calls are made (from about 17,000 per
year down to around 2,000), and hence the minimum number of Inverter EEPROM writes are carried out.
Although the app was originally developed for Solis Inverters, there's no reason why it can't support Other inverter types. However, I won't be able to develop them because it's impossible to test - so would need others to collaborate and contribute implementations for other inverters.
If you'd like to consider contributing, the steps are generally something like this:
SolisManager.Inverters.Solis
one in the project, for your inverter, which has
a class that implements the IInverter
interface (with methods to set a charge, and retrieve SOC and other
state from the inverter).SolisManager.InverterFactory
class to return an instance of the IInverter
implementation, based
on the config type passed in.InverterConfigSolis
.
You'll also need to add the JsonDerivedType
attribute for the new type in InverterConfigBase
.SolisInverterConfig.razor
component.ConfigSettings.razor
InverterSettings()
method to return the new config componentThat should be most of what's required. I may create a couple of skeleton implementations for the more popular inverter types to get people started....
If you like this app, please check out some of my other applications, including a Photo Management system called Damselfly
Solis Agile Manager is free, open-source software. But if you find it useful, and fancy buying me a coffee or a slice of pizza, that would be appreciated! You can do this via my Damselfly BuyMeACoffee link.
For those who are interested, the application is built using Blazor WebAssembly, with an ASP.Net back-end. The app is written entirely in C# on a Mac, using .Net 9. The core functionality was written over the course of about a week.