< Summary - pva.SuperV

Information
Class: pva.SuperV.Engine.Processing.AlarmStateProcessing<T>
Assembly: pva.SuperV.Engine
File(s): /home/runner/work/pva.SuperV/pva.SuperV/pva.SuperV.Engine/Processing/AlarmStateProcessing.cs
Tag: dotnet-ubuntu_18869653307
Line coverage
92%
Covered lines: 86
Uncovered lines: 7
Coverable lines: 93
Total lines: 240
Line coverage: 92.4%
Branch coverage
57%
Covered branches: 31
Total branches: 54
Branch coverage: 57.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_HighHighLimitField()100%11100%
get_HighLimitField()100%11100%
get_LowLimitField()100%11100%
get_LowLowLimitField()100%11100%
get_DeadbandField()100%11100%
get_AlarmStateField()100%11100%
get_AckStateField()100%11100%
.ctor()100%11100%
.ctor(...)75%88100%
BuildAfterDeserialization(...)100%11100%
ValidateParameters(...)100%11100%
IsFieldUsed(...)0%156120%
IsFieldUsed(...)0%620%
ProcessValue(...)78.12%323294.87%

File(s)

/home/runner/work/pva.SuperV/pva.SuperV/pva.SuperV.Engine/Processing/AlarmStateProcessing.cs

