From e6ff93aa7d3f5444363c4798d903f3112979c0bf Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 13:50:19 +0700 Subject: [PATCH 01/18] Fix IED capability threading and layout --- FaultRecordUxBehavior.cs | 46 ++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/FaultRecordUxBehavior.cs b/FaultRecordUxBehavior.cs index d88b0c0f..127cebf2 100644 --- a/FaultRecordUxBehavior.cs +++ b/FaultRecordUxBehavior.cs @@ -80,18 +80,20 @@ private static void OnListBoxItemLoaded(object sender, RoutedEventArgs e) { Tag = CapabilityPanelMarker, Orientation = Orientation.Horizontal, - HorizontalAlignment = HorizontalAlignment.Left, - VerticalAlignment = VerticalAlignment.Center, - Margin = new Thickness(4, 4, 0, 0) + HorizontalAlignment = HorizontalAlignment.Right, + VerticalAlignment = VerticalAlignment.Top, + Margin = new Thickness(4, 2, 7, 0) }; capabilityPanel.Children.Add(gooseButton); capabilityPanel.Children.Add(smvButton); capabilityPanel.Children.Add(fileButton); - Grid.SetRow(capabilityPanel, Grid.GetRow(actionPanel)); - Grid.SetColumn(capabilityPanel, Grid.GetColumn(actionPanel)); - Grid.SetColumnSpan(capabilityPanel, Math.Max(1, Grid.GetColumnSpan(actionPanel))); - Panel.SetZIndex(capabilityPanel, Math.Max(11, Panel.GetZIndex(actionPanel) + 1)); + // Keep protocol capabilities on their own card row. The previous overlay shared + // the lifecycle-action row and could cover the Stop button when File Transfer was enabled. + cardGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); + Grid.SetRow(capabilityPanel, cardGrid.RowDefinitions.Count - 1); + Grid.SetColumn(capabilityPanel, 1); + Panel.SetZIndex(capabilityPanel, 10); cardGrid.Children.Add(capabilityPanel); var registration = new CardRegistration( @@ -99,13 +101,39 @@ private static void OnListBoxItemLoaded(object sender, RoutedEventArgs e) gooseButton, smvButton, fileButton, - (_, _) => RefreshCapabilityState(currentDevice, gooseButton, smvButton, fileButton)); + (_, _) => QueueCapabilityRefresh(item, currentDevice, gooseButton, smvButton, fileButton)); Registrations.Add(item, registration); currentDevice.PropertyChanged += registration.PropertyChangedHandler; RefreshCapabilityState(currentDevice, gooseButton, smvButton, fileButton); })); } + private static void QueueCapabilityRefresh( + ListBoxItem item, + Iec61850MonitorDevice device, + Button gooseButton, + Button smvButton, + Button fileButton) + { + void RefreshOnUiThread() + { + if (!item.IsLoaded || !ReferenceEquals(item.DataContext, device)) + return; + + RefreshCapabilityState(device, gooseButton, smvButton, fileButton); + } + + if (item.Dispatcher.CheckAccess()) + { + RefreshOnUiThread(); + return; + } + + // Discovery and connection state can be published from worker threads. WPF controls + // have thread affinity, so every capability-state update must be marshalled to the card UI. + item.Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new Action(RefreshOnUiThread)); + } + private static Button CreateCapabilityButton(string capability, string pathData, RoutedEventHandler click) { var icon = new System.Windows.Shapes.Path @@ -273,4 +301,4 @@ private sealed record CardRegistration( Button SmvButton, Button FileButton, PropertyChangedEventHandler PropertyChangedHandler); -} \ No newline at end of file +} From 6abbe9c16000eb86ced56ccbc21b45f5bb810a02 Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 13:50:33 +0700 Subject: [PATCH 02/18] Add temporary capability regression validation --- .../capability-regression-validation.yml | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/capability-regression-validation.yml diff --git a/.github/workflows/capability-regression-validation.yml b/.github/workflows/capability-regression-validation.yml new file mode 100644 index 00000000..4da10297 --- /dev/null +++ b/.github/workflows/capability-regression-validation.yml @@ -0,0 +1,34 @@ +name: Capability Regression Validation + +on: + push: + branches: + - agent/fix-ied-capability-regression + +permissions: + contents: read + +jobs: + build: + runs-on: windows-latest + steps: + - name: Checkout ARSAS + uses: actions/checkout@v4 + + - name: Checkout ARIEC61850 engine + uses: actions/checkout@v4 + with: + repository: masarray/ARIEC61850 + ref: main + path: ../ARIEC61850 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - name: Restore + run: dotnet restore .\ArIED61850Tester.csproj + + - name: Build + run: dotnet build .\ArIED61850Tester.csproj -c Release --no-restore From c94640e32c5ade5306e27e1b2c037938c87bc80a Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 13:50:39 +0700 Subject: [PATCH 03/18] noop --- docs/placeholder | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/placeholder diff --git a/docs/placeholder b/docs/placeholder new file mode 100644 index 00000000..c1b0730e --- /dev/null +++ b/docs/placeholder @@ -0,0 +1 @@ +x \ No newline at end of file From b89c21ac23e5691a56b632ad09e16c489bba5d09 Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 13:50:51 +0700 Subject: [PATCH 04/18] Remove accidental placeholder --- docs/placeholder | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/placeholder diff --git a/docs/placeholder b/docs/placeholder deleted file mode 100644 index c1b0730e..00000000 --- a/docs/placeholder +++ /dev/null @@ -1 +0,0 @@ -x \ No newline at end of file From 2172761a160676fd54eec3ec90b9f9563fb3c1a9 Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 13:50:59 +0700 Subject: [PATCH 05/18] noop2 --- docs/.keep2 | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/.keep2 diff --git a/docs/.keep2 b/docs/.keep2 new file mode 100644 index 00000000..c1b0730e --- /dev/null +++ b/docs/.keep2 @@ -0,0 +1 @@ +x \ No newline at end of file From b43b2a18360e461ea1fb03baa5bfed6e3e6be692 Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 13:51:15 +0700 Subject: [PATCH 06/18] Remove accidental keep file --- docs/.keep2 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/.keep2 diff --git a/docs/.keep2 b/docs/.keep2 deleted file mode 100644 index c1b0730e..00000000 --- a/docs/.keep2 +++ /dev/null @@ -1 +0,0 @@ -x \ No newline at end of file From a6587b6675983a1f2cd45b94b8daa6cf0421fcaf Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 13:54:44 +0700 Subject: [PATCH 07/18] Remove temporary capability validation workflow --- .../capability-regression-validation.yml | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 .github/workflows/capability-regression-validation.yml diff --git a/.github/workflows/capability-regression-validation.yml b/.github/workflows/capability-regression-validation.yml deleted file mode 100644 index 4da10297..00000000 --- a/.github/workflows/capability-regression-validation.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Capability Regression Validation - -on: - push: - branches: - - agent/fix-ied-capability-regression - -permissions: - contents: read - -jobs: - build: - runs-on: windows-latest - steps: - - name: Checkout ARSAS - uses: actions/checkout@v4 - - - name: Checkout ARIEC61850 engine - uses: actions/checkout@v4 - with: - repository: masarray/ARIEC61850 - ref: main - path: ../ARIEC61850 - - - name: Setup .NET - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - - name: Restore - run: dotnet restore .\ArIED61850Tester.csproj - - - name: Build - run: dotnet build .\ArIED61850Tester.csproj -c Release --no-restore From 080c95e758cdaf36e413c91b5b358db0064233a9 Mon Sep 17 00:00:00 2001 From: masarray Date: Fri, 17 Jul 2026 16:45:23 +0700 Subject: [PATCH 08/18] Fix fault record read-only bindings --- FaultRecordWindow.xaml | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/FaultRecordWindow.xaml b/FaultRecordWindow.xaml index 50b69de2..15ef3b1c 100644 --- a/FaultRecordWindow.xaml +++ b/FaultRecordWindow.xaml @@ -91,9 +91,9 @@ - + - + @@ -117,16 +117,16 @@ -