| Developer: | Glenn's Plugins Like this plugin? Show your appreciation! |
| Category: | Energy Monitoring |
| Github: | Github Repo |
| Assistance: | Get help! |
| Plugin ID: | com.GlennNZ.indigoplugin.SolarSmart |
| Latest release: | v1.0.82 released on Nov. 6, 2025 |
| Requires: | Indigo v2022.1.0 or higher |
| (Check the Releases tab below for older releases that may have different requirements) | |
| Download latest release |
![]()
Harness your surplus solar energy automatically. SolarSmart monitors your photovoltaic (PV) production, site consumption, battery power, and/or net grid flow to calculate “headroom” (excess power)[...]
The following improvements and fixes have landed since the last README update. These notes reflect version 1.0.70 (commit f7fdad16 on main).
Notes: - Device UI wording may still refer to “Quota Window (rolling)”; functionally, windows are aligned to 06:00 as described above. - Existing images and their locations (Images/…) are unchanged.
SolarSmart is an Indigo Domotics plugin that:

Headroom is the amount of excess power you can safely use right now.
Depending on your metering, SolarSmart can compute headroom from: - A single, accurate net grid meter (preferred when available). - Separate inputs for PV output, site consumption, and battery charge/discharge.
Sign conventions (typical, but verify your meters): - Net grid: - Negative watts = exporting to the grid (good; spare power). - Positive watts = importing from the grid (no spare power). - Battery: - Negative watts = discharging (adds to available power). - Positive watts = charging (consumes power).
1) Grid-Only Mode (preferred if supported) - Uses your net grid meter as the single source of truth. - Example: - Grid = −2424 W → exporting 2424 W - Headroom = 2424 W
2) PV + Consumption + Battery Mode - Used when a net grid meter state isn’t available. - Example: - PV = 3800 W - Site Consumption = 3134 W - Battery = −9000 W (discharging) - Headroom = PV − Consumption + Battery = 3800 − 3134 + 9000 = 9666 W
3) No Spare Power example - Grid-Only Mode - Grid = +1800 W → importing from grid - Headroom = −1800 W (loads should stop)

1) Install the plugin - Double-click SolarSmart.indigoPlugin. - Enable it in Indigo.
2) Create the Main Device - Choose your operating mode. - Select the meter/source states for PV, consumption, battery and/or net grid. - Set the scheduler check frequency.
3) Create one or more Load Devices - Assign each load a tier (1 = highest priority). - Choose how the load should be controlled (device on/off or action groups). - Optionally set runtime quotas and allowed time windows.
4) Watch it run - As headroom rises, SolarSmart starts loads beginning with Tier 1. - As headroom falls, SolarSmart sheds loads starting from the highest tier.
Key options typically include: - Mode: - Grid-Only - PV + Consumption + Battery - Meters / States: - Net Grid state (single number), and/or - PV watts, Site Consumption watts, Battery watts - Scheduler: - Check frequency (e.g., every 30–120 seconds) - Logging: - Info (default), Debug, Very Verbose
Recommendations: - Use Grid-Only Mode if your metering supports it (most accurate). - Start with a moderate check frequency (e.g., 60s). - Use Debug logging briefly while tuning.
Each load can be configured with: - Tier (priority): - Lower number = starts earlier and is shed later. - Control method: - Direct device on/off, or - Action Groups to start/stop. - Optional limits and constraints: - Quota (max runtime) per day/period. - Allowed time window (hh:mm → hh:mm). - Allowed days of week. - Optional minimum headroom to start, and/or sustained headroom to continue (if exposed in your version). - Safety off behavior when headroom drops below zero.
Note: Field names may vary slightly by version.

