Skip to content

Commit 7241921

Browse files
committed
Handle the transient state of double status point of iec61850.
1 parent 7ed5549 commit 7241921

File tree

4 files changed

+73
-22
lines changed

4 files changed

+73
-22
lines changed

src/libiec61850/dotnet/core/2.0/iec61850_client/AsduReceiveHandler.cs

+58-18
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,26 @@ public class ReptParam
6969
public ReportControlBlock rcb;
7070
}
7171

72-
static Boolean MMSTestDoubleStateFailed(MmsValue mv)
72+
static bool MMSTestDoubleStateFailed(MmsValue mv)
7373
{ // test for double state inconsistent (bitstring of 2 with same values)
7474
return (mv.GetType() == MmsType.MMS_BIT_STRING && mv.Size() == 2 && mv.GetBit(0) == mv.GetBit(1));
7575
}
76+
static bool MMSTestDoubleStateTransient(MmsValue mv)
77+
{ // test for double state inconsistent (bitstring of 2 with same values)
78+
return (mv.GetType() == MmsType.MMS_BIT_STRING && mv.Size() == 2 && mv.GetBit(0) == false && mv.GetBit(1) == false);
79+
}
7680

77-
static Boolean MMSGetQualityFailed(MmsValue mv)
81+
static bool MMSGetQualityFailed(MmsValue mv)
7882
{ // tries to find a qualifier of iec61850 (bitstring) in a mms structure
79-
Boolean f = false;
80-
Boolean found = false;
83+
bool f = false;
84+
bool found = false;
8185
switch (mv.GetType())
8286
{
8387
case MmsType.MMS_STRUCTURE:
8488
for (int i = 0; i < mv.Size(); i++)
85-
if (mv.GetElement(i).GetType() == MmsType.MMS_BIT_STRING)
89+
if (mv.GetElement(i).GetType() == MmsType.MMS_BIT_STRING && mv.GetElement(i).Size() > 2)
8690
{
87-
f = !(mv.GetElement(i).BitStringToUInt32BigEndian() == 0);
91+
f = new Quality((int)mv.GetElement(i).BitStringToUInt32()).GetValidity() != Validity.GOOD;
8892
found = true;
8993
break;
9094
}
@@ -100,11 +104,35 @@ static Boolean MMSGetQualityFailed(MmsValue mv)
100104
}
101105
return f;
102106
}
107+
static bool MMSGetQualityTransient(MmsValue mv)
108+
{ // tries to find a qualifier of iec61850 (bitstring) in a mms structure
109+
bool t = false;
110+
bool found = false;
111+
switch (mv.GetType())
112+
{
113+
case MmsType.MMS_STRUCTURE:
114+
for (int i = 0; i < mv.Size(); i++)
115+
if (mv.Size() == 2 && mv.GetElement(i).GetType() == MmsType.MMS_BIT_STRING)
116+
{
117+
t = mv.GetBit(0) == false && mv.GetBit(1) == false;
118+
found = true;
119+
break;
120+
}
121+
if (!found)
122+
t = MMSGetQualityFailed(mv.GetElement(0));
123+
break;
124+
case MmsType.MMS_BIT_STRING:
125+
if (MMSTestDoubleStateTransient(mv))
126+
t = true;
127+
break;
128+
}
129+
return t;
130+
}
103131

