WARNING: This script is provided as is, without any guarantees it will work for you. Use at your own risk. |
---|
This script automates charging a Rivian vehicle using excess solar energy produced by the Enphase PV system. It dynamically adjusts the vehicle's charging speed (in Amps) to align with the available surplus solar production. Additionally, it can force charge to a certain level at night in case solar power alone is not enough for your daily needs.
Why not just use the Enphase IQ EV Charger and its native excess solar charging feature?
I tried it, but was not impressed by how well it adjusts to solar production, mainly because its algorithm is very conservative, and it can only change the charging speed at 25% increments, while the charger inside the Rivian vehicle can make more precise adjustments between 8A and 48A with 2A steps.
- Rivian vehicle (tested on R1S)
- Enphase solar system (solar gateway)
- Raspberry Pi or similar always-on computer/server to run the automation script in Docker
- (Optional) Hubitat home automation hub to monitor and switch charging automation modes from the mobile app
Every 10 minutes the script reads the solar production from Enphase solar gateway using the local API. It checks how much solar is being exported to the grid, and calculates how many more Amps the EV charger should draw to consume all the excess solar. Formula: = / 240 It then uses Rivian's Charging Schedule feature to set the desired amperage for charging (or disable changing) using Rivian web API (GraphQL).
At night, the script can either charge to a certain level (configurable) or not charge at all if you want to use solar energy only.
The algorithm intentionally does not use the home battery to charge the EV during the day, and it will prioritize charging the home battery if it's below 100%. This is because most home batteries are relatively small (compared to EV batteries), so there would be little benefit, but it would complicate the algorithm quite a bit.
The automation has three modes:
- OFF - Automation off
- DEFAULT - Use excess solar during the day and charge at full speed at night (to a certain limit)
- SOLAR_ONLY - only charge during the day using excess solar
- Check if the charger is plugged in. If not — disable charging and exit.
- If in "default mode" (charge at night): Check if it's night time (midnight <= time <= 7am) AND the EV battery state of charge is below the set limit (default 50%) — if yes, set to maximum Amperage and exit.
- Read production data from Enphase: Read net-consumption (import/export) 5 times, 10 seconds between readings. Take the median as Grid Consumption.
- Calculate the delta Amperage change: decrease by / 240 rounded down to 2. Negative consumption — increase Amperage; Positive — decrease it.
- If -2 <= Amperage Change <= 2 — ignore small change to avoid flipping.
- Current Amperage = Amerage from the schedule if Charging (check current session); if not charging == 0
- New Amperage = Current Amperage + Amperage Change. If New Amperage > 48 => New Amperage = 48; If New Amperage < 8 => New Amperage = 0.
- If New Amperage != Current Amperage: update the charging schedule with New Amperage.
- Wait 10 minutes before the next update.
Copy credentials-example.json
as credentials.json
and add your Rivian email/password, Enphase serial number, host IP
and authentication token.
See Enphase-token.py
for how to get authentication token using your Enphase login and password.
Your credentials.json
should look similar to this:
{
"rivian-user": "[email protected]",
"rivian-pass": "mysecretpass",
"enphase-token": "asdkjhsdkjhakdjh.aksdsakd.skdlksajdlksajdlksajd",
"enphase-gateway-sn": "202403011234",
"enphase-gateway-host": "https://192.168.1.123"
}
If using Hubitat to control your automation, copy hubitat-config-example.json
to hubitat-config.json
and update with
your Hubitat configuration, otherwise skip this step (and comment out the corresponding code in
ChargingAutomation.py
).
See Hubitat Setup for details.
cd charging_automation
pip install --no-cache-dir -r requirements.txt
python main.py
If the algorithm iteration runs successfully, proceed to the next step to build and run it in docker.
docker build -t charging_automation .
docker compose up -d
Disable any smart features of your EVSE, so it's always feeding power to the car when plugged in.
If you have a Hubitat home automation hub, then you can use it to control your charging automation modes (see Automation Modes).
Here is how my Hubitat dashboard looks like:
Create 3 virtual devices:
- Virtual Switch to enable/disable automation
- Virtual Dimmer to enable and configure nigh-time charging limit
- Virtual Omni Sensor to publish the info from the script to display on the dashboard
See Maker API docs
Set the following values:
- host: Local IP address / URL to your Hubitat hub
- api-id: 3-digit ID of you Maker API instance (it's part of every Maker API URL in Hubitat)
- token: access token generated by Maker API
- automation-on-switch-id: ID of a virtual switch for enabling/disabling automation
- night-charge-switch-id: ID of a virtual dimmer for enabling night charging and setting charging limit at night
- info-device-id: ID of a virtual omni sensor for publishing information to the dashboard
4. Complete the remaining steps from Setting Up section
See example dashboard above.
If you want to completely turn OFF and revert any changes made by this script, follow the steps below:
- Stop the docker container using
docker stop
command - Go to your Rivian App and disable or modify the Charging Schedule set by this automation
- Reconfigure your EVSE to the desired settings (i.e. disable "always-on")
Thank you Matthew1471 for building and publishing Enphase-API
Thank you kaedenbrinkman for publishing Rivian API Documentation