Note: - Preferred runtime windows are aligned to local 06:00: - 12h: 06:00–18:00 and 18:00–06:00 - 24h/1d: 06:00–06:00 next day - 2–3d: advance at 06:00 every N days
Some devices (pool pumps, chlorinators, ventilation fans, etc.) must run a minimum amount of time each quota window (e.g. per day or rolling window) regardless of how much excess solar was actually Scheduled Catch‑Up guarantees a fallback runtime:
Update (v1.0.70): - Catch‑up Window Period can be set independently of the Quota Period. Minutes accrue in a separate, 06:00‑aligned catch‑up slot (RuntimeCatchupMins). - For 2–3 day catch‑up periods, forced catch‑up starts only occur during the final 24 hours of the current catch‑up slot (and still inside the daily catch‑up time window).
solarsmartLoad).All must be true:
- enableCatchup is checked.
- catchupRuntimeMins > 0.
- Remaining Fallback > 0.
- Device is currently OFF.
- Current time is inside the defined catch‑up window.
- For multi‑day catch‑up periods (2d/3d): we are in the final 24h of the current catch‑up slot.
- Concurrency limit not exceeded.
- Only one catch‑up start per tick (internal safety throttle).
Catch‑up started device stops when: - Remaining Fallback = 0 (target satisfied), or - Current time exits the catch‑up window, or - For multi‑day catch‑up: not in the final slot‑day (enforced), or - You manually turn it OFF, or - The relevant window rolls over: - If using an independent catch‑up period, the catch‑up window boundary. - Otherwise, at quota window rollover (legacy behavior). - Plugin / Indigo restarts (it re‑evaluates next tick).
catchupDailyTargetMins
Exactly the configured fallback (Catch‑up Runtime).
catchupRemainingTodayMins
Minutes still needed to satisfy fallback (never negative), computed against the catch‑up window.
catchupActive
True only while plugin‑forced catch‑up run is in progress.
catchupRunTodayMins
Minutes accumulated under catch‑up active time only.
catchupRunWindowAccumMins
Mirrors catchupRunTodayMins (placeholder).
catchupLastStart / catchupLastStop
Time stamps (YYYY‑MM‑DD HH:MM:SS) when catch‑up run last began/ended.
RuntimeCatchupMins
Total runtime accrued in the current catch‑up window (any reason).
CatchupAnchorTs
Epoch marking the start of the current catch‑up slot (06:00‑aligned).
RuntimeQuotaMins
Preferred runtime accrued in the quota window (any reason).
RemainingQuotaMins
Remaining preferred (non‑fallback) runtime if a max is configured.
catchupDailyTargetMinscatchupRemainingTodayMinscatchupActiveRuntimeCatchupMinsRuntimeQuotaMinsenableCatchup unchecked
Feature disabled.
catchupRuntimeMins = 0
No fallback required.
Remaining Fallback = 0
Already satisfied by normal runtime.
Outside catch‑up window
Wait until window start.
For 2–3 day catch‑up
Not yet in the final day of the catch‑up slot.
Concurrency limit reached
Another load occupies a slot.
Start throttle
One catch‑up start already happened this tick.
Not enough time passed
Wait for the next scheduler interval.
Turn on debug5 (in plugin preferences) to see lines like:
[CATCHUP][EVAL] LoadName tier=1 served=70m target=180m remaining=110m ...
[CATCHUP][START] LoadName: remaining=110m ...
[CATCHUP][KEEP] ...
[CATCHUP][STOP] ...
[CATCHUP][NO-NEED] ...
A summary line at tick end shows total candidates, starts, stops, and satisfied loads.
Estimate today’s and tomorrow’s PV generation so you can: - Pre‑run discretionary loads if tomorrow looks poor. - Time energy‑intensive tasks near the forecast peak. - Show production expectations on Indigo Control Pages.
forecast.solar with:forecastTodayDate / forecastTomorrowDate
Local date keys (YYYY‑MM‑DD).
forecastTodayKWh / forecastTomorrowKWh
Daily production estimate in kWh (stringified float).
forecastPeakKWToday / forecastPeakKWTomorrow
Peak instantaneous kW (float).
forecastPeakTimeToday / forecastPeakTimeTomorrow
Local timestamp of strongest production (YYYY‑MM‑DD HH:MM).
forecastSolarSummary
Comma‑separated daily totals (friendly format).
forecastSolarPeaks
“Peaks: = , …” summary.
Preferences/Plugins/com.GlennNZ.indigoplugin.SmartSolar/forecast_main_<MainDeviceID>.json
(Contains the raw API payload including ratelimit info.)
forecastTomorrowKWh < X then increase today’s run time.
Time EV / battery charge
Use forecastPeakTimeToday to schedule controlled ramp or preheat.
Control Page forecast panel
Display forecastSolarSummary & forecastSolarPeaks.
forecastTodayKWh
Peak (kW @ time)
forecastPeakKWToday + forecastPeakTimeToday
Tomorrow (kWh)
forecastTomorrowKWh
Tomorrow Peak
forecastPeakKWTomorrow + forecastPeakTimeTomorrow
Summary
forecastSolarSummary
Peaks
forecastSolarPeaks
forecastSolarSummary or individual states.
Diagnose why catch‑up not starting
Enable debug5, check [CATCHUP][EVAL] lines & remaining fallback.
Force fresh forecast fetch
Delete cache file or wait until >1h since last fetch.
Limit simultaneous forced runs
Adjust “Max Concurrent Loads” on Main device.
Q: Does catch‑up exceed my regular max runtime quota? A: Catch‑up counts toward the same served minutes. It won’t ignore your preferred runtime cap: if quota is exhausted, the load is ineligible and catch‑up won’t start.
Q: Can a load be both normally running and catch‑up active? A: If it was already ON when deficit existed, it stays a “normal” run (catchupActive stays False). Catch‑up only marks ownership when it starts the load.
Q: Why is catchupRunTodayMins low even though fallback is satisfied?
A: Those minutes count only plugin‑forced (active) time. Normal passive runtime still reduces catchupRemainingTodayMins but does not increment the “run under catch‑up” counter.
Q: Can I change azimuth to use traditional compass values (e.g. 180 = South)? A: forecast.solar uses 0=South; the plugin applies your entry directly. Enter values per its convention (documented above).
The plugin logs to Indigo’s Event Log with selectable verbosity.
Typical messages:
Info - SolarSmart: Headroom = 2424 W (Grid −2424 W) - SolarSmart: Starting Tier 1 load “Pool Pump” - SolarSmart: Shedding Tier 3 load “Laundry Dryer” (headroom −450 W) - SolarSmart: Next scheduler check in 60s
Debug - SolarSmart: Mode=GridOnly, Grid=−2424 W, Headroom=2424 W - SolarSmart: Tier scan → T1:on, T2:eligible, T3:hold (window closed) - SolarSmart: Scheduled ‘start EV Charger’ (min window met) - SolarSmart: Quota remaining for “Water Heater”: 00:43:12 today
Very Verbose - SolarSmart: Tick(60s): PV=3800, Site=3134, Battery=−9000 → Headroom=9666 - SolarSmart: DOW allowed=True; TimeWindow 08:30–16:30 → within window
Diagnostics tips: - If event decisions look wrong, verify sign conventions for your meters. - If loads don’t start, check time windows/days, quotas, and tier ordering. - Use Debug temporarily to trace scheduling decisions end-to-end.
When you enable the (very verbose) debug7 flag in plugin preferences the scheduler emits a structured, multi‑section diagnostic block for each SmartSolar Load every tick. This is intended for adva[...]
Example (actual output):
══════════════════════════════════════════════════════════════════[...]
DBG7 Device: SolarSmart Load Pool 2000W No Heater (id=127719016) Tier 1
══════════════════════════════════════════════════════════════════[...]
Decision
Status: OFF Action: SKIP (quota) Skip: quota
Headroom Now: -111 W StartsThisTick: 0 RunningNow: 0
Preferred Window Runtime
Served (internal): 240 min Window Run (state): 240 min
Remaining (state): 0 min Remaining (shown row): 0 min
Used (state RuntimeQuotaMins): 240 min Percent: 100%
Anchor Start (ts): 1755149613.112328 (15:33:33)
Catch-up / Fallback
Active: state=False / mem=None Catch-up Str Col: Met
Target: 120 min Remaining: 0 min
Run Today (state): 0 min Run (active secs mem): 0 s
Window: 00:00 - 06:00 Enabled: True
External / Control
External Device On: False IsRunning(state): False
Start Ts: None (—) Cooldown Start: None (—)
Control Mode: device Cooldown Mins: 10
Power & Thresholds
Rated: 2000 W Needed (start threshold est): 2200 W
Surge Mult: 1.00 Start Margin %: 10 Keep Margin %: 5
Min Runtime: 30 min Max Runtime (per start run): 240 min Max Pref Window: 240 min
Quota Window Config: 1d
Concurrency Snapshot
Running Now: 0 Starts This Tick: 0
Raw Internal st[] Keys
IsRunning: False
catchup_run_secs: 0
quota_anchor_ts: 1755149613.112328
run_today_secs: 0.0
served_quota_mins: 240
start_ts: None
today_key: '2025-08-14'
──────────────────────────────────────────────────────────────────[...]
Decision
Preferred Window Runtime Tracks runtime within the rolling “preferred” quota window:
served_quota_mins).RuntimeWindowMins (resets at rollover; trimmed to Served on hydrate).RemainingQuotaMins after last update.(served / target) * 100 (clamped) → used to embed “(NN%)” into Status.Catch-up / Fallback Fallback (scheduled catch‑up) semantics:
catchupActive) and in‑memory (catchup_active) for validation.catchupDailyTargetMins (configured fallback minutes).catchupRemainingTodayMins (deficit after subtracting Served).catchup_run_secs).enableCatchup property.External / Control
None or False if action groups or not controllable.device or actionGroup.Power & Thresholds
ratedWatts.maxRuntimePerQuotaMins (target for the rolling preferred window).Concurrency Snapshot
Raw Internal st[] Keys
A dump of the plugin’s in‑memory dict for this load (sorted keys) to surface hidden values (e.g., cooldown_start, catchup_run_secs, quota_anchor_ts).
RuntimeWindowMins (cosmetic current-window minutes).
Rem Mins
RemainingQuotaMins (preferred window allowance left).
Watts
Estimated Watts required to START (rated * surge * margin).
Catch-up
Off / Met / ACT Xm / Need Xm (see catch-up legend above).
Action
START / KEEP / STOP / SKIP (·) with icon.
Status & Action Icons: - RUN / OFF: Running state indicator. - START: Started this tick. - KEEP: Stayed running. - STOP: Stopped this tick. - ·SKIP: Ineligible; reason encoded in parenthesis in debug lines (and Action cell uses SKIP).
In plugin preferences:
1. Set the overall log level high enough (e.g. DEBUG / 5).
2. Check the debug7 (or “Debug Level 7”) flag.
3. Save. The next scheduler tick will emit one DBG7 block per enabled SmartSolar Load device.
Disable debug7 after troubleshooting; it is intentionally verbose and can flood logs on short tick intervals.
quota_anchor_ts marks when the current preferred window began.served_quota_mins → 0RemainingQuotaMins → full targetRuntimeWindowMins → 0If you have an example DBG7 block that feels ambiguous, open an issue including: - The exact block (copy/paste) - Expected vs observed behavior - Whether catch-up or quota changes happened recently
We can expand the legend or clarify messages further.
1) Pool Pump (Tier 1) - Goal: Run as much as possible on excess solar. - Config: - Tier 1, no quota or high quota (e.g., 6h/day). - Allowed window 09:00–17:00. - Behavior: - Starts early when headroom goes positive. - Sheds late when headroom tightens.
2) EV Charger (Tier 2 or 3) - Goal: Charge only when exporting, avoid imports. - Config: - Tier 2 or 3, set a daily quota (e.g., 2h). - Optional window 10:00–16:00. - Behavior: - Starts after Tier 1 loads are satisfied. - Stops quickly if headroom dips below zero.
3) Water Heater (Tier 2) - Goal: Heat during surplus; cap daily runtime. - Config: - Tier 2, quota 1h/day, window 11:00–15:00. - Behavior: - Opportunistic heating using sunshine, with strict cap.
| v1.0.82 | Requires Indigo v2022.1.0+ | Released Nov. 6, 2025 | Logic fixes, 100W buffers, Fix for Tier priority |
| Released on: | Nov. 6, 2025 |
| Requires: | Indigo v2022.1.0+ |
| Download this release | |
1.0.82
Add 100W buffer, don't stop loads unless headroom more than -100Watts
Add Main device override to stop less important tiers if more important tier now out of cooldown and able to run. (this issue was upsetting impression of events below)
1.0.77 Better Fix for Tiers starting and stopping
1.0.75 Fix tiers priority not always being followed
1.0.70 Move catchup to its own window period checked at the end and then runs
Fine tuning multiple day windows Catchup also is over the runtime window period - so no catchup unless in the final phase / last day of the window period
| Released on: | Sept. 1, 2025 |
| Requires: | Indigo v2022.1.0+ |
| Download this release | |
The following improvements and fixes have landed since the last README update. These notes reflect version 1.0.70 (commit f7fdad16 on main).
06:00‑aligned preferred runtime windows
Quota/Preferred runtime windows now align to local 06:00 for determinism (no rolling drift). 12h: 06:00–18:00 and 18:00–06:00; 24h/1d: 06:00–06:00 next day; 2–3 day windows start at 06:00 every N days. Counters reset exactly once at slot boundaries and survive restarts within a slot. Independent Catch‑up Window Period (optional)
New per‑load option: Catch‑up Window Period can be set independently of the Quota Period. Runtime now accrues into two windows in parallel: Preferred runtime window: mirrored in RuntimeQuotaMins, resets per quota period. Catch‑up window: mirrored in RuntimeCatchupMins, resets per catch‑up period. Catch‑up only forces starts inside the daily catch‑up time window (e.g., 00:00–06:00). For 2–3 day catch‑up periods, forcing is deferred until the final 24 hours of the catch‑up slot. New load states: RuntimeCatchupMins (minutes accumulated within the catch‑up window) CatchupAnchorTs (epoch at the start of the current catch‑up slot) Forecast.Solar client robustness
Local timezone handling hardened (DST‑aware); safe fixed‑offset fallback if IANA data unavailable. Local‑day aggregation and compact summaries; on‑disk cache (~1 hour) to respect rate limits. Grid‑only mode and Test Source
Grid‑only mode uses net grid power exclusively: Headroom = −GridPower (W). Test Source can override the Main device; when “Use Grid Data Only” is checked and Grid Power is provided, PV/Consumption/Battery entries are ignored and headroom derives from grid power only.