Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
227 commits
Select commit Hold shift + click to select a range
ffb1551
FAT v2: add dataset-driven verification domain contract
masarray Aug 31, 2026
c3b9eb3
FAT v2: project every ARIEC static DataSet member
masarray Aug 31, 2026
164230c
FAT v2: lock inclusion and evidence preservation invariants
masarray Aug 31, 2026
4cbd5d9
FAT v2: regress digital and analog DataSet projection
masarray Aug 31, 2026
0eba1d5
FAT v2: add generic live value observation
masarray Aug 31, 2026
f2de792
FAT v2: add operator snapshot capture for analog values
masarray Aug 31, 2026
23596a0
FAT v2: regress analog Value 1 and Value 2 capture
masarray Aug 31, 2026
f2d3694
FAT v2: fix digital manual-capture regression fixture
masarray Aug 31, 2026
45997d7
FAT v2: add deterministic multi-SCL workspace aggregation
masarray Aug 31, 2026
b3281a3
FAT v2: regress multi-SCL aggregation and conflict policy
masarray Aug 31, 2026
8493001
docs: lock FAT v2 phased implementation and regression gates
masarray Aug 31, 2026
0fb6d60
FAT v2: preserve operator selection during clean retest
masarray Aug 31, 2026
85a549f
FAT v2: stop auto-disabling completed rows on restore
masarray Aug 31, 2026
4539d6e
FAT v2: regress restore and clean selection authority
masarray Aug 31, 2026
a9b69b0
FAT v2: update clean-session regression for operator selection
masarray Aug 31, 2026
5dd739f
FAT v2: persist operator selection across restore and handover
masarray Aug 31, 2026
53296a2
FAT v2 P2b: stage rolling evidence before promotion
masarray Sep 1, 2026
ddb869f
FAT v2 P2b: regress rolling evidence promotion
masarray Sep 1, 2026
0d85a52
FAT v2 P2c: separate capture scope and keep sessions operator-stopped
masarray Sep 1, 2026
85477ac
FAT v2 P2c: stop mutating selection for continuation
masarray Sep 1, 2026
79953d6
FAT v2 P2c: regress explicit non-mutating continuation scope
masarray Sep 1, 2026
f2b29c5
FAT v2 P2c: guard selection authority through start workflow
masarray Sep 1, 2026
ec931e5
FAT v2 P2c: regress operator-stopped rolling sessions
masarray Sep 1, 2026
19b3792
FAT v2 P2b: keep ON and OFF journal attempt identity aligned
masarray Sep 1, 2026
d65ed1a
FAT v2 P2c: keep recovered capture running until Stop
masarray Sep 1, 2026
6867dfb
FAT v2 P2: align UI contract with operator-owned selection
masarray Sep 1, 2026
7041bef
FAT v2 P2: seal journal before reading operator-stopped session tests
masarray Sep 1, 2026
e5c081c
FAT v2 P2: stop before journal inspection in recovery regression
masarray Sep 1, 2026
588109e
FAT v2 P3: add generalized source descriptors
masarray Sep 1, 2026
19261e4
FAT v2 P3: persist generalized source identity on project
masarray Sep 1, 2026
b9f2a8a
FAT v2 P3: add multi-source workspace staging
masarray Sep 1, 2026
e24836b
FAT v2 P3: stage pre-described source sets
masarray Sep 1, 2026
6e56043
FAT v2 P3: generalize workspace and package source persistence
masarray Sep 1, 2026
b409de1
FAT v2 P3: bootstrap workspaces by source-set identity
masarray Sep 1, 2026
a14b40b
FAT v2 P3: bundle and validate multiple FAT sources
masarray Sep 1, 2026
e6c25f7
FAT v2 P3: add multi-SCL source bundle regressions
masarray Sep 1, 2026
cb785bb
FAT v2 P3: fix source validation variable scope
masarray Sep 1, 2026
242d1ef
FAT v2 P4: classify capture mode from value type, not FC alone
masarray Sep 1, 2026
4ea61df
FAT v2 P4: add production ARIEC SCL to FAT project importer
masarray Sep 1, 2026
0b17529
FAT v2 P4: add real ARIEC SCL import and persistence regressions
masarray Sep 1, 2026
76058fe
FAT v2 P4: include source and SCL import regressions in focused gate
masarray Sep 1, 2026
bfdf269
FAT v2 P5: add generic point disposition and Value1 Value2 state
masarray Sep 1, 2026
4804209
FAT v2 P5: persist SCL signal kind and capture mode into workspace rows
masarray Sep 1, 2026
aa149bf
FAT v2 P5: journal generic Value1 Value2 capture metadata
masarray Sep 1, 2026
d819a6f
FAT v2 P5: expose generic operator snapshot evidence creation
masarray Sep 1, 2026
ae2ec46
FAT v2 P5: bridge automatic and operator Value1 Value2 capture in one…
masarray Sep 1, 2026
7e5bf6e
FAT v2 P5: preserve legacy evidence journal hash schema
masarray Sep 1, 2026
6270076
FAT v2 P5: keep generic snapshots inside legacy journal hash shape
masarray Sep 1, 2026
16a10a7
FAT v2 P5: exclude operator-removed rows from preflight
masarray Sep 1, 2026
65d3f3e
FAT v2 P5: persist disposition and generic Value1 Value2 evidence
masarray Sep 1, 2026
7bb5a32
FAT v2 P5: restore operator disposition and Value1 Value2 progress
masarray Sep 1, 2026
685d633
FAT v2 P5: prove generic capture disposition and persistence invariants
masarray Sep 1, 2026
e69e0d1
FAT v2 P5: retain duplicate-scope diagnostic compatibility
masarray Sep 1, 2026
8c075e1
FAT v2 P5: add multi-SCL FAT launcher
masarray Sep 1, 2026
4f327d7
FAT v2 P5: install generic Value1 Value2 workspace and remove restore UX
masarray Sep 1, 2026
8c150d5
FAT v2 P5: add dedicated removed signals restore window
masarray Sep 1, 2026
244f475
FAT v2 P5: make workspace context generic and disposition-aware
masarray Sep 1, 2026
4274ee8
FAT v2 P5: add generic native Value1 Value2 report layout
masarray Sep 1, 2026
25d1676
FAT v2 P5: route SCL projects to generic native report
masarray Sep 1, 2026
5dbef7f
FAT v2 P5: prove generic native report semantics
masarray Sep 1, 2026
7f5ed85
FAT v2 P5: fix snapshot point initializer syntax
masarray Sep 1, 2026
848dc77
FAT v2 P5: preserve atomic snapshot move call
masarray Sep 1, 2026
2674b55
FAT v2 P5: align selection authority regressions
masarray Sep 1, 2026
1bd0699
FAT v2 P5: align continuation scope regression
masarray Sep 1, 2026
8239406
FAT v2 P5: exercise production arsas package round trip
masarray Sep 1, 2026
356b60a
FAT v2 P5: align UI contract with DataSet workspace
masarray Sep 1, 2026
49e969d
FAT v2 P5: align explicit scope regression wording
masarray Sep 1, 2026
e985d8b
FAT v2 P5: lock operator checkbox while scope is active
masarray Sep 1, 2026
5c0bfc7
FAT v2 P5: guard active scope UI locks
masarray Sep 1, 2026
57a53b2
FAT P5.1: allow dataset membership live fan-out
masarray Sep 1, 2026
3b5f895
FAT P5.1: permit distinct dataset membership fan-out
masarray Sep 1, 2026
9b7a49f
FAT P5.1: restore ARIEC dataset inventory before binding
masarray Sep 1, 2026
4d4fda1
FAT P5.1: add physical dataset binding regressions
masarray Sep 1, 2026
561bdd7
FAT P5.1: satisfy point-plan evidence contract
masarray Sep 1, 2026
c4f62fa
FAT P5.2: bind static dataset display identity
masarray Sep 1, 2026
78a2fd1
FAT P5.2: retain imported SCL workspace authority
masarray Sep 1, 2026
fc1e89a
FAT P5.2: fast-connect from imported SCL authority
masarray Sep 1, 2026
2034cb5
FAT P5.2: cover unresolved static membership binding
masarray Sep 1, 2026
9e1b849
FAT v2 P5.3 allow partial live acquisition
masarray Sep 1, 2026
f311bd2
FAT v2 P5.3 start evidence on live subset
masarray Sep 1, 2026
3bd6fae
Cover FAT partial live operator authority
masarray Sep 1, 2026
0efffd7
Bump ARIEC for structured FAT DataSet binding
masarray Sep 1, 2026
f93e267
Cover structured analog FAT engine projection
masarray Sep 1, 2026
8dd2c71
Fix P5.3 partial live regression fixture
masarray Sep 1, 2026
54bdcf4
Align continuation scope regression with partial live FAT
masarray Sep 1, 2026
e889d3a
Align selection authority regression with live subset start
masarray Sep 1, 2026
2613206
Document P5.3 live subset session boundary
masarray Sep 1, 2026
937f57f
FAT P5.3: preserve G1 ancestry across engine pin advances
masarray Sep 1, 2026
4dd3880
FAT P5.4: wire semantic structured reports into live runtime
github-actions[bot] Sep 1, 2026
6cb29fe
Pin sparse structured report semantic matching fix
masarray Sep 2, 2026
88674fd
Lock ARSAS regression to sparse structured report identity fix
masarray Sep 2, 2026
c669fe2
Fix FAT structured sibling binding and expose SCL import
masarray Sep 2, 2026
7f47304
Fix multiline SCL menu regression assertion
masarray Sep 2, 2026
b77e9d7
Restrict FAT DataSet merge to exact IEC identity
masarray Sep 2, 2026
480eb36
Add cached structured MMS alias regression
masarray Sep 2, 2026
988c994
Preserve distinct static DataSet membership rows for FAT
masarray Sep 2, 2026
fab6370
Remove connected reconciliation gate from direct SCL FAT
masarray Sep 2, 2026
08aba0d
Prefer exact static DataSet identity in direct SCL FAT
masarray Sep 2, 2026
32c2ff5
Add direct SCL FAT latency and THD identity regressions
masarray Sep 2, 2026
4c525b6
Throttle repeated structured report warnings
masarray Sep 2, 2026
47becc8
Preserve scalar MMS reuse without collapsing structured FAT members
masarray Sep 2, 2026
b047703
Remove reconciliation from direct SCL FAT critical path
masarray Sep 2, 2026
22c0e7a
Allow explicit DataSet THD scalar signals into runtime
masarray Sep 2, 2026
e488f79
Lock THD runtime publication and nonblocking SCL FAT startup
masarray Sep 2, 2026
88e7901
Fix FAT runtime responsiveness and multi-IED workflow
masarray Sep 2, 2026
a1db1f0
Fix fresh SCL selection authority
masarray Sep 2, 2026
d31c0b9
Add fresh SCL selection authority regression coverage
masarray Sep 2, 2026
2fb5b27
Add schema-safe aggregate value projector
masarray Sep 2, 2026
a30d716
Align workspace bridge regression with fresh SCL authority
masarray Sep 2, 2026
3e5c946
Define schema-proven aggregate read plans
masarray Sep 2, 2026
dfca8f9
Expose schema-safe aggregate read authority
masarray Sep 2, 2026
738ce9a
Route aggregate FAT reads through exact schema leaves
masarray Sep 2, 2026
6fd04b2
Add schema-safe THD and demand aggregate regressions
masarray Sep 2, 2026
3eef76a
Fix Removed Signals restore authority
masarray Sep 2, 2026
6c0d1c5
Add Removed Signals authority regression
masarray Sep 2, 2026
d4102a2
Keep demand companion reads on proven scalar leaf
masarray Sep 2, 2026
f642c74
Keep FAT disposition independent from shared selection
masarray Sep 2, 2026
2ae8986
Align THD fast-path regression with schema-safe parent reads
masarray Sep 2, 2026
277378e
Regress Removed Signals selection independence
masarray Sep 2, 2026
7bc5e1b
P0.3 make FAT plan locks per IED
masarray Sep 2, 2026
7c5cdc5
P0.3 lock Removed Signals per IED
masarray Sep 2, 2026
c5b438d
Regress P0.3 per-IED FAT UI locks
masarray Sep 2, 2026
9df05ad
P0.3 make checkbox lock synchronous per IED
masarray Sep 2, 2026
a35ba65
Regress synchronous per-IED checkbox locking
masarray Sep 2, 2026
e3f9705
Exercise P0.3 per-IED editability behavior
masarray Sep 2, 2026
a6a48ba
Add P0.4 loaded FAT SCL append transaction
masarray Sep 2, 2026
9316fb8
Route FAT Add IED through append gate
masarray Sep 2, 2026
c716573
Make loaded FAT SCL import additive by default
masarray Sep 2, 2026
d17851a
Allow SCL append during independent IED workflows
masarray Sep 2, 2026
cf817b7
Add P0.4 loaded FAT SCL append regression
masarray Sep 2, 2026
91a19f0
Fix P0.4 append result namespace
masarray Sep 2, 2026
35ddc22
Align workspace mode regression with P0.4 append semantics
masarray Sep 2, 2026
60a1732
Align IO testing add-IED contract with P0.4
masarray Sep 2, 2026
0f73368
Decouple IED connect from FAT checkbox scope
masarray Sep 2, 2026
5ac2e3b
Add FAT acquisition scope independent of TEST selection
masarray Sep 2, 2026
49229c6
Fix FAT monitor helper namespace
masarray Sep 2, 2026
f22648d
Harden independent multi-IED FAT acquisition
masarray Sep 2, 2026
efec317
Keep FAT evidence scope separate from connection acquisition
masarray Sep 2, 2026
32a5860
Lock P1 multi-IED connection and acquisition contract
masarray Sep 2, 2026
6dc4370
Resolve direct SCL acquisition independently of TEST
masarray Sep 2, 2026
b3a9610
Regress unchecked direct-SCL acquisition in P1
masarray Sep 2, 2026
4940877
Fix P1 direct-SCL regression fixture
masarray Sep 2, 2026
2c6b3a3
Align continuation scope regression with P1 acquisition authority
masarray Sep 2, 2026
0483f63
Document P1 monitor-start compatibility seam
masarray Sep 2, 2026
4a897e6
Add per-IED parallel FAT evidence coordinator
masarray Sep 2, 2026
1ff4df9
Wire parallel FAT evidence leaves to runtime
masarray Sep 2, 2026
62bce48
Enable per-IED parallel FAT evidence sessions
masarray Sep 2, 2026
4089fd0
Add P2 parallel FAT evidence regression coverage
masarray Sep 2, 2026
5b3f68f
Lock P2 per-IED evidence session contract
masarray Sep 2, 2026
345058f
Route runtime snapshots to parallel FAT leaves
masarray Sep 2, 2026
0d16214
Align P2 runtime wiring regression
masarray Sep 2, 2026
02f64bd
Project P2 session state by selected IED
masarray Sep 2, 2026
6451d86
Guard P2 export and close across all IED sessions
masarray Sep 2, 2026
ba56d17
Align P2 regression with selected-context session state
masarray Sep 2, 2026
99ecabe
Keep P2 FAT plan locks scoped to owning IED
masarray Sep 2, 2026
254bc91
Regress P2 per-IED restore and remove locks
masarray Sep 2, 2026
30e1237
Unify Engineering and FAT SCL signal workspace
masarray Sep 3, 2026
f4cdbf7
Modernize shared SCL import workflow
masarray Sep 3, 2026
32a2a90
Separate shared workspace selection from FAT scope
masarray Sep 3, 2026
2c7bfc8
Scope direct SCL acquisition to shared workspace selection
masarray Sep 3, 2026
bada688
Materialize manual SCL selections as FAT workspace rows
masarray Sep 3, 2026
b5b4e3d
Preserve FAT scope during manual workspace selection
masarray Sep 3, 2026
88e6630
Refresh FAT projection after shared workspace mutations
masarray Sep 3, 2026
cccd059
Allow true manual SCL workspace projection into FAT
masarray Sep 3, 2026
ee31457
Preserve Engineering selection in direct SCL FAT preparation
masarray Sep 3, 2026
4c41ee1
Project FAT rows from shared workspace selection
masarray Sep 3, 2026
33fa27f
Keep FAT evidence scope inside shared workspace selection
masarray Sep 3, 2026
eb0c7da
Preflight only shared workspace FAT scope
masarray Sep 3, 2026
d7131af
Make FAT disposition a hard report scope boundary
masarray Sep 3, 2026
20fad32
Exclude removed FAT rows from print preview scope
masarray Sep 3, 2026
5faf31b
Exclude removed rows from every FAT report layout
masarray Sep 3, 2026
8f852e6
Keep selected IED preview identity while filtering at render boundary
masarray Sep 3, 2026
5ad24e2
Use one scoped report contract for PDF and print preview
masarray Sep 3, 2026
009e239
Regress Remove from FAT across testing report boundaries
masarray Sep 3, 2026
fa715ae
Restore shared workspace selection and manual SCL rows on reopen
masarray Sep 3, 2026
22661c2
Regress shared SCL workspace persistence across reopen
masarray Sep 3, 2026
b014c02
Regress Remove from FAT as a hard test and report exclusion
masarray Sep 3, 2026
a4f9ad8
Fix manual workspace projection compile shadowing
masarray Sep 3, 2026
1c3727b
Align partial live regression with shared SCL authority
masarray Sep 3, 2026
8e058f0
Regress Engineering selection as shared workspace authority
masarray Sep 3, 2026
ad0424e
Preserve preflight duplicate contract wording
masarray Sep 3, 2026
5670a82
Align selection authority regression with shared workspace state
masarray Sep 3, 2026
dbe440b
Align P1 regression with shared SCL acquisition authority
masarray Sep 3, 2026
7017208
Persist shared SCL selection and manual row identity
masarray Sep 3, 2026
bb68b42
Align workspace bridge regression with shared selection authority
masarray Sep 3, 2026
f35ffc2
Align workspace mode regression with shared selection authority
masarray Sep 3, 2026
41594ab
P3 add generic FAT value capture provenance and stages
masarray Sep 3, 2026
35f250b
P3 add automatic stable Value 1 and Value 2 capture coordinator
masarray Sep 3, 2026
a1d48a3
P3 make Value 1 and Value 2 effective evidence generic
masarray Sep 3, 2026
514ce75
P3 distinguish operator recapture provenance
masarray Sep 3, 2026
4713074
P3 add auto capture and transactional bulk recapture engine
masarray Sep 3, 2026
bb9f029
P3 route bulk Recapture through isolated IED sessions
masarray Sep 3, 2026
c78fda9
P3 add multi-row selection and Recapture context menu
masarray Sep 3, 2026
dcef256
Preserve full IED precision in FAT snapshot tooltips
masarray Sep 3, 2026
f8fc485
Regress full precision FAT snapshot timestamp tooltips
masarray Sep 3, 2026
00bd100
P3 regress auto capture, transactional Recapture and multi-row UX
masarray Sep 3, 2026
9087e4f
Fix P3 regression fixture init-only identity
masarray Sep 3, 2026
59515ba
Align legacy session tests with P3 capture contract
masarray Sep 3, 2026
8e96f14
Align point-update regression with P3 completion status
masarray Sep 3, 2026
6a201e3
Fix P3 pair journal regression to verify sealed evidence
masarray Sep 3, 2026
f971d2c
Merge pull request #237 from masarray/feat/fat-v2-p5-4-structured-rep…
masarray Sep 3, 2026
a19fa0e
Prevent redundant manual FAT rows for static runtime coverage
masarray Sep 3, 2026
26a0f74
Regress static authority over redundant manual FAT rows
masarray Sep 3, 2026
20499f2
Lock shared workspace runtime dedupe wiring
masarray Sep 3, 2026
f9c2558
Merge FAT shared-workspace duplicate runtime fix
masarray Sep 3, 2026
929a58f
Tune smart reconnect for commissioning cable tests
masarray Sep 3, 2026
d61ce0a
Lock commissioning reconnect timing contract
masarray Sep 3, 2026
cbec859
Bridge FAT events and auto-resume after reconnect
masarray Sep 3, 2026
2192c5b
Keep FAT IED connection badge visible during commissioning
masarray Sep 3, 2026
bf9ca0b
Add FAT commissioning reconnect and event bridge regressions
masarray Sep 3, 2026
54af94e
Fix FAT connection badge helper collision
masarray Sep 3, 2026
78734cc
Fix FAT current evidence assessment authority
masarray Sep 3, 2026
cd36e5d
Use runtime state for current FAT pair assessment
masarray Sep 3, 2026
2910724
Align FAT result with current evidence pair
masarray Sep 3, 2026
ce8d24b
Add FAT current-pair assessment regressions
masarray Sep 3, 2026
1601cd0
Place FAT assessment regressions in test project
masarray Sep 3, 2026
31790c8
Remove misplaced FAT assessment test file
masarray Sep 3, 2026
e41cb54
Preserve reconnect continuity authority for stale auto pairs
masarray Sep 3, 2026
820fbaf
Fail closed when stale auto evidence has no continuity verdict
masarray Sep 3, 2026
4b07626
Make FAT event recovery lossless without double delivery
masarray Sep 3, 2026
0e5c602
Register every FAT evidence controller for reconnect recovery
masarray Sep 3, 2026
038a125
Regress FAT edge capture reconnect and SOE fallback safety
masarray Sep 3, 2026
7ff70be
Merge FAT workspace base after shared-runtime dedupe
masarray Sep 3, 2026
85eae1c
Clarify stale automatic generation review reason
masarray Sep 3, 2026
1dfb963
Merge FAT current evidence assessment
masarray Sep 3, 2026
fb863e9
Revalidate FAT reconnect against current evidence-assessment base
masarray Sep 3, 2026
5b6abaa
Merge FAT commissioning reconnect and evidence recovery
masarray Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/validate-io-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ on:
- "Services/IoTesting/**"
- "tests/ARSAS.Tests/IoTest*"
- "tests/ARSAS.Tests/IoList*"
- "tests/ARSAS.Tests/IoFat*"
- "tests/ARSAS.Tests/FatDataSet*"
- "tests/ARSAS.Tests/FatScl*"
- "engines/ARIEC61850.lock.json"
- ".github/workflows/validate-io-testing.yml"
workflow_dispatch:
Expand Down Expand Up @@ -85,7 +88,7 @@ jobs:
if-no-files-found: error

