Polish IO FAT acquisition, relay timestamps, and workspace UX - #121
Conversation
There was a problem hiding this comment.
💡 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".
| if (observation.IedTimestamp != null || qualityVerdict == IoEvidenceVerdict.Rejected) | ||
| return (qualityVerdict, qualityReason); |
There was a problem hiding this comment.
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 👍 / 👎.
| device.IsConnected, | ||
| device.IsMonitoring); |
There was a problem hiding this comment.
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 👍 / 👎.
| <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> |
There was a problem hiding this comment.
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 👍 / 👎.
Purpose
Address field feedback from the workbook-driven IO List FAT workspace:
Acquisition behavior
Timestamp semantics
IedTimestampNon-modal UX
Visual redesign
Regression coverage
Automated validation at head
268c5e158cee36fa2dcf81515fca1a6df2651156Validate IO List Testing run 37 — success
.arsas, and UI contracts passedBuild ARSAS run 783 — success
Validate SV evidence bundles run 69 — success
No review threads are open.