Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 22 additions & 1 deletion Services/Iec61850StaticControlStatusProjectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ public static Iec61850StaticControlStatusProjectionResult EnsureProjections(Iec6
LiteralEquals(signal.DisplayReference, memberReference) &&
LiteralEquals(signal.ObjectReference, exactFeedbackReference));
if (existingFeedback is not null)
{
PromoteRuntimeFeedbackSemantics(existingFeedback, descriptor, cdc);
continue;
}

var feedback = CreateRuntimeFeedback(
descriptor,
Expand All @@ -161,6 +164,11 @@ public static Iec61850StaticControlStatusProjectionResult EnsureProjections(Iec6
internal static bool IsControllableCdc(string? cdc)
=> ControllableCdcs.Contains((cdc ?? string.Empty).Trim());

internal static string ResolveRuntimeFeedbackDataType(string? cdc, string? mmsType, string? sclBType)
=> string.Equals((cdc ?? string.Empty).Trim(), "DPC", StringComparison.OrdinalIgnoreCase)
? "Dbpos"
: FirstNonEmpty(mmsType, sclBType, "Unknown");

private static string ResolveExactFeedbackReference(
Iec61850SignalDescriptor descriptor,
Iec61850SignalDataSetMembership membership)
Expand Down Expand Up @@ -299,7 +307,7 @@ private static SignalDefinition CreateRuntimeFeedback(
ObjectReference = exactFeedbackReference,
DisplayReference = memberReference,
FunctionalConstraint = fc,
DataType = FirstNonEmpty(descriptor.MmsType, descriptor.SclBType, "Unknown"),
DataType = ResolveRuntimeFeedbackDataType(cdc, descriptor.MmsType, descriptor.SclBType),
Category = category,
Confidence = "High",
DataSetReference = membership.DataSetReference,
Expand All @@ -322,6 +330,19 @@ private static SignalDefinition CreateRuntimeFeedback(
};
}

private static void PromoteRuntimeFeedbackSemantics(
SignalDefinition feedback,
Iec61850SignalDescriptor descriptor,
string cdc)
{
var semanticType = ResolveRuntimeFeedbackDataType(cdc, descriptor.MmsType, descriptor.SclBType);
if (semanticType.Equals("Dbpos", StringComparison.OrdinalIgnoreCase))
{
feedback.DataType = semanticType;
feedback.Category = "Position";
}
}

private static Iec61850StaticControlStatusProjectionResult EmptyResult()
=> new(Array.Empty<SignalDefinition>(), 0);

Expand Down
4 changes: 2 additions & 2 deletions landing/release-notes.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
"summaryId": "ARSAS 1.6.37 adalah stable release Windows terverifikasi terbaru. Identitas paket, link download, checksum, dan publication evidence disinkronkan otomatis dari GitHub Release bertag.",
"highlights": [
"fix(v1.6.36): smooth COMTRADE scrub presentation at display cadence",
"fix(v1.6.36): match IEDScout RCB instances and source export identity",
"fix(v1.6.36): match live RCB instances and source export identity",
"COMTRADE: smooth scrubbing across analysis workspaces",
"Release convergence: promote field-tested v1.6.36 trial fixes to main",
"docs: synchronize documentation and landing with ARSAS 1.6.37"
],
"highlightsId": [
"Perubahan rilis: fix(v1.6.36): smooth COMTRADE scrub presentation at display cadence",
"Perubahan rilis: fix(v1.6.36): match IEDScout RCB instances and source export identity",
"Perubahan rilis: fix(v1.6.36): match live RCB instances and source export identity",
"Perubahan rilis: COMTRADE: smooth scrubbing across analysis workspaces",
"Perubahan rilis: Release convergence: promote field-tested v1.6.36 trial fixes to main",
"Dokumentasi: synchronize documentation and landing with ARSAS 1.6.37"
Expand Down
34 changes: 34 additions & 0 deletions tests/ARSAS.Tests/Iec61850ValueFormatterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,38 @@ public void Format_Does_Not_Collapse_NonStVal_Structures()

Assert.Equal(value, formatted);
}

[Theory]
[InlineData("off", "Open [01]")]
[InlineData("on", "Closed [10]")]
[InlineData("00", "Intermediate [00]")]
[InlineData("11", "Bad state [11]")]
public void Format_Preserves_Dpc_Process_Semantics_For_Report_Values(string raw, string expected)
{
var formatted = Iec61850ValueFormatter.Format(raw, "Dbpos", string.Empty);

Assert.Equal(expected, formatted);
}

[Fact]
public void StaticControlProjection_Dpc_Overrides_LowLevel_Boolean_With_Dbpos()
{
var dataType = Iec61850StaticControlStatusProjectionService.ResolveRuntimeFeedbackDataType(
"DPC",
"Boolean",
"BOOLEAN");

Assert.Equal("Dbpos", dataType);
}

[Fact]
public void StaticControlProjection_NonDpc_Retains_LowLevel_Type()
{
var dataType = Iec61850StaticControlStatusProjectionService.ResolveRuntimeFeedbackDataType(
"SPC",
"Boolean",
"BOOLEAN");

Assert.Equal("Boolean", dataType);
}
}
Loading