- name: Run IO testing regression tests
run: dotnet test .\ARSAS\tests\ARSAS.Tests\ARSAS.Tests.csproj -c Release --no-build --no-restore --filter "FullyQualifiedName~IoTest|FullyQualifiedName~IoList" --logger "trx;LogFileName=io-testing-tests.trx" --results-directory .\ARSAS\TestResults
run: dotnet test .\ARSAS\tests\ARSAS.Tests\ARSAS.Tests.csproj -c Release --no-build --no-restore --filter "FullyQualifiedName~IoTest|FullyQualifiedName~IoList|FullyQualifiedName~IoFat|FullyQualifiedName~FatDataSet|FullyQualifiedName~FatScl" --logger "trx;LogFileName=io-testing-tests.trx" --results-directory .\ARSAS\TestResults

- name: Upload IO testing test results
if: always()
Expand Down
4 changes: 2 additions & 2 deletions .release/windows.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"version": "1.6.32",
"version": "1.6.33",
"channel": "stable",
"platform": "windows-x64",
"primaryAsset": "ARSAS-Windows-x64-Setup.exe",
"publicationRequest": 20
"publicationRequest": 21
}
21 changes: 21 additions & 0 deletions App.WindowsIdentity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Runtime.InteropServices;

namespace ArIED61850Tester;

