Skip to main content

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.

Availability vs. dispatch

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

ActorRole
OperatorSelects a time window in the calendar and clicks Get Availability.
Schedule Dispatch UIBuilds an OpenFMB LoadForecastRequestProfile for each visible Dispatch Node and publishes it; waits for the forecast response.
NATSThe message bus carrying OpenFMB protobuf messages between the UI and the Dispatch Service.
Dispatch ServiceThe 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}):

DirectionSubjectPayload
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:

FieldSource in the profilePurpose
Request MRIDMessageInfo → IdentifiedObject.mRIDUnique request ID; the UI uses it to attribute the returned availability back to this request.
Node name / descriptionMessageInfo → IdentifiedObject.name / .descriptionIdentifies the requesting node and report type.
Start pointLoadForecastRequest → LoadRequestSCH → CrvPts[0].forecastTimeThe start of the requested window.
End pointLoadForecastRequest → LoadRequestSCH → CrvPts[1].forecastTimeThe end of the window — set to the operator's end time plus one hour so the final hour is inclusive.
Exclude-events flageach 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.
Mock 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 W value 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 doesStepFileLines
Subscribe to the request topic LoadForecastRequestProfile.>4src/main.ts180–184
Hand the request to the controller and publish the reply on LoadForecastProfile.{nodeId}4, 6src/main.ts200–206
handleLoadForecastRequest() — deserialize request, produce the response profile4src/NodeController.ts45–74
createLoadForecastProfile() — validate window, build hourly forecast points5src/NodeController.ts178–262
generateResourceAvailability() — per-hour availability shaped by time of day5src/NodeController.ts147–175