Skip to content

Grid power and measured DC charging

The APS MultiPlus-II is used for charging; the SureSine supplies AC loads. This addition uses the existing Modbus logger, daily CSV, append-to-Zarr job, forecast services and dashboard products. It adds no service, timer, broker, database or dependency and does not issue device-control commands.

Measurements

  • GridWatts: signed AC input watts, Cerbo system unit 100 register 820 (L1). Keep it missing unless active input register 826 reports grid (1). Modbus returns zero for some unavailable values, so zero alone is not validity.
  • MultiPlusDCWatts: DC voltage times signed DC current from a single paired read of VE.Bus unit 227 registers 26–27, scaled by 100 and 10 respectively. This is device instance 276, verified on the APS on 2026-10-23. Positive values supply the DC bus. Missing/failed reads and implausible 48 V bus voltages remain missing. The unit key multiplus_monitor is deliberately separate from the logger's dormant legacy charging-control key.
  • ChargerTemperature: the MultiPlus BatteryTemp sensor, VE.Bus unit 227 register 61, signed tenths of a degree Celsius (/Dc/0/Temperature). The Thermal State plot labels it Charger Temperature; it is the reported BatteryTemp sensor, not a documented internal heatsink measurement. A live read on 2026-10-23 returned 41.0 C. Failed reads, a missing MultiPlus DC measurement, and values outside -40 to 120 C stay missing. Raw zero also stays missing because Modbus cannot distinguish an unavailable sensor from exactly 0 C; ordinary negative temperatures are retained.

The mappings were checked against Victron's Modbus register list and unit mapping, and a read-only live check returned 53.96 V and 47.3 A (2552.308 W DC).

All three fields are optional in storage. Older records remain NaN. Daily CSV headers remain fixed: the fields first appear in the next UTC daily file after logger deployment. Do not rewrite the current or historical raw CSV files.

Overview charging indicator

The web dashboard and Overview API place MultiPlus Charger immediately after Power Data. It uses aps_multiplus_power_w and aps_multiplus_power_time_utc from the normal cloud operations snapshot. The collector reads only the final MultiPlusDCWatts sample in the existing power Zarr; it never carries a previous finite reading over a missing final sample. This adds no field-device reads, control commands, new service, or changes to collection and app-refresh schedules.

Fresh positive output means Charging; zero or negative output means Not charging. Neither describes the configured enabled/off setting. Missing, invalid, future-dated, or older-than-30-minute measurements mean Unknown. The card includes measured power and sample age. The web dashboard, iOS and Android age cached cards locally, including while offline and on return to the foreground. The browser clock only changes the charger card text and colour; it makes no requests and does not refresh other products.

Release the snapshot collector separately from the presentation/API checkout, using the existing isolated runtime and collector timer. Preserve scientific writers and all raw/product paths. Verify the next scheduled snapshot and API card against the final stored measurement; do not trigger a field query to verify this display. Older snapshots safely display Unknown. Rollback restores the previous reader/collector pins and never changes observation data.

Current Grid Power card

The Power tab's Current Conditions section places Grid Power above the charts on the web dashboard, iOS and Android. It displays signed AC input in W or kW and the measurement age. This is separate from the existing MultiPlus DC charging measurement and the historical Grid AC input chart.

The existing cloud collector reads the final GridWatts and MultiPlusDCWatts row in one opening of the stored power product. It publishes aps_grid_power_w and aps_grid_power_time_utc in the normal operations snapshot. The card reads only that snapshot; it does not query the field, start collection, change the sampling interval or use the last finite chart point to fill a gap. The logger's existing AC-source validity checks remain authoritative; a valid zero is displayed as zero, never as proof of grid Off.

The native Power response adds optional currentSignals in current, observed and all groups, using the established Overview-card shape. Forecast groups do not include it. Older clients can ignore this additive field; newer clients show Unknown when an older snapshot or API lacks the measurement. Missing, invalid, future-dated or older-than-30-minute readings show Unknown. Each client updates age locally, including offline and on foreground return, without adding requests. Release the collector separately and verify its next normal scheduled snapshot before claiming live card availability.

