Battery dispatch programs at utilities tend to have a simple model: during a demand event, dispatch enrolled batteries. The program documentation describes this as a straightforward sequence. The operational reality is more complicated, because "dispatch enrolled batteries" is only meaningful if you know, before issuing the signal, what state those batteries are actually in. Pre-dispatch state verification is where most programs lose the gap between committed and delivered capacity.
What follows is a description of three specific signals that operations teams consistently miss in pre-dispatch workflows, and what happens when those signals are absent.
Signal one: current SoC at the 90-minute and 30-minute pre-dispatch windows
The most consequential pre-dispatch signal for battery dispatch is state of charge. This is obvious in concept and underperformed in practice.
A 10 kWh battery enrolled in a demand response program has a rated discharge contribution based on its nameplate capacity and the program's discharge depth agreement (typically discharging from an upper setpoint, often 80-90% SoC, to a lower limit, often 20% SoC). The expected contribution is calculated at program enrollment from those parameters. What the dispatch model uses when the event fires depends entirely on how the SoC data is structured in the DER management system.
If the system stores SoC at polling intervals and the pre-dispatch decision uses the most recently stored reading, the effective pre-dispatch data currency is whatever the polling cadence is. For DER platforms pulling SoC from manufacturer cloud APIs on 15-minute or 30-minute polling schedules, the SoC used in the dispatch calculation may be 30 to 45 minutes old at the time the event fires. In a summer afternoon scenario where batteries have been self-cycling through price optimization since noon, a 30-minute stale SoC reading can be meaningfully wrong. Batteries that were at 75% SoC at 3:30 PM may be at 45% SoC at 4:00 PM after completing a discharge cycle that the polling system didn't capture in time.
The two-window pre-dispatch check matters because it separates two different questions. The 90-minute check is a planning check: does the current fleet SoC support the committed capacity level? If the aggregate available capacity at 90 minutes pre-dispatch is materially below the program commitment, there may be time to adjust the commitment to the ISO or utility system operations. The 30-minute check is a dispatch readiness check: are the assets that will receive the dispatch signal in a state that allows them to respond? This is when stale SoC data is most expensive: if the dispatch signal is about to issue and the SoC data is 30 minutes old, there's no time to recheck, and the program commits to a delivery it may not be able to make.
The operational fix is a dedicated pre-dispatch SoC pull triggered at both windows: not the scheduled polling read, but a forced synchronous API call to get current SoC before the dispatch decision finalizes. This adds API load on the manufacturer platform, which is why many systems use scheduled polling as the default rather than on-demand pulls. For programs where delivery accuracy matters (ISO market participation, utility demand peak avoidance with financial consequences), the on-demand pre-dispatch pull is worth the API overhead.
Signal two: BMS temperature and cycle count flags
Battery management systems track cell temperature and cycle count as primary indicators of battery health and performance limits. Most battery vendor APIs surface a subset of BMS data in their telemetry: SoC, power output, state (charging/discharging/idle), and alarm codes. What they frequently do not surface in accessible API fields is cell temperature and cumulative cycle count, which are stored in BMS internal registers rather than the high-level API status objects.
Why this matters for dispatch: lithium battery discharge characteristics change with temperature. At high ambient temperatures in summer (battery enclosures in unconditioned garages or exterior utility spaces can reach internal temperatures of 38 to 45 degrees Celsius), battery management systems reduce maximum charge and discharge rates to protect cell longevity. A battery that can nominally deliver 5 kW continuous discharge at 25 degrees Celsius may be limited to 3.5 kW discharge at 40 degrees Celsius by the BMS thermal management algorithms. The API SoC reading will correctly show 80% SoC; it will not show that the BMS is currently derated on discharge power due to thermal limits.
In practice, the dispatch model calculates available capacity from SoC times rated power, and issues a dispatch signal expecting rated power delivery. The battery responds, but delivers at the derated power level the BMS allows in thermal conditions. The gap between expected and actual delivery looks like a telemetry anomaly rather than a thermal derating event, because the dispatch system has no visibility into the BMS temperature state that caused it.
Cycle count matters because batteries nearing end-of-life show reduced usable capacity and slower discharge rates. An enrolled battery at 95% of its design cycle life may have only 70% of its original usable capacity, but its enrollment record still shows the original nameplate specification. Without cycle count data in the operational view, the dispatch model treats all enrolled batteries as identical in capacity, which overestimates available dispatch from aging assets.
This is an area where the right expectation-setting matters. Not every deployment will have access to BMS cell temperature and cycle count through vendor APIs; some BMS data is available only through direct device communication via MODBUS TCP or CAN bus, not through the cloud API layer. For programs where precision matters, it is worth establishing at commissioning what BMS data the vendor API surfaces, and what data requires direct device access. That knowledge should inform how the dispatch model estimates available capacity for assets where thermal and aging data is unavailable.
Signal three: feeder loading and reverse power flow at the substation head
The third pre-dispatch signal is not about the battery fleet directly; it is about the distribution circuit context in which the dispatch will occur.
Battery discharge adds generation to the distribution feeder. On a feeder that is already heavily loaded, additional discharge capacity helps manage the load. On a feeder that is lightly loaded or that is exporting power to the substation due to high solar generation, adding battery discharge may push the feeder into reverse power flow territory that the substation transformer or voltage regulation equipment wasn't configured to handle during that operating condition.
A coordinated dispatch decision considers both the load relief needed (from the demand management perspective) and the feeder's current operating state (from the distribution operations perspective). If the dispatch signal is issuing 200 kW of battery discharge on a feeder that is currently near zero load due to cloud cover reducing air conditioning and a prior solar generation ramp (a common pattern on high-solar penetration feeders in fall shoulder season), the feeder may receive more discharge than it can absorb without voltage excursions at the feeder extremities.
The feeder loading signal comes from SCADA or distribution management system (DMS) feeder data, not from the DER management platform. A pre-dispatch workflow that doesn't include a SCADA feeder load check is making dispatch decisions without the distribution context that makes those decisions safe. This is a data integration requirement: the DER dispatch system needs a live data link to SCADA feeder loading, or the operations team needs a manual step that checks SCADA before confirming the dispatch. Either way, the feeder state at dispatch time is a decision input, not an afterthought.
Building pre-dispatch checks into the workflow
The three signals above (SoC currency, BMS state, feeder loading) share a common characteristic: they are not available in the enrollment database that most DER management platforms treat as their primary data source. Enrollment databases record program membership and nameplate specifications. Operational dispatch requires live state data that the enrollment database doesn't track.
The practical architecture that addresses this runs a pre-dispatch confirmation step as an automated workflow trigger: at T-90 min and T-30 min before a planned dispatch event, the system runs forced SoC pulls, checks BMS alarm states, and pulls current feeder loading from SCADA. The output is a confirmed available capacity estimate that replaces the enrollment-based estimate in the dispatch decision. If the confirmed capacity is materially below the committed level, the operations team is notified in time to adjust the commitment rather than under-delivering without warning.
We are not saying that programs without these checks fail; many run adequately on enrollment-based capacity estimates with acceptable delivery variance. The point is that the variance is attributable to known data gaps, and closing those gaps is a tractable engineering problem for programs where delivery precision matters, not an inherent limitation of battery dispatch programs. The signals are available; they just require deliberate data architecture to capture and use them in the pre-dispatch window.