Skip to content

Document GOPACS Redispatch attributes, state machine, and runtime behavior#35

Open
Miggets7 wants to merge 4 commits into
mainfrom
feature/gopacs-redispatch-docs
Open

Document GOPACS Redispatch attributes, state machine, and runtime behavior#35
Miggets7 wants to merge 4 commits into
mainfrom
feature/gopacs-redispatch-docs

Conversation

@Miggets7
Copy link
Copy Markdown
Contributor

@Miggets7 Miggets7 commented May 6, 2026

Description

Documentation-only changes to ems/README.md filling gaps in the Redispatch (Intraday Congestion Management) section. Before this PR, 14 of the 19 redispatch attributes on EmsGOPACSAsset were undocumented and several non-obvious runtime behaviors (state machine, MANDATORY-vs-VOLUNTARY selection, transient-failure handling, mandatory API key, polling floor) were not surfaced. The Redispatch section now matches the level of detail already established by the UFTP section above it.

What was added

  • Sequence diagram — Mermaid diagram of the Operator ↔ OpenRemote (CSP) ↔ GOPACS API ↔ Trading Platform flow, mirroring the UFTP one.
  • 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.
  • Asset attributes subsection — single grouped table (Configuration / Status / Bid / Workflow / History) listing every redispatch attribute on EmsGOPACSAsset, its type, whether it is read-only, and a one-line purpose. redispatchSuggestedPower and redispatchSuggestedVolume are explicitly marked as not yet populated (pending bid pricing strategy follow-up).
  • State machine — explicit list of redispatchBidStatus values: NONE, PENDING_CONFIRMATION, CONFIRMED.
  • Resilience and polling — ≥5 min poll floor (GOPACS guidance), HTTP/exception failures skip the poll and preserve attributes, only confirmed-empty clears them, handler refuses to start without GOPACS_REDISPATCH_API_KEY (logs SEVERE), toggling redispatchEnabled or changing contractedEAN restarts the handler. Persistent non-200s (e.g. 401 from a bad API key) keep stale announcements visible — operator log strings are documented.
  • History semantics — clarified that every polled announcement is recorded on first sight, and selected announcements get a second, richer entry with effectivity details. Recorded-IDs set is bounded at 10 000 (LRU) so a long-running handler cannot leak memory.
  • Cross-link — Redispatch section now links back to UFTP "Getting Started" prerequisites (account, EAN).

Verification

Documentation only — no executable verification. Each claim was cross-checked against:

  • ems/src/main/java/org/openremote/extension/ems/agent/EmsGOPACSAsset.java (attribute definitions)
  • ems/src/main/java/org/openremote/extension/ems/manager/gopacs/GOPACSRedispatchHandler.java (state machine constants, selection logic, failure handling, polling floor, API-key gate, history recording)
  • ems/src/main/java/org/openremote/extension/ems/manager/EmsOptimisationService.java (lifecycle behaviors triggered by attribute changes)

Checklist

  • 1. Acceptance criteria of the linked issue(s) are met
  • 2. Tests are written and all tests pass — N/A (documentation only)
  • 3. Changes are manually tested by you and the reviewer
  • 4. Documentation is written or updated

Miggets7 added 2 commits May 6, 2026 12:09
…ion rules

Fills the gaps between the redispatch implementation and ems/README.md:
- Adds a Mermaid sequence diagram mirroring the UFTP one
- Adds a 'Selection rules' note (MANDATORY preferred over VOLUNTARY)
- Adds an 'Asset attributes' table covering all 19 redispatch attributes
- Enumerates redispatchBidStatus values (NONE, PENDING_CONFIRMATION, CONFIRMED)
- Adds a 'Resilience and polling' subsection covering the polling floor,
  fetch-failure semantics, mandatory API key, and handler-restart triggers
- Clarifies that announcement history records every polled announcement
  (audit trail) and notes the 10k LRU bound
- Cross-links the prerequisites back to the UFTP Getting Started section
- Clarify that redispatchAnnouncementHistory records announcements
  twice for selections (first-sight without effectivity, then a
  richer entry when selected) so the audit trail does not look
  duplicated to operators.
- Note that the >=5 min poll floor clamps the configured interval,
  not a runtime backoff.
- Spell out that persistent non-200 responses (e.g. 401 from a bad
  API key) keep stale announcements visible indefinitely; point to
  the log strings to grep for.
- Add an example category for redispatchEanEffectivity and tighten
  the redispatchLastPoll description to "completed poll where the
  API responded".
- Note that the diagram's selection-side actions only fire on a new
  selection, not every iteration.
@Miggets7 Miggets7 added the Enhancement Improvement of an existing feature label May 6, 2026
@MartinaeyNL
Copy link
Copy Markdown
Member

Adding this to the internal sprint board

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Documentation update to the EMS GOPACS README to fully describe the Redispatch (intraday congestion management) feature, aligning its detail level with the existing UFTP documentation and making runtime behavior and asset attributes explicit for operators and developers.

Changes:

  • Added Redispatch prerequisites cross-linking back to UFTP “Getting Started” and documented the required Redispatch API key/env vars.
  • Added a Redispatch sequence diagram plus explicit selection rules and bid-status state machine descriptions.
  • Documented all Redispatch-related EmsGOPACSAsset attributes (grouped table) and clarified resilience/polling and history semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ems/README.md
Comment on lines +219 to +221
- 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. Only a confirmed-empty response (HTTP 200 with no announcements) clears the active announcement and resets `redispatchBidStatus` to `NONE`.
- 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).
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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 CONGESTIONMANAGEMENT announcements, and contracted EAN absent from the effectivity categories — matching the three clearAnnouncementAttributes() call sites in the handler. Only a failed fetch preserves prior state.

Comment thread ems/README.md Outdated
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 (LRU-evicted).
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 803c773 by correcting the wording rather than the implementation. The set is add-only for dedup and IDs are never re-queried, so access-order LRU would behave identically to insertion order here — FIFO is the intended behavior. Updated both the README and the recordedAnnouncementIds code comment to say insertion-order/FIFO (the LinkedHashMap uses accessOrder=false).

Comment thread ems/README.md
Comment on lines +146 to +148
loop every poll interval (≥ 5 min)
OR->>API: GET /machineannouncements (CONGESTIONMANAGEMENT, OPEN)
API-->>OR: announcements
Copy link
Copy Markdown
Contributor Author

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 the ANNOUNCEMENT_STATE_OPEN constant and the surrounding prose.

Address Copilot review feedback on the redispatch documentation:

- Resilience note now describes all three HTTP-200 conditions that clear
  the active announcement (empty response, no open CONGESTIONMANAGEMENT
  announcements, or contracted EAN absent from effectivity categories),
  instead of only the empty-response case. Clarifies that only a failed
  fetch preserves prior state.
- Replace inaccurate "LRU-evicted" wording with insertion-order/FIFO in
  both the README and the recordedAnnouncementIds code comment; the set
  uses a LinkedHashMap with accessOrder=false.
- Align the sequence diagram announcement state label with the actual
  ANNOUNCEMENT_OPEN constant used by the handler and prose.
@pierrekil
Copy link
Copy Markdown
Member

@igorrutka to approve

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Improvement of an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants