Availability Request — Message Sequence
This page traces a single Availability Request end to end: the NATS message the Schedule Dispatch UI sends when an operator clicks Get Availability, how a Dispatch Service picks it up, generates a forecast of how much its DER equipment can offer over the requested window, and responds with that availability — which the UI then shows in the calendar.
The flow below uses the Mock DER Dispatch Service (mock-der-dispatch-service) as the consuming Dispatch Service. The mock implements the same OpenFMB topics and message contracts a real Dispatch Service must implement, so the sequence is representative of production.
The step-by-step walkthrough below cites the specific functions in mock-der-dispatch-service that implement the service side of each step, and a Source Reference table at the end collects them in one place.
An Availability Request asks "what can this resource do?" — it is read-only and changes nothing. Committing a schedule is a separate exchange; see Dispatched Event — Message Sequence. The operator normally requests availability first, then builds a dispatch within the returned availability.
Actors
| Actor | Role |
|---|---|
| Operator | Selects a time window in the calendar and clicks Get Availability. |
| Schedule Dispatch UI | Builds an OpenFMB LoadForecastRequestProfile for each visible Dispatch Node and publishes it; waits for the forecast response. |
| NATS | The message bus carrying OpenFMB protobuf messages between the UI and the Dispatch Service. |
| Dispatch Service | The DER controller (here, the Mock DER Dispatch Service). Subscribes to forecast requests, generates an availability forecast, and replies. |
The Two Topics
An availability request is a request/response exchange over two related subjects, both keyed by the Dispatch Node's MRID ({nodeMrid}):
| Direction | Subject | Payload |
|---|---|---|
| Request (UI → Service) | openfmb.loadforecastmodule.LoadForecastRequestProfile.{nodeMrid} | LoadForecastRequestProfile (binary protobuf) |
| Response (Service → UI) | openfmb.loadforecastmodule.LoadForecastProfile.{nodeMrid} | LoadForecastProfile (binary protobuf) carrying hourly availability points |
The UI publishes the request, then listens on the response subject for the matching LoadForecastProfile. Because the operator may have several Dispatch Nodes visible, the UI fires one of these exchanges per node in parallel and tracks each one's progress independently.
Sequence Diagram
Step-by-Step
1. Operator requests availability
The operator selects a start/end window in the calendar and clicks Get Availability. The UI iterates over every visible Dispatch Node and issues one request per node, tracking each node's state (pending → loading → success/error) so a single slow or failing resource is reported on its own without blocking the others.
2. UI builds the LoadForecastRequestProfile
For each node, the UI builds a LoadForecastRequestProfile. The request is intentionally small — it just bounds the window the service should forecast:
| Field | Source in the profile | Purpose |
|---|---|---|
| Request MRID | MessageInfo → IdentifiedObject.mRID | Unique request ID; the UI uses it to attribute the returned availability back to this request. |
| Node name / description | MessageInfo → IdentifiedObject.name / .description | Identifies the requesting node and report type. |
| Start point | LoadForecastRequest → LoadRequestSCH → CrvPts[0].forecastTime | The start of the requested window. |
| End point | LoadForecastRequest → LoadRequestSCH → CrvPts[1].forecastTime | The end of the window — set to the operator's end time plus one hour so the final hour is inclusive. |
| Exclude-events flag | each CrvPt.setState (0 or 1) | Whether the forecast should exclude already-scheduled events. |
Note that the request carries only the two endpoints (start and end), not a point per hour — it is up to the service to expand that window into an hourly forecast.
3. UI publishes the request
The UI serializes the profile and publishes it on openfmb.loadforecastmodule.LoadForecastRequestProfile.{nodeMrid}, then awaits the matching reply on openfmb.loadforecastmodule.LoadForecastProfile.{nodeMrid}.
4. Dispatch Service receives and digests
The service is subscribed to the wildcard openfmb.loadforecastmodule.LoadForecastRequestProfile.> (src/main.ts:180–184). The subscription handler (src/main.ts:200–206) extracts the node MRID from the 4th segment of the topic and calls handleLoadForecastRequest() (src/NodeController.ts:45–74), which deserializes the request and hands it to createLoadForecastProfile() (src/NodeController.ts:178–262).
5. Service generates the availability forecast
createLoadForecastProfile() (src/NodeController.ts:178–262) validates and expands the request:
- The request must contain at least 2 curve points (start and end); otherwise it is rejected.
- The end time must be after the start time.
- The window is divided into hourly points. For each hour,
generateResourceAvailability()(src/NodeController.ts:147–175) produces an availability value in watts, shaped by time of day (morning ramp-up, full daytime, evening ramp-down, reduced overnight) and bounded by the node's capacity.
The mock service uses a fixed capacity of 0–50 W for every node (src/NodeController.ts:55–59) — it does not model real device limits. A production Dispatch Service would derive availability from the actual state and capability of the equipment it manages.
Each hourly value is attached to a LoadForecastPoint (start time + W), and the node's MRID is set as the forecast value source so the UI can attribute the response back to the right node.
6. Service responds with the forecast
After a short simulated delay (~500–1500 ms, src/main.ts:200–206), the service publishes the assembled LoadForecastProfile on openfmb.loadforecastmodule.LoadForecastProfile.{nodeMrid}.
7. UI digests the response into availability
The UI receives the LoadForecastProfile and maps it into the availability it displays:
- It reads the forecast value source MRID to confirm which node the forecast belongs to (a missing message ID or source ID is treated as bad data).
- It narrows the availability's start/end to the first and last returned points.
- It converts each hourly point's
Wvalue to kW (÷ 1000) and stores it as the node's availability.
The node is then marked Success in the progress display.
8. Availability shown in the calendar
With the AvailabilityReq populated, the calendar shows how much each resource can offer in each hour of the window. The operator uses this as the basis for building a dispatch schedule — which is then committed via the Dispatched Event exchange.
Source Reference
This table collects the mock-der-dispatch-service code behind the service side of each step in one place, useful when implementing or debugging a real Dispatch Service against the same contract. The steps in parentheses refer to the Step-by-Step sections above. Line numbers reflect the service at the time of writing and may drift as it evolves.
| What it does | Step | File | Lines |
|---|---|---|---|
Subscribe to the request topic LoadForecastRequestProfile.> | 4 | src/main.ts | 180–184 |
Hand the request to the controller and publish the reply on LoadForecastProfile.{nodeId} | 4, 6 | src/main.ts | 200–206 |
handleLoadForecastRequest() — deserialize request, produce the response profile | 4 | src/NodeController.ts | 45–74 |
createLoadForecastProfile() — validate window, build hourly forecast points | 5 | src/NodeController.ts | 178–262 |
generateResourceAvailability() — per-hour availability shaped by time of day | 5 | src/NodeController.ts | 147–175 |
Related
- Dispatched Event — Message Sequence — the companion exchange that commits a schedule built from this availability.
- Schedule Dispatch UI — User Guide — the operator workflow that produces these requests.
- Deployment: Adding Services — deploying backend services such as
mock-der-dispatch-service.