#LineLine coverage
 1using System.Numerics;
 2
 3namespace pva.SuperV.Engine.Processing
 4{
 5    /// <summary>
 6    /// Alarm state generation processing on a field.
 7    /// It sets the alarm state based on a 2 or 4 limits with optional deadband and optionally sets an acknowledgement.
 8    /// </summary>
 9    /// <typeparam name="T"></typeparam>
 10    /// <seealso cref="FieldValueProcessing{T}" />
 11    public class AlarmStateProcessing<T> : FieldValueProcessing<T>, IAlarmStateProcessing where T : INumber<T>
 12    {
 13        /// <summary>
 14        /// The high-high alarm state value.
 15        /// </summary>
 16        private const int HighHighAlarmState = 2;
 17
 18        /// <summary>
 19        /// The high alarm state value.
 20        /// </summary>
 21        private const int HighAlarmState = 1;
 22
 23        /// <summary>
 24        /// The ok alarm state value
 25        /// </summary>
 26        private const int OkAlarmState = 0;
 27
 28        /// <summary>
 29        /// The low alarm state value.
 30        /// </summary>
 31        private const int LowAlarmState = -1;
 32
 33        /// <summary>
 34        /// The low-low alarm state value.
 35        /// </summary>
 36        private const int LowLowAlarmState = -2;
 37
 38        /// <summary>
 39        /// The unacknowledge state value.
 40        /// </summary>
 41        private const int UnackState = 1;
 42
 43        /// <summary>
 44        /// Gets or sets the high-high limit field definition.
 45        /// </summary>
 46        /// <value>
 47        /// The high-high limit field definition.
 48        /// </value>
 18049        public IFieldDefinition? HighHighLimitField { get; set; }
 50
 51        /// <summary>
 52        /// Gets or sets the high limit field definition.
 53        /// </summary>
 54        /// <value>
 55        /// The high limit field definition.
 56        /// </value>
 18057        public IFieldDefinition? HighLimitField { get; set; }
 58
 59        /// <summary>
 60        /// Gets or sets the low limit field definition.
 61        /// </summary>
 62        /// <value>
 63        /// The low limit field definition.
 64        /// </value>
 18065        public IFieldDefinition? LowLimitField { get; set; }
 66
 67        /// <summary>
 68        /// Gets or sets the low-low limit field definition.
 69        /// </summary>
 70        /// <value>
 71        /// The low-low limit field definition.
 72        /// </value>
 18073        public IFieldDefinition? LowLowLimitField { get; set; }
 74
 75        /// <summary>
 76        /// Gets or sets the deadband field definition.
 77        /// </summary>
 78        /// <value>
 79        /// The deadband field definition.
 80        /// </value>
 16081        public IFieldDefinition? DeadbandField { get; set; }
 82
 83        /// <summary>
 84        /// Gets or sets the alarm state field definition.
 85        /// </summary>
 86        /// <value>
 87        /// The alarm state field definition.
 88        /// </value>
 18089        public IFieldDefinition? AlarmStateField { get; set; }
 90
 91        /// <summary>
 92        /// Gets or sets the acknowledgement state field definition.
 93        /// </summary>
 94        /// <value>
 95        /// The acknowledgement state field definition.
 96        /// </value>
 18097        public IFieldDefinition? AckStateField { get; set; }
 98
 99        /// <summary>
 100        /// Initializes a new instance of the <see cref="AlarmStateProcessing{T}"/> class. Used for deserialization.
 101        /// </summary>
 1102        public AlarmStateProcessing()
 1103        {
 1104        }
 105
 106        /// <summary>
 107        /// Initializes a new instance of the <see cref="AlarmStateProcessing{T}"/> class.
 108        /// </summary>
 109        /// <param name="name">The name of processing.</param>
 110        /// <param name="clazz">The class of the instance to be processed.</param>
 111        /// <param name="trigerringFieldName">Name of the trigerring field.</param>
 112        /// <param name="highHighLimitFieldName">Name of the high-high limit field. Can be null/empty if not used.</para
 113        /// <param name="highLimitFieldName">Name of the high limit field.</param>
 114        /// <param name="lowLimitFieldName">Name of the low limit field.</param>
 115        /// <param name="lowLowLimitFieldName">Name of the low-low limit field. Can be null/empty if not used.</param>
 116        /// <param name="deadbandFieldName">Name of the deadband field. Can be null/empty if not used.</param>
 117        /// <param name="alarmStateFieldName">Name of the alarm state field.</param>
 118        /// <param name="ackStateFieldName">Name of the acknowledgment state field. Can be null/empty if not used</param
 119        public AlarmStateProcessing(string name, Class clazz, string trigerringFieldName,
 120            string? highHighLimitFieldName, string highLimitFieldName, string lowLimitFieldName, string? lowLowLimitFiel
 121            string? deadbandFieldName, string alarmStateFieldName, string? ackStateFieldName)
 151122            : base(name)
 151123        {
 151124            CtorArguments.Add(trigerringFieldName);
 151125            CtorArguments.Add(highHighLimitFieldName ?? "");
 151126            CtorArguments.Add(highLimitFieldName);
 151127            CtorArguments.Add(lowLimitFieldName);
 151128            CtorArguments.Add(lowLowLimitFieldName ?? "");
 151129            CtorArguments.Add(deadbandFieldName ?? "");
 151130            CtorArguments.Add(alarmStateFieldName);
 151131            CtorArguments.Add(ackStateFieldName ?? "");
 132
 151133            ValidateParameters(clazz, trigerringFieldName,
 151134                highHighLimitFieldName, highLimitFieldName, lowLimitFieldName, lowLowLimitFieldName, deadbandFieldName,
 151135                alarmStateFieldName, ackStateFieldName);
 151136        }
 137
 138        /// <summary>
 139        /// Builds the field value processing from the <see cref="P:pva.SuperV.Engine.FieldValueProcessing`1.CtorArgumen
 140        /// </summary>
 141        /// <param name="project">The project.</param>
 142        /// <param name="clazz">The clazz.</param>
 143        public override void BuildAfterDeserialization(Project project, Class clazz)
 1144        {
 1145            string? trigerringFieldName = GetCtorArgument<string>(0);
 1146            string? highHighLimitFieldName = GetCtorArgument<string>(1);
 1147            string? highLimitFieldName = GetCtorArgument<string>(2);
 1148            string? lowLimitFieldName = GetCtorArgument<string>(3);
 1149            string? lowLowLimitFieldName = GetCtorArgument<string>(4);
 1150            string? deadbandFieldName = GetCtorArgument<string>(5);
 1151            string? alarmStateFieldName = GetCtorArgument<string>(6);
 1152            string? ackStateFieldName = GetCtorArgument<string>(7);
 153
 1154            ValidateParameters(clazz, trigerringFieldName,
 1155                highHighLimitFieldName, highLimitFieldName, lowLimitFieldName, lowLowLimitFieldName, deadbandFieldName,
 1156                alarmStateFieldName, ackStateFieldName);
 1157        }
 158
 159        private void ValidateParameters(Class clazz, string? trigerringFieldName, string? highHighLimitFieldName, string
 152160        {
 152161            TrigerringFieldDefinition = GetFieldDefinition<T>(clazz, trigerringFieldName);
 152162            HighHighLimitField = GetFieldDefinition<T>(clazz, highHighLimitFieldName);
 152163            HighLimitField = GetFieldDefinition<T>(clazz, highLimitFieldName)!;
 152164            LowLimitField = GetFieldDefinition<T>(clazz, lowLimitFieldName)!;
 152165            LowLowLimitField = GetFieldDefinition<T>(clazz, lowLowLimitFieldName);
 152166            DeadbandField = GetFieldDefinition<T>(clazz, deadbandFieldName);
 152167            AlarmStateField = GetFieldDefinition<int>(clazz, alarmStateFieldName)!;
 152168            AckStateField = GetFieldDefinition<int>(clazz, ackStateFieldName)!;
 152169        }
 170
 171        public override bool IsFieldUsed(string fieldName)
 0172        => IsFieldUsed(HighHighLimitField, fieldName) || IsFieldUsed(HighLimitField, fieldName) ||
 0173            IsFieldUsed(LowLimitField, fieldName) || IsFieldUsed(LowLowLimitField, fieldName) ||
 0174            IsFieldUsed(DeadbandField, fieldName) ||
 0175            IsFieldUsed(AlarmStateField, fieldName) || IsFieldUsed(AckStateField, fieldName);
 176
 177        private static bool IsFieldUsed(IFieldDefinition? field, string fieldName)
 0178        {
 0179            return (field is not null && field.Name.Equals(fieldName));
 0180        }
 181
 182        /// <summary>
 183        /// Processes the value change.
 184        /// </summary>
 185        /// <param name="instance">Instance on which the triggering field changed.</param>
 186        /// <param name="changedField">The <see cref="Field{T}" /> which changed.</param>
 187        /// <param name="valueChanged">If <c>true</c>, indicates that the trigerring field value changed.</param>
 188        /// <param name="previousValue">The previous value of field.</param>
 189        /// <param name="currentValue">The current value of field.</param>
 190        public override void ProcessValue(IInstance instance, Field<T> changedField, bool valueChanged, T previousValue,
 22191        {
 22192            if (!valueChanged)
 2193            {
 2194                return;
 195            }
 20196            Field<T>? highHighLimit = GetInstanceField<T>(instance, HighHighLimitField?.Name);
 20197            Field<T>? highLimit = GetInstanceField<T>(instance, HighLimitField!.Name);
 20198            Field<T>? lowLimit = GetInstanceField<T>(instance, LowLimitField!.Name);
 20199            Field<T>? lowLowLimit = GetInstanceField<T>(instance, LowLowLimitField?.Name);
 200            // TODO: Add deadband
 201            // Field<T>? deadband = GetInstanceField<T>(instance, DeadbandField?.Name);
 20202            Field<int> alarmState = GetInstanceField<int>(instance, AlarmStateField!.Name)!;
 20203            Field<int>? ackState = GetInstanceField<int>(instance, AckStateField?.Name);
 20204            int previousAlarmState = alarmState.Value;
 205            int newAlarmState;
 206            // TODO: Handle deadband
 20207            if (highHighLimit is not null && currentValue >= highHighLimit.Value)
 12208            {
 12209                newAlarmState = HighHighAlarmState;
 12210            }
 8211            else if (highHighLimit is not null && currentValue < highHighLimit.Value && currentValue >= highLimit!.Value
 1212            {
 1213                newAlarmState = HighAlarmState;
 1214            }
 7215            else if (lowLowLimit is not null && currentValue <= lowLowLimit.Value)
 1216            {
 1217                newAlarmState = LowLowAlarmState;
 1218            }
 6219            else if (currentValue <= lowLimit!.Value)
 1220            {
 1221                newAlarmState = LowAlarmState;
 1222            }
 223            else
 5224            {
 5225                newAlarmState = OkAlarmState;
 5226            }
 227
 20228            if (newAlarmState == previousAlarmState)
 2229            {
 2230                return;
 231            }
 232
 18233            alarmState.SetValue(newAlarmState);
 18234            if (ackState is not null && newAlarmState != OkAlarmState && ackState.Value != UnackState)
 4235            {
 4236                ackState.SetValue(UnackState);
 4237            }
 22238        }
 239    }
 240}