internal static class WindowsApplicationIdentity
{
private const string AppUserModelId = "masarray.ARSAS.IEC61850";

internal static void Apply()
{
if (!OperatingSystem.IsWindows())
return;

// A stable explicit identity makes Windows use the ARSAS executable icon for
// taskbar grouping even when the app was launched by dotnet or a portable host.
_ = SetCurrentProcessExplicitAppUserModelID(AppUserModelId);
}

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern int SetCurrentProcessExplicitAppUserModelID(string appId);
}
1 change: 1 addition & 0 deletions App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public partial class App : Application

protected override void OnStartup(StartupEventArgs e)
{
WindowsApplicationIdentity.Apply();
base.OnStartup(e);

// P2 installs one calm industrial visual system before StartupUri materializes.
Expand Down
6 changes: 3 additions & 3 deletions ArIED61850Tester.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
<Product>ARSAS</Product>
<AssemblyTitle>ARSAS - IEC 61850 Engineering Workstation</AssemblyTitle>
<Description>Open-source Windows IEC 61850 engineering workstation for MMS model discovery, reporting, independent multi-IED monitoring, GOOSE subscription, fault-record file transfer, Sampled Values engineering and evidence export, SCL workflows, diagnostics, sequence of events, and guarded control validation.</Description>
<Version>1.6.32</Version>
<AssemblyVersion>1.6.32.0</AssemblyVersion>
<FileVersion>1.6.32.0</FileVersion>
<Version>1.6.33</Version>
<AssemblyVersion>1.6.33.0</AssemblyVersion>
<FileVersion>1.6.33.0</FileVersion>
<PackageProjectUrl>https://github.com/masarray/arsas</PackageProjectUrl>
<RepositoryUrl>https://github.com/masarray/arsas</RepositoryUrl>
<RepositoryType>git</RepositoryType>
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ Notable public changes to ARSAS are recorded here. Application releases must ide

## Unreleased

## 1.6.33 — 2026-09-02

### Added

- FAT workspaces can import additional CID/SCD/ICD/IID sources without replacing the current project, including while another IED evidence session remains active.
- Engineering and FAT workspaces now share imported SCL signal selection, so operator selection remains consistent when switching modes.

### Fixed

- Direct-SCL FAT connection now reuses the imported model and returns after the MMS association and bounded point setup instead of rediscovering or waiting through the legacy settle path.
- Structured THD current/voltage aggregates and demand-energy values retain exact parent and phase identities and use authoritative MMS projections instead of remaining `Unknown`.
- FAT live updates are coalesced below operator input priority; steady telemetry no longer refreshes the whole collection or schedules autosave for every sample, restoring smooth scrolling and reliable Capture clicks.
- The Add IED action is independent from the active evidence-session edit lock while preserving the running IED's immutable capture mapping.
- Windows receives a stable ARSAS AppUserModelID in addition to the embedded executable icon, fixing generic taskbar grouping for portable and `dotnet`-hosted launches.

## 1.6.31 — 2026-08-15

### Fixed
Expand Down
8 changes: 4 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<Version>1.6.32</Version>
<AssemblyVersion>1.6.32.0</AssemblyVersion>
<FileVersion>1.6.32.0</FileVersion>
<InformationalVersion>1.6.32</InformationalVersion>
<Version>1.6.33</Version>
<AssemblyVersion>1.6.33.0</AssemblyVersion>
<FileVersion>1.6.33.0</FileVersion>
<InformationalVersion>1.6.33</InformationalVersion>
</PropertyGroup>
</Project>
82 changes: 82 additions & 0 deletions IoListTestingWindow.AddIed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System.IO;
using System.Windows;
using ArIED61850Tester.Models.IoTesting;
using ArIED61850Tester.Services.IoTesting;
using Microsoft.Win32;

namespace ArIED61850Tester;

public partial class IoListTestingWindow
{
private async void AddFatIedFromScl_Click(object sender, RoutedEventArgs e)
{
if (!CanAddFatIed || Owner is not MainWindow engineeringWindow)
return;

var dialog = new OpenFileDialog
{
Title = "Add IEC 61850 IED to current FAT workspace",
Filter = "IEC 61850 SCL (*.scd;*.cid;*.icd;*.iid;*.ssd)|*.scd;*.cid;*.icd;*.iid;*.ssd|XML SCL (*.xml)|*.xml|All files (*.*)|*.*",
CheckFileExists = true,
Multiselect = true
};
if (dialog.ShowDialog(this) != true)
return;

var result = await ImportAdditionalSclSourcesAsync(engineeringWindow, dialog.FileNames);
if (!result.Succeeded)
ShowActionResult(result, "IED could not be added");
}

internal async Task<IoTestSessionActionResult> ImportAdditionalSclSourcesAsync(
MainWindow engineeringWindow,
IReadOnlyCollection<string> sclPaths)
{
ArgumentNullException.ThrowIfNull(engineeringWindow);
ArgumentNullException.ThrowIfNull(sclPaths);
if (_isAddingFatIeds)
return IoTestSessionActionResult.Failure("Another SCL append is already being prepared for this FAT workspace.");

SetAddingFatIeds(true);
PreparationStatusText = $"Importing {sclPaths.Count} SCL source(s) into the current FAT workspace…";
try
{
var result = await engineeringWindow.AppendSclIedsToLoadedFatAsync(this, sclPaths);
PreparationStatusText = result.Message;
return result;
}
catch (OperationCanceledException)
{
const string message = "SCL append was cancelled.";
PreparationStatusText = message;
return IoTestSessionActionResult.Failure(message);
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or InvalidDataException or InvalidOperationException or ArgumentException)
{
PreparationStatusText = ex.Message;
return IoTestSessionActionResult.Failure(ex.Message);
}
finally
{
SetAddingFatIeds(false);
}
}

internal void RegisterAddedIeds(IReadOnlyCollection<Models.IoTesting.IoTestIedPlan> addedIeds)
{
Project.InitializeRuntimeNotifications();
foreach (var ied in addedIeds)
{
if (_selectedIedContextInstalled)
ied.PropertyChanged += ContextIed_PropertyChanged;
Storage?.TrackAddedIed(ied);
}

FatIedList.Items.Refresh();
SelectedIed = addedIeds.FirstOrDefault() ?? SelectedIed;
Raise(nameof(ProjectSummary));
RaiseStatusProperties();
RaiseSelectedIedContextProperties();
Storage?.ScheduleSave();
}
}
100 changes: 100 additions & 0 deletions IoListTestingWindow.CommissioningStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using ArIED61850Tester.Models.IoTesting;

namespace ArIED61850Tester;

public partial class IoListTestingWindow
{
private DispatcherTimer? _commissioningConnectionBadgeTimer;

protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
if (_commissioningConnectionBadgeTimer != null)
return;

_commissioningConnectionBadgeTimer = new DispatcherTimer(DispatcherPriority.Background)
{
Interval = TimeSpan.FromMilliseconds(200)
};
_commissioningConnectionBadgeTimer.Tick += CommissioningConnectionBadgeTimer_Tick;
_commissioningConnectionBadgeTimer.Start();
Closed += (_, _) =>
{
if (_commissioningConnectionBadgeTimer == null)
return;
_commissioningConnectionBadgeTimer.Stop();
_commissioningConnectionBadgeTimer.Tick -= CommissioningConnectionBadgeTimer_Tick;
_commissioningConnectionBadgeTimer = null;
};
}

private void CommissioningConnectionBadgeTimer_Tick(object? sender, EventArgs e)
{
foreach (var plan in FatIedList.Items.OfType<IoTestIedPlan>())
{
if (FatIedList.ItemContainerGenerator.ContainerFromItem(plan) is not ListBoxItem container)
continue;

var badge = FindNamedVisual<Border>(container, "StateBadge");
var text = FindNamedVisual<TextBlock>(container, "StateText");
if (badge == null || text == null)
continue;

var state = plan.IsPreparing
? "CONNECTING"
: plan.IsLiveConnected
? "ONLINE"
: plan.IsLiveMonitoring
? "RECONNECTING"
: "OFFLINE";

var palette = state switch
{
"ONLINE" => new BadgePalette("#EAF8F1", "#8FD1B1", "#16845A"),
"RECONNECTING" => new BadgePalette("#FFF8E8", "#E9C46A", "#A56D00"),
"CONNECTING" => new BadgePalette("#EDF3FF", "#9CB8F5", "#315DBF"),
_ => new BadgePalette("#FFF1F2", "#F0B7BC", "#C53A45")
};

// Connection health is independent from FAT PASS/FAIL. A previous XAML
// visibility binding hid StateBadge when all rows passed; a local value here
// intentionally keeps ONLINE / RECONNECTING / OFFLINE visible at all times.
badge.Visibility = Visibility.Visible;
badge.Background = ConnectionBadgeBrushFromHex(palette.Background);
badge.BorderBrush = ConnectionBadgeBrushFromHex(palette.Border);
badge.ToolTip = string.IsNullOrWhiteSpace(plan.LiveStatusText)
? state
: $"{state} · {plan.LiveStatusText}";
text.Text = state;
text.Foreground = ConnectionBadgeBrushFromHex(palette.Foreground);

if (FindNamedVisual<Control>(container, "RelayIcon") is { } relayIcon)
relayIcon.Foreground = ConnectionBadgeBrushFromHex(palette.Foreground);
}
}

private static T? FindNamedVisual<T>(DependencyObject root, string name)
where T : FrameworkElement
{
var count = VisualTreeHelper.GetChildrenCount(root);
for (var index = 0; index < count; index++)
{
var child = VisualTreeHelper.GetChild(root, index);
if (child is T element && element.Name.Equals(name, StringComparison.Ordinal))
return element;
var nested = FindNamedVisual<T>(child, name);
if (nested != null)
return nested;
}
return null;
}

private static Brush ConnectionBadgeBrushFromHex(string value)
=> new SolidColorBrush((Color)ColorConverter.ConvertFromString(value));

private sealed record BadgePalette(string Background, string Border, string Foreground);
}
Loading
Loading