Inspiration
Solar power is abundant during the middle of the day, but household electricity demand does not always happen when solar energy is available. Flexible activities such as charging a vehicle, running a dishwasher, or doing laundry can often be moved to a better time without preventing people from completing them.
We built Solar Saver to explore a simple question: Can we schedule flexible household electricity requests around expected solar production while still respecting grid capacity, household preferences, workload priority, and fairness?
What it does
Solar Saver simulates one day in a Charlottesville district with:
- 24 one-hour time slots
- 100 synthetic households
- One flexible electricity request per household
- A solar supply forecast
- Background electricity demand
- A total-demand capacity limit
The application compares three scheduling policies:
- Uncoordinated: Runs each household request close to its preferred time.
- Solar-only: Moves requests toward hours with available solar energy.
- Balanced: Considers solar availability, grid capacity, household preferences, priority, and fairness together.
The results show the hourly solar supply and total demand, completed household requests, grid energy use, renewable matching, preference shifts, and capacity violations.
Renewable matching is calculated as:
[ \text{Renewable Matching} = \frac{\text{Solar Energy Used}}{\text{Total Energy Served}} \times 100\% ]
Solar Saver focuses on shifting when electricity is used. It does not claim to reduce total energy consumption.
How we built it
We designed Solar Saver as a backend-first Python application with separate components for forecasting, demand simulation, scheduling, metrics, and the user interface.
The forecasting system can load a trained weather-aware gradient-boosting model. It uses weather and time-based features to produce a 24-hour solar profile. When the trained artifact or weather service is unavailable, the application switches to a deterministic seasonal baseline and clearly tells the user that fallback data is being shown.
The demand generator creates deterministic synthetic household scenarios from a seed. Each household receives one flexible request with its own power requirement, duration, preferred start time, allowed window, and priority.
The scheduler evaluates all three policies against the same scenario. Explicit rules protect critical requests and enforce scheduling windows, requested durations, energy conservation, and capacity limits.
We built the interface with HTML, CSS, and JavaScript. A Python integration layer runs the comparison and prepares the results for both the local application and a static GitHub Pages deployment. The project includes automated unit and integration tests covering forecasting, demand generation, scheduling, metrics, the UI, and static export.
Challenges we faced
One major challenge was integrating independently developed subsystems without breaking their shared contracts. Forecasting, demand generation, scheduling, and the UI all needed to exchange the same domain objects while different team members worked on them.
Another challenge was applying the trained forecasting pipeline in the actual application. The model existed, but the original demo still constructed the seasonal baseline directly. We introduced runtime model selection so the application can use the trained model while retaining a reliable fallback.
Deployment created a related challenge. Trained model artifacts are intentionally excluded from the Git repository because generated artifacts should not become undocumented shared dependencies. The local application can use the trained model, while the current GitHub Pages build uses the seasonal fallback and labels it clearly.
We also had to describe the simulated data carefully. The household demand is synthetic and uncalibrated, so we made sure the interface does not present it as observed Charlottesville utility data.
What we learned
We learned that a successful machine-learning project requires more than training a model. The model must be connected to the application, validated through a stable interface, monitored for external-service failures, and accompanied by understandable fallback behavior.
We also learned how important deterministic simulation is for comparing algorithms. Using the same seed and scenario allows us to attribute differences in the results to the scheduling policy rather than random changes in demand.
Finally, we learned that optimization metrics need context. A policy can reduce grid use by leaving requests unfinished, so completion, capacity, priority, and preference shifts must be shown alongside renewable matching.
Accomplishments
- Integrated trained solar forecasting into the application
- Added reliable and visible fallback behavior
- Built deterministic demand for 100 synthetic households
- Compared three scheduling strategies using the same scenario
- Preserved capacity, scheduling-window, duration, and energy invariants
- Created a responsive results dashboard
- Deployed a working demonstration through GitHub Pages
- Built a suite of 90 automated tests
What’s next
Our next step is to provide the trained model artifact securely during deployment so the public demo can display trained predictions. We also want to calibrate the synthetic demand assumptions against documented data sources, improve weather-data caching and resilience, evaluate the scheduler under more constrained scenarios, and study more advanced optimization methods.
Built With
- and
- css
- github
- github-actions
- html
- javascript
- nasa-power-api
- numpy
- open-meteo-api
- pandas
- python
- scikit-learn
Log in or sign up for Devpost to join the conversation.