Intelligent solar-first battery automation for Franklin WH batteries
Fully automated charging system that optimizes for Time-of-Use (TOU) electricity rates, dynamic hourly pricing, and solar self-consumption. Makes smart decisions every 30 minutes with comprehensive monitoring.
- API-Native Mode Management - Reads and sets battery modes directly through the Franklin WH API
- Schedule-Aware Timing - Critical checks pinned to peak boundaries so mode switches are never late
- Per-Battery Monitoring - Individual SOC and power tracking for multi-battery systems
- Peak State Tracking - Prevents mode changes during expensive peak periods
- Solar-First Intelligence - Waits for solar production before grid charging
- Dynamic Pricing Support - Optional ComEd hourly pricing with negative price credit capture
- Configurable Everything - All settings via
.envfile, no code edits needed - Web Dashboard - Real-time monitoring with energy flow visualization and system info
- Weekly Reports - Performance charts showing 7-day automation effectiveness
- Robust API Handling - 5-attempt retry logic for Franklin Cloud API
- Docker Deployment - Single command startup with built-in scheduler and dashboard
- Decision checks now run at fixed :00 and :30 each hour for predictable timing
- 30-minute minimum interval to reduce Franklin Cloud API load — this is a temporary conservative default until API rate limit guidance is formalized
- Pre-peak check moved to 10 minutes before peak start (configurable via
PEAK_TRANSITION_BUFFER_MINUTES) - Eliminates timing drift from container start time
- Solar charging now properly overrides grid-charge deadlines when solar-to-battery rate can beat the clock
- Prevents unnecessary grid charging during strong solar production in tight pre-peak windows
- Franklin API reports stale
gridChBat/soChBatvalues during battery discharge — now zeroed out automatically - Ensures accurate logs and correct solar estimation during peak/discharge periods
- PVOutput collector now reads credentials from
.envconfiguration instead of hardcoded values - Supports multiple systems via
PVOUTPUT_SYSTEM_IDSsetting
- New REST endpoints for emergency mode control:
/api/overrideand/api/override/cancel - Dashboard buttons for Self Consumption and Emergency Backup modes
- Overrides auto-expire after configurable duration (default 2 hours)
git clone https://github.com/mtnears/FranklinWH-Automation.git
cd FranklinWH-Automation
cp .env.example .env
nano .env # Set your credentials and preferencesRequired settings in .env:
FRANKLIN_USERNAME=your_email@example.com
FRANKLIN_PASSWORD=your_password
FRANKLIN_GATEWAY_ID=your_gateway_id
BATTERY_CAPACITY_KWH=30
CHARGE_RATE_PER_HOUR=32mkdir -p logs data web
docker compose build
docker compose up -ddocker logs franklin-automation 2>&1 | head -25You should see the v3.4.0 banner with your configured features and scheduled tasks.
Open http://YOUR-SERVER-IP:8100 in your browser.
See DOCKER_INSTALLATION.md for complete setup details.
Every 30 minutes (clock-aligned at :00 and :30), plus pinned checks at peak boundaries:
┌─ Get battery stats via Franklin API (with retry logic)
├─ Detect current mode from API (name field)
├─ Check enabled features
├─ Layer 0: Price Override (if DYNAMIC_PRICING + SOLAR_OVERRIDE configured)
│ └─ Grid credit/negative pricing overrides everything
├─ Layer 1: Peak Protection (if TOU_ENABLED)
│ └─ NO ACTION during peak period
├─ Layer 2: Solar Assessment (if SOLAR_ENABLED)
│ └─ Use solar when available
├─ Layer 3: Dynamic Pricing (if DYNAMIC_PRICING_ENABLED)
│ └─ Charge when price is cheap
├─ Layer 4: Time-Based Logic
│ └─ Ensure ready for peak
└─ Execute mode switch via API if needed (with verification + cooldown)
The system guarantees battery readiness for peak hours:
- Calculates time needed to reach target SOC based on your measured charge rate
- Waits for solar as long as there's enough time buffer
- Switches to grid charging only when necessary
- Never changes modes during peak period
- Pre-peak check ensures mode is set before peak starts
| Method | Best For | Guide |
|---|---|---|
| Docker (Recommended) | All users, easiest setup | DOCKER_INSTALLATION.md |
| Native | Advanced users, custom setups | INSTALLATION.md |
All settings live in your .env file. See .env.example for all options.
| Feature | Default | Description |
|---|---|---|
SOLAR_ENABLED |
true |
Solar-first charging logic |
TOU_ENABLED |
true |
Time-of-Use peak protection |
DYNAMIC_PRICING_ENABLED |
false |
Hourly pricing (ComEd) |
WEATHER_ENABLED |
false |
Weather data collection |
PVOUTPUT_ENABLED |
false |
PVOutput solar tracking |
| Setting | Default | Description |
|---|---|---|
CHECK_INTERVAL_MINUTES |
30 |
Decision frequency (minimum 30) |
PEAK_TRANSITION_BUFFER_MINUTES |
10 |
Minutes before peak to check |
HOME_MODE |
tou |
Normal mode: tou or self_consumption |
| Setting | Default | Description |
|---|---|---|
PEAK_START_HOUR |
17 |
Peak period start (5 PM) |
PEAK_END_HOUR |
20 |
Peak period end (8 PM) |
PEAK_DAYS |
weekdays |
Which days have peak pricing |
See CONFIGURATION_REFERENCE.md for complete details.
| Script | Purpose |
|---|---|
smart_decision.py |
Main decision engine with API-native mode management |
config.py |
Configuration management from .env |
scheduler.py |
Schedule-aware task runner with peak-pinned checks |
generate_dashboard_data.py |
Real-time dashboard data |
generate_weekly_charts.py |
Performance visualization |
calculate_daily_savings.py |
Daily savings tracking |
Real-time monitoring at http://YOUR-SERVER-IP:8100:
Live Dashboard — Battery SOC, energy flow, charging status, savings tracker, peak countdown
Weekly Reports — 7-day SOC timeline, daily summaries, power flow charts
System Logs — Intelligence log, scheduler log, monitoring data with auto-refresh
See WEB_DASHBOARD.md for details.
- Battery: Franklin WH aPower2 (2× FHP, 30 kWh total)
- Solar: 28.26 kW total capacity (dual-meter, house + barn)
- Utility: PG&E E-TOU-D with CARE discount
- Location: Georgetown, CA
- Peak Protection: 100% success rate
- API Reliability: 99.5% uptime
- Target SOC Achievement: 91-94% before peak
- Average Daily Savings: ~$3.40/day
- Docker Installation — Recommended setup path
- Native Installation — For advanced users
- Configuration Reference — All settings explained
- Web Dashboard — Dashboard setup and features
- Troubleshooting — Common issues and solutions
- Changelog — Version history
Contributions welcome!
- Report bugs with log excerpts
- Share configurations for different utilities
- Submit PRs for new pricing providers
- Open discussions for feature ideas
MIT License — See LICENSE
Built using the franklinwh Python library by richö butts.
Built with ☀️ for the Franklin WH community