Grid Power history

Current Conditions places a Grid Power chart immediately after Renewables on both dashboards and in the iOS and Android apps. It shows Grid AC input and MultiPlus DC charging as separate solid and dashed lines on one watts axis. These traces move from Battery Charging into this dedicated panel. Battery Charging continues to show net battery current and power.

The chart uses the existing stored display product, time controls, point limits, measurement timestamps and gap handling. Signed readings and valid zeros remain measurements; missing history stays missing. If only one measurement is available, show that trace; if neither is available, omit the chart as for other unavailable panels. The current Grid Power card remains the authority for the latest sample and its freshness, independently of older chart points.

Both native apps already render the server's current panels in order, so this addition requires no app binary release or extra request. Release only the presentation/API code; no collector, writer, forecast, equipment or schedule change is required.

Forecast meaning

Qualified station demand is:

SolarEast + SolarSouth + SolarWest + max(MultiPlusDCWatts, 0) - BatteryWatts

All inputs must be present; negative inferred demand is invalid. Missing DC power is not zero. Historical unknown-supply rows cannot train the corrected load model. If no recent qualified load exists, the deterministic forecast is not replaced and the operating product reports unavailable. Model versions isolate previous load learning and SOC corrections.

The standard forecasts and operating recommendations assume no grid charging. An optional GridContinuesSOCP50 curve uses the same SOC anchor, weather, load members and battery parameters as the current-state operating forecast. It adds the preceding 15-minute median measured DC supply inside the existing SOC integrator, retaining battery efficiency, power limits and SOC bounds. It is shown for up to 96 hours and is a conditional scenario, not a prediction of grid availability or charger taper.

Eligibility requires at least 90% paired AC/DC coverage, a valid final sample, nonnegative input and charging values, and an observation age of at most 20 minutes. One-second coverage bins allow at most one second of nearest-sample tolerance to accommodate the logger's approximately 1.1-second cadence. A valid zero rate produces the same curve as the baseline. Missing or stale telemetry omits the comparison. Its rate, contract, anchor and median curve are retained in the existing operating recommendation archive.

No-grid SOC calibration rejects verification intervals with observed charging or insufficient DC telemetry, including charging between otherwise valid SOC endpoints. The two measured powers appear on the Grid Power history panel. The conditional median appears on the existing 24 h and 96 h panels.

Rollout and rollback

  1. Preserve the current source and deploy the compatible cloud reader first.
  2. Deploy the logger's two changed source files through its existing Git checkout and restart only powermonitor.service. Check fresh acquisition and the DC read. Expect the new CSV columns at the next UTC boundary.
  3. Check raw CSV → Zarr values and missing-history semantics before activating the corrected forecast. Do not activate it before qualified DC samples exist.
  4. Keep scientific writers and presentation releases separate. Stage the tested main commit in an immutable presentation checkout, use the focused presentation_release.yml playbook on development, then tag and release the same revision on production. Preserve the existing runtime and data routes. Check both forecast cards and the battery and Thermal State panels. Activate corrected forecast writers only after isolated generation succeeds with qualified new DC data; do not move all writers to the presentation pin.
  5. Confirm the current-state comparison shares the SOC anchor and that missing DC data hides it. Verify the archived charging rate and curve.

For rollback, redeploy the preceding application and logger commits. Preserve raw data and added Zarr fields; older code may ignore them. Keep the original forecast timestamps when retaining a previous product.

Pre-implementation checkpoint refs in both repositories: codex/grid-integration-pre-implementation-20261023. Logger checkpoint: ba519f2f1cad21aa7fca96a850d320bca6d56b0a. Dashboard checkpoint: 8f6b021b792cba9e076cf4c60044b52b94af9c3a.

The initial deployment on 2026-10-25 uses the existing scientific writer base plus additive storage and observed-summary changes, tagged power-storage-20261025.2. The logger uses 5bc8387. The existing daily CSV header means the first new columns are expected in power_data_20261026.csv. Until those measurements arrive and pass end-to-end checks, forecast activation remains pending. The unrelated development writer edits are preserved separately; the public dashboard uses its isolated presentation checkout.