-
Notifications
You must be signed in to change notification settings - Fork 0
Document GOPACS Redispatch attributes, state machine, and runtime behavior #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c1627cd
95e58b7
23a2414
803c773
079cbd3
53c4b42
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -125,6 +125,8 @@ ISPs (Imbalance Settlement Periods) are 15-minute intervals. `FlexRequestISPType | |
|
|
||
| In addition to the UFTP day-ahead flex trading described above, GOPACS provides a **Redispatch** mechanism for intraday congestion management. When a congestion situation is expected today, grid operators publish announcements requesting flexibility from market participants. | ||
|
|
||
| > Prerequisites are the same as UFTP — see [Getting Started](#getting-started) for the GOPACS account and contracted EAN. Redispatch additionally requires an API key (see [Configuration](#configuration-1) below). | ||
|
|
||
| The Redispatch flow is different from the UFTP flow: | ||
|
|
||
| 1. **Announcements** — GOPACS publishes congestion announcements via a REST API | ||
|
|
@@ -134,6 +136,30 @@ The Redispatch flow is different from the UFTP flow: | |
| 5. **Activation** — The trading platform notifies the CSP when an order is filled | ||
| 6. **Delivery** — The CSP adjusts power as agreed | ||
|
|
||
| ```mermaid | ||
| sequenceDiagram | ||
| participant Op as Operator | ||
| participant OR as OpenRemote (CSP) | ||
| participant API as GOPACS Redispatch API | ||
| participant TP as Trading Platform (future) | ||
|
|
||
| loop every poll interval (≥ 5 min) | ||
| OR->>API: GET /machineannouncements (CONGESTIONMANAGEMENT, ANNOUNCEMENT_OPEN) | ||
| API-->>OR: announcements | ||
| Note right of OR: Record every newly-seen announcement in history | ||
| OR->>API: GET .../eansolvingeffectivity per announcement | ||
| API-->>OR: EAN categories per announcement | ||
| Note right of OR: Keep announcements where the contracted EAN<br/>is listed; prefer MANDATORY over VOLUNTARY | ||
| OR->>OR: On a new selection: update redispatch* attributes,<br/>record a second history entry with effectivity,<br/>set redispatchBidStatus = PENDING_CONFIRMATION | ||
| end | ||
|
|
||
| Op->>OR: Set redispatchBidPrice, toggle redispatchConfirmBid = true | ||
| OR->>OR: Log bid, set redispatchBidStatus = CONFIRMED | ||
| OR-->>TP: Place order (not yet implemented) | ||
| ``` | ||
|
|
||
| **Selection rules:** per poll, the handler keeps only `CONGESTIONMANAGEMENT` / `ANNOUNCEMENT_OPEN` announcements where the contracted EAN appears in some EAN-effectivity category, then prefers `MANDATORY` over `VOLUNTARY` compliance type when more than one matches. | ||
|
|
||
| ### Configuration | ||
|
|
||
| | Variable | Required | Description | | ||
|
|
@@ -148,6 +174,38 @@ On the **EMS GOPACS Asset**, configure: | |
|
|
||
| - **`redispatchEnabled`** — Set to `true` to start polling for announcements | ||
|
|
||
| ### Asset attributes | ||
|
|
||
| Every redispatch attribute on `EmsGOPACSAsset`. All status, bid-suggestion and history attributes are written by the handler and surfaced read-only in the UI; only `redispatchEnabled`, `redispatchBidPrice` and `redispatchConfirmBid` are operator-editable. | ||
|
|
||
| | Group | Attribute | Type | RO | Purpose | | ||
| |---|---|---|---|---| | ||
| | Configuration | `redispatchEnabled` | boolean | | Master switch — toggle off/on to (re)start the polling handler. | | ||
| | Status | `redispatchAnnouncementId` | text | ✓ | ID of the currently selected announcement, if any. | | ||
| | Status | `redispatchComplianceType` | text | ✓ | `MANDATORY` or `VOLUNTARY`. | | ||
| | Status | `redispatchAnnouncementMessage` | text (multiline) | ✓ | Free-text description from the DSO. | | ||
| | Status | `redispatchStartTime` | timestamp | ✓ | Start of the problem period. | | ||
| | Status | `redispatchEndTime` | timestamp | ✓ | End of the problem period. | | ||
| | Status | `redispatchBidValidityEnd` | timestamp | ✓ | Latest moment a bid can still be submitted for this announcement. | | ||
| | Status | `redispatchRequestedPower` | number (kW) | ✓ | Remaining problem profile, written as predicted data points (15-min ISP grid, 7-day retention). | | ||
| | Status | `redispatchEanEffectivity` | text | ✓ | Effectivity category in which the contracted EAN was matched (e.g. `THREE_PHASE_NETWORK_REDUCE`). | | ||
| | Status | `redispatchRequestAreaBuy` | text | ✓ | DSO-supplied area description for buy orders. | | ||
| | Status | `redispatchRequestAreaSell` | text | ✓ | DSO-supplied area description for sell orders. | | ||
| | Status | `redispatchLastPoll` | timestamp | ✓ | Timestamp of the last completed poll cycle (only updated when the API responded). | | ||
| | Bid | `redispatchSuggestedPower` | number (kW) | ✓ | _Not yet populated — pending bid pricing strategy follow-up._ | | ||
| | Bid | `redispatchSuggestedVolume` | number (kWh) | ✓ | _Not yet populated — pending bid pricing strategy follow-up._ | | ||
| | Bid | `redispatchBidPrice` | number (EUR/MWh) | | Operator-supplied bid price. | | ||
| | Workflow | `redispatchConfirmBid` | boolean | | Operator toggles to `true` to confirm the active bid; handler resets it after processing. | | ||
| | Workflow | `redispatchBidStatus` | text | ✓ | State machine — see below. | | ||
| | History | `redispatchAnnouncementHistory` | JSON object | ✓ | One data point on first sight of each polled announcement, plus a richer entry (with effectivity details) when one is selected (90-day retention). | | ||
| | History | `redispatchBidHistory` | JSON object | ✓ | One data point per confirmed bid (90-day retention). | | ||
|
|
||
| `redispatchBidStatus` values: | ||
|
|
||
| - `NONE` — no active announcement | ||
| - `PENDING_CONFIRMATION` — operator action required | ||
| - `CONFIRMED` — bid logged (and, in future, sent to the trading platform) | ||
|
|
||
| ### Operator Workflow (Pilot Phase) | ||
|
|
||
| 1. When a relevant congestion announcement is detected, the asset attributes are updated with the announcement details | ||
|
|
@@ -156,6 +214,14 @@ On the **EMS GOPACS Asset**, configure: | |
| 4. The operator sets `redispatchBidPrice` (EUR/MWh) and toggles `redispatchConfirmBid` to `true` | ||
| 5. The bid is confirmed and logged (trading platform integration is pending) | ||
|
|
||
| ### Resilience and polling | ||
|
|
||
| - The polling interval is clamped to a minimum of 5 minutes because GOPACS recommends spacing requests at least that far apart. | ||
| - HTTP errors and exceptions on the announcements endpoint **skip the poll and preserve current attributes**, so transient API hiccups do not flap the bid status. Any *successful* poll (HTTP 200) that yields no announcement selected for the contracted EAN clears the active announcement and resets `redispatchBidStatus` to `NONE`. That covers three cases: the response is empty, the response has announcements but none are open `CONGESTIONMANAGEMENT`, or some are but the contracted EAN is not listed in their EAN-effectivity categories. Only a failed fetch (HTTP error / exception) leaves the previous announcement untouched. | ||
| - A *persistent* non-200 (e.g. an invalid API key returning 401, or a sustained outage) keeps the previously selected announcement on screen indefinitely. If `redispatchLastPoll` falls behind the configured interval, check the manager logs for `Failed to fetch announcements: HTTP …` (warning) or `Error fetching announcements` (severe). | ||
|
Comment on lines
+219
to
+221
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 803c773. The resilience note now states that any HTTP-200 poll yielding no selected announcement clears state, and enumerates the three cases — empty response, no open |
||
| - The handler **refuses to start** (logs `SEVERE`) when `GOPACS_REDISPATCH_API_KEY` is unset — without it there is no way to resolve EAN effectivity per announcement. | ||
| - Toggling `redispatchEnabled` off then on restarts the handler; the same applies when `contractedEAN` is changed. Useful when you need to force a clean state. | ||
|
|
||
| ### Components | ||
|
|
||
| ``` | ||
|
|
@@ -170,7 +236,9 @@ gopacs/ | |
|
|
||
| ### History | ||
|
|
||
| Announcement and bid history are stored as time-series data points on `redispatchAnnouncementHistory` and `redispatchBidHistory` attributes, retained for 90 days. These are viewable in the OpenRemote history panel. | ||
| Announcement and bid history are stored as time-series data points on `redispatchAnnouncementHistory` and `redispatchBidHistory`, retained for 90 days and viewable in the OpenRemote history panel. | ||
|
|
||
| `redispatchAnnouncementHistory` records **every** polled announcement on first sight (including ones that the EAN-effectivity check later rejects), so the audit trail captures everything GOPACS returned during the handler's lifetime — not just the announcements that became active. When an announcement is then *selected* on a poll, a second, richer history entry is recorded with the matched effectivity details, so an active announcement will appear twice in the timeline (once at first sight, once on selection). To keep memory bounded for long-running handlers, the running set of already-recorded announcement IDs is capped at 10 000 entries (oldest inserted IDs are evicted first — insertion-order/FIFO). | ||
|
|
||
| ### Future | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 803c773. The diagram label now reads
ANNOUNCEMENT_OPEN, matching theANNOUNCEMENT_STATE_OPENconstant and the surrounding prose.