If you have rooftop solar and some flavor of net energy metering (NEM), you may want to consume as much of your solar output as possible, as measured on an hourly basis. For example this is useful to minimize non-bypassable charges (NBCs) under California's NEM2 regime.
By predicting the total energy produced or consumed in the coming hour, this project can help you shift energy usage to maximize self-consumption and minimize NBCs.
What you'll need:
- Emporia VUE Utility Connect
- A compatible smart meter
- A suitable python web service environment
Before getting started with this project, configure your Emporia VUE Utility Connect to receive data from your smart meter.
Then deploy to a suitable python environment. The button below should make it easy to deploy to Render:
If that doesn't work, you can still deploy to Render manually, or you can run locally, or deploy to pretty much any python environment.
Once set up, you'll be able to view a simple web page showing how much energy your system has used or generated for the current hour, and how much it's likely to generate by the end of the current hour. You can also use a simple HTTP GET request to fetch these metrics in JSON format, suitable for home automation.
The prediction is based on per-second energy usage for the past ten minutes, as reported by your smart meter through the VUE Utility Connect. The prediction won't always be correct, but I hope you'll find it useful.
Besides your Emporia VUE Utility Connect and a compatible smart meter, you'll need a render account. You should be able to run this project under render's free tier.
Create a new web service on render.com using python and flask, as described here:
https://render.com/docs/deploy-flask
However in step one, instead of forking flask-hello-world fork this repository.
Note that requests will only show MOCK data until you configure
the new web service with your Emporia credentials and deploy again.
This means trusting render with your Emporia username and password.
Do this at your own risk, and take reasonable precautions.
Use a strong password, and one that's unique to your Emporia account.
To configure the web service with your Emporia account credentials,
visit the Environment section of your web service in the
render dashboard. Add these environment
variables:
- VUE_USERNAME
- VUE_PASSWORD
After setting these credentials, deploy the web service again. You should now see live data from your VUE Utility Connect.
For load management features (smart plug and Tesla charging control), you'll also need additional environment variables. See env.example and docs/LOADMANAGER.md for the full configuration reference.
You can also run this project locally, or adapt these instructions to pretty much any python environment.
Requirements:
First, clone this repository:
git clone https://github.com/mblakele/solara.git
Next, install dependencies:
uv sync
Next, copy env.example to .env and configure your credentials:
cp env.example .envEdit .env with your Emporia username/password and any optional load management
settings. See env.example for all available options.
Never check the .env file into source control. It is listed in .gitignore.
Finally, start a local server with:
uv run python app.py
This runs Flask's built-in development server (with background services — MQTT telemetry and the load manager — already started). The output looks like this:
* Serving Flask app 'app'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:8000
Press CTRL+C to quit
For development work you may prefer gunicorn with auto-reload, which matches production behavior (threaded worker, cooperative shutdown):
gunicorn --reload \
--reload-extra-file .env \
--reload-extra-file templates \
-c gunicorn.conf.py --worker-class=gthread --threads=4 \
wsgi:app
Its output looks like this:
[2026-08-24 04:56:00 +0000] [15341] [INFO] Starting gunicorn 26.0.0
[2026-08-24 04:56:00 +0000] [15341] [INFO] Listening at: http://127.0.0.1:8000 (15341)
[2026-08-24 04:56:00 +0000] [15341] [INFO] Using worker: gthread
[2026-08-24 04:56:00 +0000] [15342] [INFO] Booting worker with pid: 15342
Test the server by opening the Listening at: link from the output.
In the sample above, that's:
Here's a screenshot of a sample html view. This is meant to be readable on mobile devices, and the output should be fairly self-explanatory. Here's what you can read on each line:
- Device info and request timestamp, mapped to the device's timezone
- Minutes remaining in the current hour
- Energy produced or consumed in the last 60 seconds
- Result of multiplying minutes remaining by the most recent minute's energy
- Energy produced or consumed in the hour so far
- Estimated total energy for the hour, in bold
- Minimum and maximum estimate, based on up to 10 minutes of data
- How long the Emporia API took to respond
- Lag, or the age of the most recent data in the Emporia API response
Substitute the correct hostname in the URL below.
curl -H 'Accept: application/json' \
'https://fubar-12345.onrender.com'
Sample output:
{
"apiResponse": {
"getChartUsage/1,2,3": "PT0.677919S",
"total": "PT0.677919S"
},
"debug": false,
"devices": [
{
"gid": 654321,
"lag": "PT6.279410S",
"name": "fubar",
"minutePredicted": -8.23541694800059,
"minutesRemaining": 9.833333333333334,
"prediction": -27.6879148912382,
"predictionMin": -27.6879148912382,
"predictionMax": -22.758956398742814,
"timezone": "America/Los_Angeles"
}
],
"instant": "2022-03-08T20:50:16.279Z"
}
As you can see, the JSON data includes information that isn't available in the HTML view.
Solara can automatically control smart plugs and Tesla vehicle charging to absorb excess solar energy. The load management engine uses NBC predictions to decide when to turn flexible loads on or off, aiming to keep your quarter-hour net usage near a configurable target (default: -50 Wh).
Supported devices include HomeKit smart plugs, VOCOlinc smart plugs, and Tesla vehicle charging. See docs/LOADMANAGER.md for full configuration details, including Tesla Fleet API OAuth setup.
- Copy
env.exampleto.envand configure your devices - Start with
LOAD_MANAGE_DRY_RUN=Trueto test without executing actions - Review logs to verify decisions match expectations
- Set
LOAD_MANAGE_DRY_RUN=Falsewhen ready for real control
The code in this project can't see into the future. Instead it looks at the hour so far, and especially the past 60 seconds, to estimate how the rest of the current hour might go. Much of the time this works pretty well. However, the accuracy of these estimates will vary depending on several factors including, but not limited to:
- changes in solar output
- changes in energy use
- beginning of the hour
- data age (lag)
- data accuracy
As the sun rises and sets, and as the weather changes, so does the output of your panels. The code in this project does not try to account for that. This can affect accuracy, especially in circumstances such as partly cloudy weather or at times of day when the amount of sunlight reaching your panels is changing rapidly.
Changes in your energy use can also influence accuracy, because this code projects usage for the rest of the hour based on the most recent 60 seconds of Emporia data. For example if your electic water heater runs for five minutes, then turns off, the prediction will reflect that usage. However the prediction should improve over time, as the water heater's usage moves out of the running 60-second window.
At the beginning of the hour, this code has limited data for projections. For example there may be less than 60 seconds of data available. Accuracy should improve once the first minute or so of data is available.
Data age, or lag, can influence accuracy for the same reasons. As you'll observe, data from the Emporia API often lags by seconds, and sometimes by minutes. If your solar output or energy usage change quickly, and Emporia's available data is lagging, the prediction won't be as accurate.
To help with these variables, this code makes a primary prediction based on the last minute, plus predictions for various time intervals up to 10 minutes. The HTML view shows the minimum and maximum these predictions. In the JSON data, each time interval is broken out and labeled: 1MIN, 2MIN, 3MIN, etc.
Finally, at times the data coming from Emporia Energy's APIs may not be as accurate as we would all like. This could be due to faults at your smart meter, or its communication with the VUE Utility Connect, or its communication with Emporia Energy's backend servers, or in those servers. In any case, keep in mind that the code in this project can only make predictions using the available data.
The web service will cache your authentication tokens and Emporia VUE Utility Connect device info. This information should refresh as needed.
If the web service seems to be hanging on to stale authentication or device information, try restarting the web service.
Yes, please!
The web service can't find your Emporia account credentials, so it's showing static test data. Revisit the Setup section and configure the Emporia account credentials.
VUE_USERNAMEVUE_PASSWORD
An error occurred (NotAuthorizedException) when calling the
RespondToAuthChallenge operation: Incorrect username or password.
One or both of the Emporia account credentials are probably wrong.
VUE_USERNAMEVUE_PASSWORD
An error occurred (UserNotFoundException) when calling the
InitiateAuth operation: User does not exist.
Check the VUE_USERNAME for errors. Make sure it matches your
Emporia account username exactly.
Thanks to Emporia Energy and to PyEmVue.
