You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
827 lines
27 KiB
C#
827 lines
27 KiB
C#
/*
|
|
* IEC61850CommonAPI.cs
|
|
*
|
|
* Copyright 2014-2025 Michael Zillgith
|
|
*
|
|
* This file is part of libIEC61850.
|
|
*
|
|
* libIEC61850 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* libIEC61850 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* See COPYING file for the complete license text.
|
|
*/
|
|
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace IEC61850
|
|
{
|
|
namespace Common
|
|
{
|
|
|
|
public enum Iec61850Edition : byte
|
|
{
|
|
EDITION_1 = 0,
|
|
EDITION_2 = 1,
|
|
EDITION_2_1 = 2
|
|
}
|
|
|
|
public class LibIEC61850
|
|
{
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern IntPtr LibIEC61850_getVersionString();
|
|
|
|
/// <summary>
|
|
/// Get the version string of the native libiec61850 library
|
|
/// </summary>
|
|
/// <returns>The version string in format MAJOR.MINOR.PATCH</returns>
|
|
public static string GetVersionString()
|
|
{
|
|
return Marshal.PtrToStringAnsi(LibIEC61850_getVersionString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts millisecond timestamp to a DateTime object
|
|
/// </summary>
|
|
/// <returns>The DateTime object representing the value of the timestamp</returns>
|
|
/// <param name="msTime">The timestamp in milliseconds since epoch (UTC)</param>
|
|
public static DateTime MsTimestampToDateTime(ulong msTime)
|
|
{
|
|
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
|
|
|
ulong seconds = msTime / 1000;
|
|
ulong millies = msTime % 1000;
|
|
|
|
dateTime.AddSeconds(seconds);
|
|
dateTime.AddMilliseconds(millies);
|
|
|
|
return dateTime;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts a DateTime object in milliseconds since epoch timestamp (UTC)
|
|
/// </summary>
|
|
/// <returns>The timestamp in ms</returns>
|
|
/// <param name="msTime">The DateTime object to convert</param>
|
|
public static ulong DateTimeToMsTimestamp(DateTime dateTime)
|
|
{
|
|
return (ulong)(dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds);
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public class PhyComAddress
|
|
{
|
|
public byte vlanPriority;
|
|
public UInt16 vlanId;
|
|
public UInt16 appId;
|
|
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
|
public byte[] dstAddress = new byte[6];
|
|
}
|
|
|
|
/// <summary>
|
|
/// MMS data access error for MmsValue type MMS_DATA_ACCESS_ERROR
|
|
/// </summary>
|
|
public enum MmsDataAccessError
|
|
{
|
|
NO_RESPONSE = -2, /* for server internal purposes only! */
|
|
SUCCESS = -1,
|
|
OBJECT_INVALIDATED = 0,
|
|
HARDWARE_FAULT = 1,
|
|
TEMPORARILY_UNAVAILABLE = 2,
|
|
OBJECT_ACCESS_DENIED = 3,
|
|
OBJECT_UNDEFINED = 4,
|
|
INVALID_ADDRESS = 5,
|
|
TYPE_UNSUPPORTED = 6,
|
|
TYPE_INCONSISTENT = 7,
|
|
OBJECT_ATTRIBUTE_INCONSISTENT = 8,
|
|
OBJECT_ACCESS_UNSUPPORTED = 9,
|
|
OBJECT_NONE_EXISTENT = 10,
|
|
OBJECT_VALUE_INVALID = 11,
|
|
UNKNOWN = 12,
|
|
}
|
|
|
|
[Flags]
|
|
public enum TriggerOptions
|
|
{
|
|
NONE = 0,
|
|
/** send report when value of data changed */
|
|
DATA_CHANGED = 1,
|
|
/** send report when quality of data changed */
|
|
QUALITY_CHANGED = 2,
|
|
/** send report when data or quality is updated */
|
|
DATA_UPDATE = 4,
|
|
/** periodic transmission of all data set values */
|
|
INTEGRITY = 8,
|
|
/** general interrogation (on client request) */
|
|
GI = 16,
|
|
/** Report will be triggered only on rising edge (transient variable) */
|
|
TRG_OPT_TRANSIENT = 128
|
|
}
|
|
|
|
/// <summary>
|
|
/// SmpMod values
|
|
/// </summary>
|
|
public enum SmpMod
|
|
{
|
|
SAMPLES_PER_PERIOD = 0,
|
|
SAMPLES_PER_SECOND = 1,
|
|
SECONDS_PER_SAMPLE = 2
|
|
}
|
|
|
|
/// <summary>
|
|
/// Values for Sampled Values (SV) OptFlds
|
|
/// </summary>
|
|
[Flags]
|
|
public enum SVOptions
|
|
{
|
|
NONE = 0,
|
|
REFRESH_TIME = 1,
|
|
SAMPLE_SYNC = 2,
|
|
SAMPLE_RATE = 4,
|
|
DATA_SET = 8,
|
|
SECURITY = 16,
|
|
ALL = 31
|
|
}
|
|
|
|
[Flags]
|
|
public enum ReportOptions
|
|
{
|
|
NONE = 0,
|
|
SEQ_NUM = 1,
|
|
TIME_STAMP = 2,
|
|
REASON_FOR_INCLUSION = 4,
|
|
DATA_SET = 8,
|
|
DATA_REFERENCE = 16,
|
|
BUFFER_OVERFLOW = 32,
|
|
ENTRY_ID = 64,
|
|
CONF_REV = 128,
|
|
SEGMENTATION = 256,
|
|
ALL = SEQ_NUM | TIME_STAMP | REASON_FOR_INCLUSION | DATA_SET | DATA_REFERENCE |
|
|
BUFFER_OVERFLOW | ENTRY_ID | CONF_REV | SEGMENTATION
|
|
}
|
|
|
|
public enum Validity
|
|
{
|
|
GOOD = 0,
|
|
RESERVED = 1,
|
|
INVALID = 2,
|
|
QUESTIONABLE = 3
|
|
}
|
|
|
|
/// <summary>
|
|
/// The quality of a data object.
|
|
/// </summary>
|
|
public class Quality
|
|
{
|
|
private UInt16 value;
|
|
|
|
private const UInt16 QUALITY_DETAIL_OVERFLOW = 4;
|
|
private const UInt16 QUALITY_DETAIL_OUT_OF_RANGE = 8;
|
|
private const UInt16 QUALITY_DETAIL_BAD_REFERENCE = 16;
|
|
private const UInt16 QUALITY_DETAIL_OSCILLATORY = 32;
|
|
private const UInt16 QUALITY_DETAIL_FAILURE = 64;
|
|
private const UInt16 QUALITY_DETAIL_OLD_DATA = 128;
|
|
private const UInt16 QUALITY_DETAIL_INCONSISTENT = 256;
|
|
private const UInt16 QUALITY_DETAIL_INACCURATE = 512;
|
|
private const UInt16 QUALITY_SOURCE_SUBSTITUTED = 1024;
|
|
private const UInt16 QUALITY_TEST = 2048;
|
|
private const UInt16 QUALITY_OPERATOR_BLOCKED = 4096;
|
|
private const UInt16 QUALITY_DERIVED = 8192;
|
|
|
|
public ushort Value => value;
|
|
|
|
public override string ToString()
|
|
{
|
|
return GetValidity().ToString();
|
|
|
|
}
|
|
|
|
public Quality(int bitStringValue)
|
|
{
|
|
value = (UInt16)bitStringValue;
|
|
}
|
|
|
|
public Quality()
|
|
{
|
|
value = 0;
|
|
}
|
|
|
|
public Validity GetValidity()
|
|
{
|
|
int qualityVal = value & 0x3;
|
|
|
|
return (Validity)qualityVal;
|
|
}
|
|
|
|
public void SetValidity(Validity validity)
|
|
{
|
|
value = (UInt16)(value & 0xfffc);
|
|
|
|
value += (ushort)validity;
|
|
}
|
|
|
|
public Validity Validity
|
|
{
|
|
get { return GetValidity(); }
|
|
set { SetValidity(value); }
|
|
}
|
|
|
|
public bool Overflow
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_OVERFLOW) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_OVERFLOW;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_OVERFLOW));
|
|
}
|
|
}
|
|
|
|
public bool OutOfRange
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_OUT_OF_RANGE) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_OUT_OF_RANGE;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_OUT_OF_RANGE));
|
|
}
|
|
}
|
|
|
|
public bool BadReference
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_BAD_REFERENCE) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_BAD_REFERENCE;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_BAD_REFERENCE));
|
|
}
|
|
}
|
|
|
|
public bool Oscillatory
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_OSCILLATORY) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_OSCILLATORY;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_OSCILLATORY));
|
|
}
|
|
}
|
|
|
|
public bool Failure
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_FAILURE) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_FAILURE;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_FAILURE));
|
|
}
|
|
}
|
|
|
|
public bool OldData
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_OLD_DATA) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_OLD_DATA;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_OLD_DATA));
|
|
}
|
|
}
|
|
|
|
public bool Inconsistent
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_INCONSISTENT) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_INCONSISTENT;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_INCONSISTENT));
|
|
}
|
|
}
|
|
|
|
public bool Inaccurate
|
|
{
|
|
get { return ((value & QUALITY_DETAIL_INACCURATE) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DETAIL_INACCURATE;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DETAIL_INACCURATE));
|
|
}
|
|
}
|
|
|
|
public bool Substituted
|
|
{
|
|
get { return ((value & QUALITY_SOURCE_SUBSTITUTED) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_SOURCE_SUBSTITUTED;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_SOURCE_SUBSTITUTED));
|
|
}
|
|
}
|
|
|
|
public bool Test
|
|
{
|
|
get { return ((value & QUALITY_TEST) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_TEST;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_TEST));
|
|
}
|
|
}
|
|
|
|
public bool OperatorBlocked
|
|
{
|
|
get { return ((value & QUALITY_OPERATOR_BLOCKED) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_OPERATOR_BLOCKED;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_OPERATOR_BLOCKED));
|
|
}
|
|
}
|
|
|
|
public bool Derived
|
|
{
|
|
get { return ((value & QUALITY_DERIVED) != 0); }
|
|
set
|
|
{
|
|
if (value)
|
|
this.value |= QUALITY_DERIVED;
|
|
else
|
|
this.value = (ushort)(this.value & (~QUALITY_DERIVED));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Timestamp (represents IEC 61850 timestamps e.g. "t" attribute)
|
|
/// </summary>
|
|
public class Timestamp
|
|
{
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern IntPtr Timestamp_create();
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern IntPtr Timestamp_createFromByteArray(byte[] byteArry);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_destroy(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_clearFlags(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.I1)]
|
|
static extern bool Timestamp_isLeapSecondKnown(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setLeapSecondKnown(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.I1)]
|
|
static extern bool Timestamp_hasClockFailure(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setClockFailure(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
[return: MarshalAs(UnmanagedType.I1)]
|
|
static extern bool Timestamp_isClockNotSynchronized(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setClockNotSynchronized(IntPtr self, [MarshalAs(UnmanagedType.I1)] bool value);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern int Timestamp_getSubsecondPrecision(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setSubsecondPrecision(IntPtr self, int subsecondPrecision);
|
|
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setTimeInSeconds(IntPtr self, UInt32 secondsSinceEpoch);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setTimeInMilliseconds(IntPtr self, UInt64 millisSinceEpoch);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern UInt32 Timestamp_getTimeInSeconds(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern UInt64 Timestamp_getTimeInMs(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setByMmsUtcTime(IntPtr self, IntPtr mmsValue);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern UInt32 Timestamp_getFractionOfSecondPart(IntPtr self);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern void Timestamp_setFractionOfSecondPart(IntPtr self, UInt32 fractionOfSecond);
|
|
|
|
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
|
|
static extern float Timestamp_getFractionOfSecond(IntPtr self);
|
|
|
|
internal IntPtr self = IntPtr.Zero;
|
|
private bool responsibleForDeletion;
|
|
|
|
internal Timestamp(IntPtr timestampRef, bool selfAllocated)
|
|
{
|
|
self = timestampRef;
|
|
responsibleForDeletion = selfAllocated;
|
|
}
|
|
|
|
public Timestamp(DateTime timestamp) : this()
|
|
{
|
|
SetDateTime(timestamp);
|
|
}
|
|
|
|
public Timestamp(MmsValue mmsUtcTime) : this()
|
|
{
|
|
SetByMmsUtcTime(mmsUtcTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="IEC61850CommonAPI.Timestamp"/> class.
|
|
/// </summary>
|
|
public Timestamp()
|
|
{
|
|
self = Timestamp_create();
|
|
LeapSecondKnown = true;
|
|
responsibleForDeletion = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="IEC61850CommonAPI.Timestamp"/> class.
|
|
/// </summary>
|
|
public Timestamp(Timestamp other) : this()
|
|
{
|
|
SetTimeInSeconds(other.GetTimeInSeconds());
|
|
SetSubsecondPrecision(other.GetSubsecondPrecision());
|
|
SetFractionOfSecondPart(other.GetFractionOfSecondPart());
|
|
SetLeapSecondKnow(other.IsLeapSecondKnown());
|
|
SetClockFailure(other.HasClockFailure());
|
|
SetClockNotSynchronized(other.IsClockNotSynchronized());
|
|
}
|
|
|
|
public Timestamp(byte[] value)
|
|
{
|
|
self = Timestamp_createFromByteArray(value);
|
|
responsibleForDeletion = true;
|
|
}
|
|
|
|
~Timestamp()
|
|
{
|
|
if (responsibleForDeletion)
|
|
Timestamp_destroy(self);
|
|
}
|
|
|
|
public void ClearFlags()
|
|
{
|
|
Timestamp_clearFlags(self);
|
|
}
|
|
|
|
public void SetDateTime(DateTime timestamp)
|
|
{
|
|
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
DateTime timestampUTC = timestamp.ToUniversalTime();
|
|
|
|
TimeSpan timeDiff = timestampUTC - epoch;
|
|
ulong timeVal = Convert.ToUInt64(timeDiff.TotalMilliseconds);
|
|
|
|
SetTimeInMilliseconds(timeVal);
|
|
}
|
|
|
|
public bool LeapSecondKnown
|
|
{
|
|
get { return IsLeapSecondKnown(); }
|
|
set { SetLeapSecondKnow(value); }
|
|
}
|
|
|
|
public bool IsLeapSecondKnown()
|
|
{
|
|
return Timestamp_isLeapSecondKnown(self);
|
|
}
|
|
|
|
public void SetLeapSecondKnow(bool value)
|
|
{
|
|
Timestamp_setLeapSecondKnown(self, value);
|
|
}
|
|
|
|
public bool ClockFailure
|
|
{
|
|
get { return HasClockFailure(); }
|
|
set { SetClockFailure(value); }
|
|
}
|
|
|
|
public bool HasClockFailure()
|
|
{
|
|
return Timestamp_hasClockFailure(self);
|
|
}
|
|
|
|
public void SetClockFailure(bool value)
|
|
{
|
|
Timestamp_setClockFailure(self, value);
|
|
}
|
|
|
|
public bool ClockNotSynchronized
|
|
{
|
|
get { return IsClockNotSynchronized(); }
|
|
set { SetClockNotSynchronized(value); }
|
|
}
|
|
|
|
public bool IsClockNotSynchronized()
|
|
{
|
|
return Timestamp_isClockNotSynchronized(self);
|
|
}
|
|
|
|
public void SetClockNotSynchronized(bool value)
|
|
{
|
|
Timestamp_setClockNotSynchronized(self, value);
|
|
}
|
|
|
|
public int SubsecondPrecision
|
|
{
|
|
get { return GetSubsecondPrecision(); }
|
|
set { SetSubsecondPrecision(value); }
|
|
}
|
|
|
|
public int GetSubsecondPrecision()
|
|
{
|
|
return Timestamp_getSubsecondPrecision(self);
|
|
}
|
|
|
|
public void SetSubsecondPrecision(int subsecondPrecision)
|
|
{
|
|
Timestamp_setSubsecondPrecision(self, subsecondPrecision);
|
|
}
|
|
|
|
public UInt32 TimeInSeconds
|
|
{
|
|
get { return GetTimeInSeconds(); }
|
|
set { SetTimeInSeconds(value); }
|
|
}
|
|
|
|
public UInt32 GetTimeInSeconds()
|
|
{
|
|
return Timestamp_getTimeInSeconds(self);
|
|
}
|
|
|
|
public void SetTimeInSeconds(UInt32 secondsSinceEpoch)
|
|
{
|
|
Timestamp_setTimeInSeconds(self, secondsSinceEpoch);
|
|
}
|
|
|
|
public UInt64 TimeInMilliseconds
|
|
{
|
|
get { return GetTimeInMilliseconds(); }
|
|
set { SetTimeInMilliseconds(value); }
|
|
}
|
|
|
|
public UInt64 GetTimeInMilliseconds()
|
|
{
|
|
return Timestamp_getTimeInMs(self);
|
|
}
|
|
|
|
public void SetTimeInMilliseconds(UInt64 millisSinceEpoch)
|
|
{
|
|
Timestamp_setTimeInMilliseconds(self, millisSinceEpoch);
|
|
}
|
|
|
|
public void SetByMmsUtcTime(MmsValue mmsValue)
|
|
{
|
|
Timestamp_setByMmsUtcTime(self, mmsValue.valueReference);
|
|
}
|
|
|
|
public DateTime AsDateTime()
|
|
{
|
|
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
|
|
DateTime retVal = epoch.AddMilliseconds(GetTimeInMilliseconds());
|
|
|
|
return retVal;
|
|
}
|
|
|
|
public UInt32 GetFractionOfSecondPart()
|
|
{
|
|
return Timestamp_getFractionOfSecondPart(self);
|
|
}
|
|
|
|
public void SetFractionOfSecondPart(UInt32 fractionOfSecond)
|
|
{
|
|
Timestamp_setFractionOfSecondPart(self, fractionOfSecond);
|
|
}
|
|
|
|
public float GetFractionOfSecond()
|
|
{
|
|
return Timestamp_getFractionOfSecond(self);
|
|
}
|
|
|
|
}
|
|
|
|
public enum ACSIClass
|
|
{
|
|
/** data objects */
|
|
ACSI_CLASS_DATA_OBJECT,
|
|
/** data sets (container for multiple data objects) */
|
|
ACSI_CLASS_DATA_SET,
|
|
/** buffered report control blocks */
|
|
ACSI_CLASS_BRCB,
|
|
/** unbuffered report control blocks */
|
|
ACSI_CLASS_URCB,
|
|
/** log control blocks */
|
|
ACSI_CLASS_LCB,
|
|
/** logs (journals) */
|
|
ACSI_CLASS_LOG,
|
|
/** setting group control blocks */
|
|
ACSI_CLASS_SGCB,
|
|
/** GOOSE control blocks */
|
|
ACSI_CLASS_GoCB,
|
|
/** GSE control blocks */
|
|
ACSI_CLASS_GsCB,
|
|
/** multicast sampled values control blocks */
|
|
ACSI_CLASS_MSVCB,
|
|
/** unicast sampled values control blocks */
|
|
ACSI_CLASS_USVCB
|
|
}
|
|
|
|
public enum FunctionalConstraint
|
|
{
|
|
/** Status information */
|
|
ST = 0,
|
|
/** Measurands - analog values */
|
|
MX = 1,
|
|
/** Setpoint */
|
|
SP = 2,
|
|
/** Substitution */
|
|
SV = 3,
|
|
/** Configuration */
|
|
CF = 4,
|
|
/** Description */
|
|
DC = 5,
|
|
/** Setting group */
|
|
SG = 6,
|
|
/** Setting group editable */
|
|
SE = 7,
|
|
/** Service response / Service tracking */
|
|
SR = 8,
|
|
/** Operate received */
|
|
OR = 9,
|
|
/** Blocking */
|
|
BL = 10,
|
|
/** Extended definition */
|
|
EX = 11,
|
|
/** Control */
|
|
CO = 12,
|
|
/** Unicast SV */
|
|
US = 13,
|
|
/** Multicast SV */
|
|
MS = 14,
|
|
/** Unbuffered report */
|
|
RP = 15,
|
|
/** Buffered report */
|
|
BR = 16,
|
|
/** Log control blocks */
|
|
LG = 17,
|
|
|
|
/** All FCs - wildcard value */
|
|
ALL = 99,
|
|
NONE = -1
|
|
}
|
|
|
|
/// <summary>
|
|
/// Definition for LastAppError error type for control models
|
|
/// Used in LastApplError and CommandTermination messages.
|
|
/// </summary>
|
|
public enum ControlLastApplError
|
|
{
|
|
NO_ERROR = 0,
|
|
UNKNOWN = 1,
|
|
TIMEOUT_TEST = 2,
|
|
OPERATOR_TEST = 3
|
|
}
|
|
|
|
/// <summary>
|
|
/// AddCause - additional cause information for control model errors
|
|
/// Used in LastApplError and CommandTermination messages.
|
|
/// </summary>
|
|
public enum ControlAddCause
|
|
{
|
|
ADD_CAUSE_UNKNOWN = 0,
|
|
ADD_CAUSE_NOT_SUPPORTED = 1,
|
|
ADD_CAUSE_BLOCKED_BY_SWITCHING_HIERARCHY = 2,
|
|
ADD_CAUSE_SELECT_FAILED = 3,
|
|
ADD_CAUSE_INVALID_POSITION = 4,
|
|
ADD_CAUSE_POSITION_REACHED = 5,
|
|
ADD_CAUSE_PARAMETER_CHANGE_IN_EXECUTION = 6,
|
|
ADD_CAUSE_STEP_LIMIT = 7,
|
|
ADD_CAUSE_BLOCKED_BY_MODE = 8,
|
|
ADD_CAUSE_BLOCKED_BY_PROCESS = 9,
|
|
ADD_CAUSE_BLOCKED_BY_INTERLOCKING = 10,
|
|
ADD_CAUSE_BLOCKED_BY_SYNCHROCHECK = 11,
|
|
ADD_CAUSE_COMMAND_ALREADY_IN_EXECUTION = 12,
|
|
ADD_CAUSE_BLOCKED_BY_HEALTH = 13,
|
|
ADD_CAUSE_1_OF_N_CONTROL = 14,
|
|
ADD_CAUSE_ABORTION_BY_CANCEL = 15,
|
|
ADD_CAUSE_TIME_LIMIT_OVER = 16,
|
|
ADD_CAUSE_ABORTION_BY_TRIP = 17,
|
|
ADD_CAUSE_OBJECT_NOT_SELECTED = 18,
|
|
ADD_CAUSE_OBJECT_ALREADY_SELECTED = 19,
|
|
ADD_CAUSE_NO_ACCESS_AUTHORITY = 20,
|
|
ADD_CAUSE_ENDED_WITH_OVERSHOOT = 21,
|
|
ADD_CAUSE_ABORTION_DUE_TO_DEVIATION = 22,
|
|
ADD_CAUSE_ABORTION_BY_COMMUNICATION_LOSS = 23,
|
|
ADD_CAUSE_ABORTION_BY_COMMAND = 24,
|
|
ADD_CAUSE_NONE = 25,
|
|
ADD_CAUSE_INCONSISTENT_PARAMETERS = 26,
|
|
ADD_CAUSE_LOCKED_BY_OTHER_CLIENT = 27
|
|
}
|
|
|
|
/// <summary>
|
|
/// Object reference. Helper function to handle object reference strings.
|
|
/// </summary>
|
|
public static class ObjectReference
|
|
{
|
|
|
|
/// <summary>
|
|
/// Get the name part of an object reference with appended FC
|
|
/// </summary>
|
|
/// <returns>
|
|
/// The element name.
|
|
/// </returns>
|
|
/// <param name='objectReferenceWithFc'>
|
|
/// Object reference with appended fc.
|
|
/// </param>
|
|
public static string getElementName(string objectReferenceWithFc)
|
|
{
|
|
int fcPartStartIndex = objectReferenceWithFc.IndexOf('[');
|
|
|
|
if (fcPartStartIndex == -1)
|
|
return objectReferenceWithFc;
|
|
|
|
return objectReferenceWithFc.Substring(0, fcPartStartIndex);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the FC of an object reference with appended FC.
|
|
/// </summary>
|
|
/// <returns>
|
|
/// The FC
|
|
/// </returns>
|
|
/// <param name='objectReferenceWithFc'>
|
|
/// Object reference with FC.
|
|
/// </param>
|
|
public static FunctionalConstraint getFC(string objectReferenceWithFc)
|
|
{
|
|
int fcPartStartIndex = objectReferenceWithFc.IndexOf('[');
|
|
|
|
if (fcPartStartIndex == -1)
|
|
return FunctionalConstraint.NONE;
|
|
|
|
string fcString = objectReferenceWithFc.Substring(fcPartStartIndex + 1, 2);
|
|
|
|
try
|
|
{
|
|
return (FunctionalConstraint)Enum.Parse(typeof(FunctionalConstraint), fcString);
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
return FunctionalConstraint.NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|