104132
static ulong MMSGetTimestamp(MmsValue mv)
105133
{ // tries to find a timestamp of iec61850 (utc time) in a mms structure, return number of ms UTC
106134
ulong t = 0;
107-
Boolean found = false;
135+
bool found = false;
108136
switch (mv.GetType())
109137
{
110138
case MmsType.MMS_STRUCTURE:
@@ -125,10 +153,10 @@ static ulong MMSGetTimestamp(MmsValue mv)
125153
return t;
126154
}
127155

128-
static Double MMSGetNumericVal(MmsValue mv, out Boolean isBinary)
156+
static Double MMSGetNumericVal(MmsValue mv, out bool isBinary)
129157
{ // tries to find a numeric value of iec61850 (flot, integer, unsigned) in a mms structure
130158
Double v = 0;
131-
Boolean found = false;
159+
bool found = false;
132160
isBinary = false;
133161
switch (mv.GetType())
134162
{
@@ -193,7 +221,7 @@ static Double MMSGetNumericVal(MmsValue mv, out Boolean isBinary)
193221
return v;
194222
}
195223

196-
static Double MMSGetDoubleVal(MmsValue mv, out Boolean isBinary)
224+
static Double MMSGetDoubleVal(MmsValue mv, out bool isBinary)
197225
{ // tries to convert any mms value into a double
198226
Double v = 0;
199227
isBinary = false;
@@ -412,10 +440,11 @@ private static void reportHandler(Report report, object parameter)
412440
log += " Included for reason " + report.GetReasonForInclusion(k).ToString() + " \n";
413441
string tag = entry.js_tag;
414442
var value = values.GetElement(k);
415-
double v;
416-
bool failed;
417-
ulong timestamp;
418-
Boolean isBinary = false;
443+
double v = 0;
444+
bool failed = false;
445+
ulong timestamp = 0;
446+
bool isBinary = false;
447+
bool transient = false;
419448

420449
if (value.GetType() == MmsType.MMS_STRUCTURE)
421450
{
@@ -430,6 +459,7 @@ private static void reportHandler(Report report, object parameter)
430459
}
431460
v = MMSGetNumericVal(value, out isBinary);
432461
failed = MMSGetQualityFailed(value);
462+
transient = MMSGetQualityTransient(value);
433463
timestamp = MMSGetTimestamp(value);
434464

435465
for (int i = 0; i < value.Size(); i++)
@@ -450,6 +480,7 @@ private static void reportHandler(Report report, object parameter)
450480
}
451481
}
452482
failed = MMSGetQualityFailed(value.GetElement(i));
483+
transient = MMSGetQualityTransient(value.GetElement(i));
453484
timestamp = MMSGetTimestamp(value.GetElement(i));
454485
if (value.GetElement(i).GetType() == MmsType.MMS_BIT_STRING)
455486
{
@@ -460,7 +491,7 @@ private static void reportHandler(Report report, object parameter)
460491
if (value.GetElement(i).GetType() == MmsType.MMS_UTC_TIME)
461492
{
462493
if (LogLevel > LogLevelNoLog)
463-
log += " -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset() + "\n";
494+
log += " -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset().ToString("o") + "\n";
464495
}
465496
else
466497
{
@@ -478,6 +509,7 @@ private static void reportHandler(Report report, object parameter)
478509
var iv = new IECValue
479510
{
480511
isDigital = isBinary,
512+
isTransient = transient,
481513
value = v,
482514
valueString = vstr,
483515
valueJson = MMSGetStringValue(value),
@@ -509,7 +541,8 @@ private static void reportHandler(Report report, object parameter)
509541
log += " Value is of simple type " + value.GetType() + " " + v;
510542
}
511543
failed = false;
512-
if (MMSTestDoubleStateFailed(value)) failed = true; // double state inconsistent status
544+
failed = MMSTestDoubleStateFailed(value); // double state inconsistent status
545+
transient = MMSTestDoubleStateTransient(value); // double state inconsistent status
513546
string vstr;
514547
if (isBinary)
515548
vstr = v != 0 ? "true" : "false";
@@ -519,6 +552,7 @@ private static void reportHandler(Report report, object parameter)
519552
var iv = new IECValue
520553
{
521554
isDigital = isBinary,
555+
isTransient = transient,
522556
value = v,
523557
valueString = vstr,
524558
valueJson = MMSGetStringValue(value),
@@ -848,6 +882,7 @@ static void Process(Iec61850Connection srv)
848882
var tp = value.GetType();
849883
double v = 0;
850884
bool failed = false;
885+
bool transient = false;
851886
ulong timestamp = 0;
852887
bool isBinary = false;
853888

@@ -857,6 +892,7 @@ static void Process(Iec61850Connection srv)
857892
if (LogLevel >= LogLevelDetailed) log += "\n Value is of complex type \n";
858893
v = MMSGetNumericVal(value, out isBinary);
859894
failed = MMSGetQualityFailed(value);
895+
transient = MMSGetQualityTransient(value);
860896
timestamp = MMSGetTimestamp(value);
861897

862898
for (int i = 0; i < value.Size(); i++)
@@ -874,6 +910,7 @@ static void Process(Iec61850Connection srv)
874910
}
875911
}
876912
failed = MMSGetQualityFailed(value.GetElement(i));
913+
transient = MMSGetQualityTransient(value.GetElement(i));
877914
timestamp = MMSGetTimestamp(value.GetElement(i));
878915
if (value.GetElement(i).GetType() == MmsType.MMS_BIT_STRING)
879916
{
@@ -882,7 +919,7 @@ static void Process(Iec61850Connection srv)
882919
else
883920
if (value.GetElement(i).GetType() == MmsType.MMS_UTC_TIME)
884921
{
885-
if (LogLevel >= LogLevelDetailed) log += " -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset() + "\n";
922+
if (LogLevel >= LogLevelDetailed) log += " -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset().ToString("o") + "\n";
886923
}
887924
else
888925
{
@@ -899,6 +936,7 @@ static void Process(Iec61850Connection srv)
899936
var iv = new IECValue
900937
{
901938
isDigital = isBinary,
939+
isTransient = transient,
902940
value = v,
903941
valueString = vstr,
904942
valueJson = MMSGetStringValue(value),
@@ -922,7 +960,8 @@ static void Process(Iec61850Connection srv)
922960
else
923961
{
924962
v = MMSGetDoubleVal(value, out isBinary);
925-
if (MMSTestDoubleStateFailed(value)) failed = true; // double state inconsistent status
963+
failed = MMSTestDoubleStateFailed(value); // double state inconsistent status
964+
transient = MMSTestDoubleStateTransient(value); // double state inconsistent status
926965
string vstr;
927966
if (isBinary)
928967
vstr = v != 0 ? "true" : "false";
@@ -932,6 +971,7 @@ static void Process(Iec61850Connection srv)
932971
var iv = new IECValue
933972
{
934973
isDigital = isBinary,
974+
isTransient = transient,
935975
value = v,
936976
valueString = vstr,
937977
valueJson = MMSGetStringValue(value),

src/libiec61850/dotnet/core/2.0/iec61850_client/Common_srv_cli.cs

+1
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ public struct IECValue
167167
public string address;
168168
public string asdu;
169169
public bool isDigital;
170+
public bool isTransient;
170171
public double value;
171172
public string valueString;
172173
public int cot;

src/libiec61850/dotnet/core/2.0/iec61850_client/Main.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ partial class MainClass
3535
{
3636
public static String CopyrightMessage = "{json:scada} IEC61850 Client Driver - Copyright 2023 - 2024 Ricardo Olsen";
3737
public static String ProtocolDriverName = "IEC61850";
38-
public static String DriverVersion = "0.1.7";
38+
public static String DriverVersion = "0.1.8";
3939
public static bool Active = false; // indicates this driver instance is the active node in the moment
4040
public static Int32 DataBufferLimit = 20000; // limit to start dequeuing and discarding data from the acquisition buffer
4141
public static Int32 BulkWriteLimit = 1250; // limit of each bulk write to mongodb
@@ -61,6 +61,7 @@ public static void Main(string[] args)
6161
if (res) LogLevel = num;
6262
}
6363
Log(CopyrightMessage + " Version " + DriverVersion);
64+
Log("Using libiec61850 v" + LibIEC61850.GetVersionString());
6465
Log("Log level: " + LogLevel);
6566

6667
string fname = JsonConfigFilePath;
@@ -123,8 +124,7 @@ public static void Main(string[] args)
123124
.Find(inst =>
124125
inst.protocolDriver == ProtocolDriverName &&
125126
inst.protocolDriverInstanceNumber ==
126-
ProtocolDriverInstanceNumber &&
127-
inst.enabled == true)
127+
ProtocolDriverInstanceNumber)
128128
.ToList();
129129
var foundInstance = false;
130130
foreach (protocolDriverInstancesClass inst in instances)

src/libiec61850/dotnet/core/2.0/iec61850_client/MongoUpdate.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,17 @@ static public async void ProcessMongo(JSONSCADAConfig jsConfig)
224224
"substitutedAtSource",
225225
BsonBoolean
226226
.Create(false)
227-
}
227+
},
228+
{
229+
"transientAtSource",
230+
BsonBoolean
231+
.Create(iv.isTransient)
232+
},
233+
{
234+
"originator",
235+
BsonValue
236+
.Create(ProtocolDriverName + "|" + iv.conn_number )
237+
},
228238
}
229239
}
230240
}

0 commit comments

Comments
 (0)