Overview Zendure Schedule Management
Background
The Zendure App “net-zero” option did not work properly because the P1 data lags by up to 20 seconds. A datagram is sent every second, but the values are delayed too much. As far as I have been able to determine, this is caused by the smart meter, the Landis+Gyr meter.
In addition, I want to be able to combine the different modes from the Zendure app myself. Ultimately, I want more control over charging and discharging the battery.
Schedule
The base of the system is built around a schedule. The schedule is a JSON file with keys that define a date/time and a value that defines a charge/discharge action.
There is a system, the schedule manager, that is used to manually manage the system by changing the entries in the JSON. This is the main GUI. At the moment there is both a mobile and a desktop version.
The actual battery manager is the system that reads the schedule and uses it to control the battery.
Because we use a standard JSON schema, we can manage and/or modify the schedule using different tools. We can also create smart systems that automatically create or alter the schedule.
Battery Manager
For this I use an old Raspberry Pi 2. What you use does not matter, as long as it is on the same network as the battery and the P1 meter. The Python script reads a charge/discharge schedule and acts according to this schedule. The schedule defines when the battery should charge or discharge and at how many watts. In addition, I added two special modes: NetZero and NetZero+.
NetZero is net-zero and attempts to compensate for household consumption by discharging the battery.
NetZero+ is net-zero, but only for charging. All electricity that would otherwise be fed back into the grid is stored.
Within the local LAN there is a simple computer such as a Raspberry Pi. This system reads the schedule and controls the Zendure battery.
The automation script is written in Python and can run on any system that supports Python.
API Calls used by the Automation System
The automation system makes 6 different types of API calls:
- Control the Zendure battery via LAN (write)
Set the charge/discharge level or put the battery into standby mode.
This is done via LAN access to the local API port of the battery. - Read Zendure battery status via LAN
Checks the state of charge of the battery. This is mainly used to keep the charge within the configured limits. These limits are defined in the application configuration. - Read P1 meter data via LAN
This is required to determine household power usage in order to run NetZero or NetZero+. - Store data
Store P1 and Zendure data (read by steps 2 and 3) via an API on the main web server on the Internet. - Fetch charge schedule
Every 5 minutes the schedule is loaded from the Internet. - Post automation status updates
Posts status information, including the last charge/discharge command and a timestamp, to indicate that the process is still running.
The Automation System is started via a Bash script. This script checks whether the system is already running; if not, it starts it. This process is triggered via CRONTAB every hour. If the system crashes, it will be restarted at the top of the next hour.
ToDo: IP addresses are currently statically defined in the configuration. They should be discovered automatically on the LAN.
The Automation System uses P1 data. This can come from any system, as long as the actual power usage can be read. The default configuration uses the HomeWizard P1 meter.
Smooth charging/discharging
Because of the delay in the P1 meter, the control system uses a smoothing algorithm. It only polls the actual household usage once every 20 seconds and limits sudden changes. Both the maximum charge/discharge rate and the maximum change rate are configurable. This makes the battery less responsive. The drawback is that consumption is not perfectly zero. In practice, this results in a deviation of approximately ±50 watt-hours in the worst case, and on average closer to 25 watt-hours.
Schedule Manager
The schedule is stored in JSON format and can be accessed via an API. It can be hosted on any web server (PHP, CSS, JS) and is modified and/or retrieved via API calls. This ensures that the schedule management component can be hosted on any server.
The schedule manager includes a dynamic price graph for electricity prices for today and tomorrow, when available. These prices are retrieved via a public API and cached in JSON format.
Schedule (JSON)
Example schedule:
{
"********0000": 0,
"********1200": "netzero+",
"********1500": 0,
"202601241700": "netzero",
"202601241900": -100,
"202601242100": 0
}
The JSON key represents a date and time and may contain wildcards (*).
The value is either a number (negative, zero, or positive), netzero, or netzero+.
A non-wildcard entry takes precedence over a wildcard entry.
In the example above, every day at 12:00 the system starts storing solar energy that would otherwise be exported to the grid, and stops at 15:00. On January 24th at 17:00, the system starts compensating household usage to achieve net-zero. At 19:00 it starts discharging at 100 watts, and at 21:00 all charging and discharging stops.