Skip to content

Polish IO FAT acquisition, relay timestamps, and workspace UX - #121

Merged
masarray merged 13 commits into
mainfrom
agent/io-fat-premium-reporting-timestamps
Jul 29, 2026
Merged

Polish IO FAT acquisition, relay timestamps, and workspace UX#121
masarray merged 13 commits into
mainfrom
agent/io-fat-premium-reporting-timestamps

Conversation

@masarray

@masarray masarray commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Purpose

Address field feedback from the workbook-driven IO List FAT workspace:

  1. keep Explorer navigation responsive while one IED connects
  2. show relay timestamps as the visible ON/OFF evidence time
  3. prefer configured RCB coverage and allow temporary dynamic DataSet/URCB acquisition before bounded MMS fallback
  4. rebuild the dense grid into a calm, premium evidence table
  5. remove low-value text and filesystem path noise
  6. reuse the workstation relay/IED SVG language in the IED Explorer

Acquisition behavior

  • configured RCB/DataSet coverage first
  • association-scoped temporary dynamic DataSet/URCB when imported points are not covered
  • bounded MMS verification/fallback last
  • no process control command execution
  • acquisition preparation remains asynchronous

Timestamp semantics

  • ON/OFF columns display IedTimestamp
  • ARSAS capture time remains in the journal/export and in UI tooltips as provenance
  • a transition with good quality but no relay timestamp is REVIEW, not clean PASS

Non-modal UX

  • IED Explorer remains selectable during connection/discovery/report arming
  • the IED that started preparation is captured independently of the currently viewed card
  • per-IED OFFLINE / READY / LIVE / CONNECTING states
  • header and card loading animations
  • active evidence remains pinned to one IED; browsing cannot change session scope

Visual redesign

  • 48-pixel calm rows
  • grouped live/acquisition/evidence/result columns
  • operator-friendly state labels
  • concise header/footer
  • local paths moved to tooltips
  • relay/BCU SVG icon reused from the main workstation visual language

Regression coverage

  • Smart Reporting policy without process controls
  • non-modal Explorer navigation
  • relay-timestamp bindings instead of ARSAS capture timestamps
  • missing relay timestamp produces REVIEW
  • premium grid density, spinner, SVG, and low-noise UI contracts

Automated validation at head 268c5e158cee36fa2dcf81515fca1a6df2651156

Validate IO List Testing run 37 — success

  • WPF/XAML compilation succeeded
  • 69/69 focused IO FAT regression tests passed
  • relay timestamp semantics, Smart Reporting policy, non-modal UX, evidence state machine, persistence, Excel, PDF, .arsas, and UI contracts passed
  • compiler and test evidence uploaded

Build ARSAS run 783 — success

  • source, website, license, premium UX, GOOSE, SMV, SAS, and immutable engine invariants passed
  • full solution restore/build succeeded
  • complete application regression suite passed
  • portable Windows x64 publication and artifact upload succeeded

Validate SV evidence bundles run 69 — success

  • Sampled Values evidence workflow remains deterministic and unaffected

No review threads are open.

@masarray
masarray marked this pull request as ready for review July 29, 2026 04:40
@masarray
masarray merged commit 57782f6 into main Jul 29, 2026
3 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 268c5e158c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +271 to +272
if (observation.IedTimestamp != null || qualityVerdict == IoEvidenceVerdict.Rejected)
return (qualityVerdict, qualityReason);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject stale relay timestamps before accepting evidence

When an edge is detected through MMS polling, Iec61850MonitorRuntime reuses state.DeviceTimestamp and refreshes the companion t attribute only every 3–30 seconds, so a transition occurring between those polls can carry the previous transition's timestamp. Treating every non-null timestamp as sufficient lets such ON/OFF evidence receive Accepted and ultimately PASS while displaying the wrong relay time; require the timestamp to be refreshed or otherwise correlated with the observed edge.

Useful? React with 👍 / 👎.

Comment on lines +52 to +53
device.IsConnected,
device.IsMonitoring);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep per-IED connection state synchronized after binding

These booleans are copied only when Bind runs, and IoTestIedPlan is not subscribed to subsequent Iec61850MonitorDevice property changes. If monitoring disconnects after preparation, the session controller correctly enters Interrupted, but the Explorer card retains IsLiveMonitoring == true and continues showing LIVE until some unrelated operation invokes binding again; update the plan when the underlying device's connection/monitoring properties change.

Useful? React with 👍 / 👎.

Comment thread IoListTestingWindow.xaml
<Grid.RowDefinitions><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/><RowDefinition Height="Auto"/></Grid.RowDefinitions>
<Grid><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="Auto"/></Grid.ColumnDefinitions><TextBlock Text="{Binding IedName}" FontSize="12.8" FontWeight="SemiBold" Foreground="{StaticResource Ink}" TextTrimming="CharacterEllipsis"/><Border x:Name="StateBadge" Grid.Column="1" Background="#FFF1F2" BorderBrush="#F0B7BC" BorderThickness="1" CornerRadius="9" Padding="6,2"><TextBlock x:Name="StateText" Text="{Binding CardStateText}" FontSize="8.5" FontWeight="Bold" Foreground="#C53A45"/></Border></Grid>
<TextBlock Grid.Row="1" Text="{Binding IpAddress}" Style="{StaticResource Caption}" Margin="0,3,0,0"/>
<TextBlock Grid.Row="2" Margin="0,7,0,0" FontSize="10.5" Foreground="{StaticResource Muted}"><Run Text="{Binding BoundCount, Mode=OneWay}"/><Run Text=" live · "/><Run Text="{Binding PassedCount, Mode=OneWay}"/><Run Text=" pass · "/><Run Text="{Binding PendingCount, Mode=OneWay}"/><Run Text=" pending"/></TextBlock>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Label model-bound points separately from live points

BoundCount counts every point whose state is BoundExact, BoundNormalized, or LivePointReady, so an offline device with a cached/discovered model can show all points as “live” even though none has an active monitor point. Bind this label to a count of LivePointReady points or retain the previous “bound” wording to avoid presenting model matches as live acquisition.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant