コード例 #1
0
        private MeasurementStateFlags ConvertStatusFlags(AFValueStatus status)
        {
            MeasurementStateFlags flags = MeasurementStateFlags.Normal;

            if ((status & AFValueStatus.Bad) > 0)
            {
                flags |= MeasurementStateFlags.BadData;
            }

            if ((status & AFValueStatus.Questionable) > 0)
            {
                flags |= MeasurementStateFlags.SuspectData;
            }

            if ((status & AFValueStatus.BadSubstituteValue) > 0)
            {
                flags |= MeasurementStateFlags.CalculationError | MeasurementStateFlags.BadData;
            }

            if ((status & AFValueStatus.UncertainSubstituteValue) > 0)
            {
                flags |= MeasurementStateFlags.CalculationError | MeasurementStateFlags.SuspectData;
            }

            if ((status & AFValueStatus.Substituted) > 0)
            {
                flags |= MeasurementStateFlags.CalculatedValue;
            }

            return(flags);
        }
コード例 #2
0
        protected MeasurementFlags GetMeasurementFlags(IMeasurement measurement)
        {
            MeasurementStateFlags tslFlags = measurement.StateFlags;    // Time-series Library Measurement State Flags
            MeasurementFlags      ecaflags = MeasurementFlags.Normal;   // openECA Measurement Flags

            MeasurementStateFlags badValueFlags =
                MeasurementStateFlags.BadData |
                MeasurementStateFlags.SuspectData |
                MeasurementStateFlags.ReceivedAsBad |
                MeasurementStateFlags.DiscardedValue |
                MeasurementStateFlags.MeasurementError;

            if ((tslFlags & badValueFlags) != MeasurementStateFlags.Normal)
            {
                ecaflags |= MeasurementFlags.BadValue;
            }

            MeasurementStateFlags badTimeFlags =
                MeasurementStateFlags.BadTime |
                MeasurementStateFlags.SuspectTime |
                MeasurementStateFlags.LateTimeAlarm |
                MeasurementStateFlags.FutureTimeAlarm;

            if ((tslFlags & badTimeFlags) != MeasurementStateFlags.Normal)
            {
                ecaflags |= MeasurementFlags.BadTime;
            }

            MeasurementStateFlags calculatedValueFlags =
                MeasurementStateFlags.CalculatedValue |
                MeasurementStateFlags.UpSampled |
                MeasurementStateFlags.DownSampled;

            if ((tslFlags & calculatedValueFlags) != MeasurementStateFlags.Normal)
            {
                ecaflags |= MeasurementFlags.CalculatedValue;
            }

            MeasurementStateFlags unreasonableValueFlags =
                MeasurementStateFlags.OverRangeError |
                MeasurementStateFlags.UnderRangeError |
                MeasurementStateFlags.AlarmHigh |
                MeasurementStateFlags.AlarmLow |
                MeasurementStateFlags.WarningHigh |
                MeasurementStateFlags.WarningLow |
                MeasurementStateFlags.FlatlineAlarm |
                MeasurementStateFlags.ComparisonAlarm |
                MeasurementStateFlags.ROCAlarm |
                MeasurementStateFlags.CalculationError |
                MeasurementStateFlags.CalculationWarning |
                MeasurementStateFlags.SystemError |
                MeasurementStateFlags.SystemWarning;

            if ((tslFlags & unreasonableValueFlags) != MeasurementStateFlags.Normal)
            {
                ecaflags |= MeasurementFlags.UnreasonableValue;
            }

            return(ecaflags);
        }
コード例 #3
0
            public bool Update(Measurement measurement)
            {
                double   value     = measurement.Value;
                DateTime timestamp = new DateTime(measurement.Timestamp, DateTimeKind.Utc);

                if (StartTimestamp == default)
                {
                    StartTimestamp = timestamp;
                }

                // Check for stale point
                if (LastTimestamp != default && (timestamp - LastTimestamp).TotalMilliseconds > s_settings.WindowSize)
                {
                    Reset();
                    return(false);
                }

                LastTimestamp = timestamp;

                if (value < Minimum)
                {
                    Minimum = value;
                }

                if (value > Maximum)
                {
                    Maximum = value;
                }

                Total += value;
                Count++;
                Flags |= measurement.Flags;

                return((timestamp - StartTimestamp).TotalMilliseconds > s_settings.WindowSize);
            }
コード例 #4
0
        /// <summary>
        /// Initializes the adapter's settings.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            string setting;

            // Load required parameters

            if (settings.TryGetValue(nameof(SourceMeasurements), out setting))
            {
                m_sourceMeasurements = ParseInputMeasurementKeys(DataSource, true, setting);
            }
            else
            {
                throw new ArgumentException("Missing required connection string parameter: SourceMeasurements", nameof(SourceMeasurements));
            }

            if (settings.TryGetValue(nameof(DestinationMeasurements), out setting))
            {
                m_destinationMeasurements = ParseInputMeasurementKeys(DataSource, true, setting);
            }
            else
            {
                throw new ArgumentException("Missing required connection string parameter: DestinationMeasurements", nameof(DestinationMeasurements));
            }

            if (m_sourceMeasurements.Length != m_destinationMeasurements.Length)
            {
                throw new ArgumentException($"Source and destination measurements are parallel arrays, therefore their lengths must match - Src: {m_sourceMeasurements.Length}, Dst: {m_destinationMeasurements.Length}");
            }

            InputMeasurementKeys = m_sourceMeasurements.Concat(m_destinationMeasurements).ToArray();

            Dictionary <MeasurementKey, MeasurementKey> sourceToDestinationLookup = m_sourceMeasurements
                                                                                    .Zip(m_destinationMeasurements, (Src, Dst) => new { Src, Dst })
                                                                                    .ToDictionary(obj => obj.Src, obj => obj.Dst);

            Dictionary <MeasurementKey, MeasurementStateFlags> destinationToStateLookup = m_destinationMeasurements
                                                                                          .ToDictionary(dst => dst, dst => MeasurementStateFlags.Normal);

            m_sourceToDestinationLookup = sourceToDestinationLookup;
            m_destinationToStateLookup  = new ConcurrentDictionary <MeasurementKey, MeasurementStateFlags>(destinationToStateLookup);

            // Load optional parameters

            if (!settings.TryGetValue(nameof(Flags), out setting) || !Enum.TryParse(setting, out m_flags))
            {
                m_flags = DefaultFlags;
            }

            if (settings.TryGetValue(nameof(SupportsTemporalProcessing), out setting))
            {
                m_supportsTemporalProcessing = setting.ParseBoolean();
            }
            else
            {
                m_supportsTemporalProcessing = DefaultSupportsTemporalProcessing;
            }
        }
コード例 #5
0
        // Processes measurements in the queue.
        private void ProcessMeasurements(IList <IMeasurement> measurements)
        {
            SignalAlarms alarms;

            Alarm activeAlarm;
            Alarm firstRaisedAlarm;
            List <IMeasurement> alarmEvents;

            alarmEvents = new List <IMeasurement>();

            foreach (IMeasurement measurement in measurements)
            {
                lock (m_alarmLock)
                {
                    // Get alarms that apply to the measurement being processed
                    if (!m_alarmLookup.TryGetValue(measurement.ID, out alarms))
                    {
                        continue;
                    }

                    // Get the currently active alarm
                    activeAlarm = alarms.Alarms.FirstOrDefault(alarm => alarm.State == AlarmState.Raised);

                    // Test each alarm to determine whether their states have changed
                    alarmEvents.AddRange(alarms.Alarms.Where(alarm => alarm.Test(measurement)).Select(alarm => CreateAlarmEvent(measurement.Timestamp, alarm)));

                    // Get the alarm that will become the currently active alarm
                    firstRaisedAlarm = alarms.Alarms.FirstOrDefault(alarm => alarm.State == AlarmState.Raised);
                }

                // Update alarm log to show changes in state of active alarms
                if (firstRaisedAlarm != activeAlarm)
                {
                    LogStateChange(measurement.ID, activeAlarm, firstRaisedAlarm, measurement.Timestamp, measurement.Value);
                }

                const MeasurementStateFlags        ErrorFlags = MeasurementStateFlags.BadData | MeasurementStateFlags.BadTime | MeasurementStateFlags.SystemError;
                Func <MeasurementStateFlags, bool> hasError   = flags => (flags & ErrorFlags) != MeasurementStateFlags.Normal;

                if (hasError(measurement.StateFlags))
                {
                    if ((object)firstRaisedAlarm != null && firstRaisedAlarm.Severity > AlarmSeverity.None)
                    {
                        alarms.Statistics.IncrementCounter(firstRaisedAlarm);
                    }
                }
            }

            if (alarmEvents.Count > 0)
            {
                // Update alarm history by sending
                // new alarm events into the system
                OnNewMeasurements(alarmEvents);
                Interlocked.Add(ref m_eventCount, alarmEvents.Count);
            }

            // Increment total count of processed measurements
            IncrementProcessedMeasurements(measurements.Count);
        }
コード例 #6
0
        public Measurement(System.Guid signalID, long timestamp, double value = double.NaN, MeasurementStateFlags flags = MeasurementStateFlags.Normal)
        {
            Value     = value;
            Timestamp = timestamp;
            Flags     = flags;

            this.SetSignalID(signalID);
        }
コード例 #7
0
 public void Reset()
 {
     StartTimestamp = default;
     LastTimestamp  = default;
     Minimum        = double.MaxValue;
     Maximum        = double.MinValue;
     Total          = default;
     Count          = default;
     Flags          = MeasurementStateFlags.Normal;
 }
コード例 #8
0
        /// <summary>
        /// Initializes the <see cref="BestValueSelector"/>.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            if (OutputMeasurements?.Length != 1 && OutputMeasurements?.Length != 2)
            {
                throw new ArgumentException($"Exactly one or two output measurement must be defined. Amount defined: {OutputMeasurements?.Length ?? 0}");
            }

            Dictionary <string, string> settings = Settings;
            string setting;

            if (settings.TryGetValue(nameof(PublishBadValues), out setting))
            {
                m_publishBadValues = setting.ParseBoolean();
            }
            else
            {
                m_publishBadValues = DefaultHandleZeroAsBad;
            }

            if (!settings.TryGetValue(nameof(BadFlags), out setting) || !Enum.TryParse(setting, out m_badFlags))
            {
                m_badFlags = DefaultBadFlags;
            }

            if (settings.TryGetValue(nameof(HandleZeroAsBad), out setting))
            {
                m_handleZeroAsBad = setting.ParseBoolean();
            }
            else
            {
                m_handleZeroAsBad = DefaultHandleZeroAsBad;
            }

            if (settings.TryGetValue(nameof(HandleNaNAsBad), out setting))
            {
                m_handleNaNAsBad = setting.ParseBoolean();
            }
            else
            {
                m_handleNaNAsBad = DefaultHandleNaNAsBad;
            }

            if (settings.TryGetValue(nameof(SupportsTemporalProcessing), out setting))
            {
                m_supportsTemporalProcessing = setting.ParseBoolean();
            }
            else
            {
                m_supportsTemporalProcessing = DefaultSupportsTemporalProcessing;
            }
        }
コード例 #9
0
        /// <summary>
        /// Initializes the adapter's settings.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            Dictionary <string, string> settings = Settings;
            string setting;
            MeasurementStateFlags flags;

            if (settings.TryGetValue(nameof(Flags), out setting) && Enum.TryParse(setting, out flags))
            {
                m_flags = flags;
            }
            else
            {
                m_flags = DefaultFlags;
            }

            if (settings.TryGetValue(nameof(SupportsTemporalProcessing), out setting))
            {
                m_supportsTemporalProcessing = setting.ParseBoolean();
            }
            else
            {
                m_supportsTemporalProcessing = DefaultSupportsTemporalProcessing;
            }

            const string AlarmTable    = "Alarms";
            const string AlarmIDField  = "AssociatedMeasurementID";
            const string SignalIDField = "SignalID";

            HashSet <MeasurementKey> inputMeasurementKeys = new HashSet <MeasurementKey>(InputMeasurementKeys);

            Func <DataRow, string, MeasurementKey> getKey = (row, field) =>
                                                            MeasurementKey.LookUpBySignalID(row.ConvertField <Guid>(field));

            Dictionary <MeasurementKey, MeasurementKey> alarmToSignalLookup = DataSource.Tables[AlarmTable]
                                                                              .Select(AlarmIDField + " IS NOT NULL")
                                                                              .Select(row => new { AlarmID = getKey(row, AlarmIDField), SignalID = getKey(row, SignalIDField) })
                                                                              .Where(obj => inputMeasurementKeys.Contains(obj.AlarmID))
                                                                              .Where(obj => inputMeasurementKeys.Contains(obj.SignalID))
                                                                              .ToDictionary(obj => obj.AlarmID, obj => obj.SignalID);

            HashSet <MeasurementKey> raisedAlarms = new HashSet <MeasurementKey>(AlarmAdapter.Default?.GetRaisedAlarms()
                                                                                 .Select(alarm => alarm.AssociatedMeasurementID.GetValueOrDefault())
                                                                                 .Select(alarmID => MeasurementKey.LookUpBySignalID(alarmID)) ?? Enumerable.Empty <MeasurementKey>());

            Dictionary <MeasurementKey, bool> signalToAlarmStateLookup = alarmToSignalLookup.Values
                                                                         .ToDictionary(key => key, key => raisedAlarms.Contains(key));

            m_alarmToSignalLookup      = alarmToSignalLookup;
            m_signalToAlarmStateLookup = new ConcurrentDictionary <MeasurementKey, bool>(signalToAlarmStateLookup);
        }
コード例 #10
0
        protected MeasurementFlags GetMeasurementFlags(IMeasurement measurement)
        {
            MeasurementStateFlags tslFlags = measurement.StateFlags;    // Time-series Library Measurement State Flags
            MeasurementFlags      ecaflags = MeasurementFlags.Normal;   // openECA Measurement Flags

            if (tslFlags.HasFlag(MeasurementStateFlags.BadData) ||
                tslFlags.HasFlag(MeasurementStateFlags.SuspectData) ||
                tslFlags.HasFlag(MeasurementStateFlags.ReceivedAsBad) ||
                tslFlags.HasFlag(MeasurementStateFlags.DiscardedValue) ||
                tslFlags.HasFlag(MeasurementStateFlags.MeasurementError))
            {
                ecaflags |= MeasurementFlags.BadValue;
            }

            if (tslFlags.HasFlag(MeasurementStateFlags.BadTime) ||
                tslFlags.HasFlag(MeasurementStateFlags.SuspectTime) ||
                tslFlags.HasFlag(MeasurementStateFlags.LateTimeAlarm) ||
                tslFlags.HasFlag(MeasurementStateFlags.FutureTimeAlarm))
            {
                ecaflags |= MeasurementFlags.BadTime;
            }

            if (tslFlags.HasFlag(MeasurementStateFlags.CalcuatedValue) ||
                tslFlags.HasFlag(MeasurementStateFlags.UpSampled) ||
                tslFlags.HasFlag(MeasurementStateFlags.DownSampled))
            {
                ecaflags |= MeasurementFlags.CalculatedValue;
            }

            if (tslFlags.HasFlag(MeasurementStateFlags.OverRangeError) ||
                tslFlags.HasFlag(MeasurementStateFlags.UnderRangeError) ||
                tslFlags.HasFlag(MeasurementStateFlags.AlarmHigh) ||
                tslFlags.HasFlag(MeasurementStateFlags.AlarmLow) ||
                tslFlags.HasFlag(MeasurementStateFlags.WarningHigh) ||
                tslFlags.HasFlag(MeasurementStateFlags.WarningLow) ||
                tslFlags.HasFlag(MeasurementStateFlags.FlatlineAlarm) ||
                tslFlags.HasFlag(MeasurementStateFlags.ComparisonAlarm) ||
                tslFlags.HasFlag(MeasurementStateFlags.ROCAlarm) ||
                tslFlags.HasFlag(MeasurementStateFlags.CalculationError) ||
                tslFlags.HasFlag(MeasurementStateFlags.CalculationWarning) ||
                tslFlags.HasFlag(MeasurementStateFlags.SystemError) ||
                tslFlags.HasFlag(MeasurementStateFlags.SystemWarning))
            {
                ecaflags |= MeasurementFlags.UnreasonableValue;
            }

            return(ecaflags);
        }
コード例 #11
0
        /// <summary>
        /// Gets derived quality flags from specified value and time quality.
        /// </summary>
        /// <param name="valueQualityIsGood">Flag that determines if value quality is good.</param>
        /// <param name="timeQualityIsGood">Flag that determines if time quality is good.</param>
        /// <returns>Derived quality flags.</returns>
        public static MeasurementStateFlags From(bool valueQualityIsGood, bool timeQualityIsGood)
        {
            MeasurementStateFlags derivedQuality = MeasurementStateFlags.Normal;

            if (!valueQualityIsGood)
            {
                derivedQuality |= MeasurementStateFlags.BadData;
            }

            if (!timeQualityIsGood)
            {
                derivedQuality |= MeasurementStateFlags.BadTime;
            }

            return(derivedQuality);
        }
コード例 #12
0
ファイル: SerializationExtensions.cs プロジェクト: xj0229/gsf
        public static DataQualityFlags DeriveQualityFlags(this MeasurementStateFlags stateFlags)
        {
            DataQualityFlags qualityFlags = DataQualityFlags.Normal;

            if (stateFlags.HasFlag(MeasurementStateFlags.BadData))
            {
                qualityFlags |= DataQualityFlags.ValueQualityIsBad;
            }

            if (stateFlags.HasFlag(MeasurementStateFlags.BadTime))
            {
                qualityFlags |= DataQualityFlags.TimeQualityIsBad;
            }

            return(qualityFlags);
        }
コード例 #13
0
ファイル: SerializationExtensions.cs プロジェクト: xj0229/gsf
        public static MeasurementStateFlags DeriveStateFlags(this DataQualityFlags qualityFlags)
        {
            MeasurementStateFlags stateFlags = MeasurementStateFlags.Normal;

            if (qualityFlags.HasFlag(DataQualityFlags.ValueQualityIsBad))
            {
                stateFlags |= MeasurementStateFlags.BadData;
            }

            if (qualityFlags.HasFlag(DataQualityFlags.TimeQualityIsBad))
            {
                stateFlags |= MeasurementStateFlags.BadTime;
            }

            return(stateFlags);
        }
コード例 #14
0
        private int CountFlags(MeasurementStateFlags flags)
        {
            if (flags == MeasurementStateFlags.Normal)
            {
                return(0);
            }

            uint count = (uint)flags;

            count = count - ((count >> 1) & 0x55555555u);
            count = ((count >> 2) & 0x33333333u) + (count & 0x33333333u);
            count = ((count >> 4) + count) & 0x0F0F0F0Fu;
            count = ((count >> 8) + count) & 0x00FF00FFu;
            count = ((count >> 16) + count) & 0x0000FFFFu;

            return((int)count);
        }
コード例 #15
0
        /// <summary>
        /// Gets derived quality flags from a set of value and time quality vectors.
        /// </summary>
        /// <param name="valueQualities">Boolean vector where flag determines if value quality is good.</param>
        /// <param name="timeQualities">Boolean vector where flag determines if time quality is good.</param>
        /// <returns>Derived quality flags.</returns>
        public static MeasurementStateFlags From(IEnumerable <bool> valueQualities, IEnumerable <bool> timeQualities)
        {
            MeasurementStateFlags derivedQuality = MeasurementStateFlags.Normal;

            bool qualityIsBad(bool qualityIsGood) => !qualityIsGood;

            if (valueQualities.Any(qualityIsBad))
            {
                derivedQuality |= MeasurementStateFlags.BadData;
            }

            if (timeQualities.Any(qualityIsBad))
            {
                derivedQuality |= MeasurementStateFlags.BadTime;
            }

            return(derivedQuality);
        }
コード例 #16
0
        /// <summary>
        /// Gets a <see cref="MeasurementStateFlags"/> value from a <see cref="Quality"/> value.
        /// </summary>
        /// <param name="quality"><see cref="Quality"/> value to interpret.</param>
        /// <returns><see cref="MeasurementStateFlags"/> value from a <see cref="Quality"/> value.</returns>
        public static MeasurementStateFlags MeasurementQuality(this Quality quality)
        {
            MeasurementStateFlags stateFlags = MeasurementStateFlags.Normal;

            if (quality == Quality.DeletedFromProcessing)
            {
                stateFlags |= MeasurementStateFlags.DiscardedValue;
            }

            if (quality == Quality.Old)
            {
                stateFlags |= MeasurementStateFlags.BadTime;
            }

            if (quality == Quality.SuspectData)
            {
                stateFlags |= MeasurementStateFlags.BadData;
            }

            return(stateFlags);
        }
コード例 #17
0
ファイル: IMeasurementExtensions.cs プロジェクト: sotaria/gsf
        /// <summary>
        /// Gets derived quality flags from a set of source measurements.
        /// </summary>
        /// <param name="measurements">Source measurements.</param>
        /// <returns>Derived quality flags.</returns>
        public static MeasurementStateFlags DeriveQualityFlags(this IEnumerable <IMeasurement> measurements)
        {
            MeasurementStateFlags derivedQuality = MeasurementStateFlags.Normal;

            MeasurementStateFlags[] stateFlags = measurements.Select(measurement => measurement.StateFlags).ToArray();

            bool dataQualityIsBad(MeasurementStateFlags flags) => (flags & MeasurementStateFlags.BadData) > 0;
            bool timeQualityIsBad(MeasurementStateFlags flags) => (flags & MeasurementStateFlags.BadTime) > 0;

            if (stateFlags.Any(dataQualityIsBad))
            {
                derivedQuality |= MeasurementStateFlags.BadData;
            }

            if (stateFlags.Any(timeQualityIsBad))
            {
                derivedQuality |= MeasurementStateFlags.BadTime;
            }

            return(derivedQuality);
        }
コード例 #18
0
ファイル: Publisher.cs プロジェクト: lulzzz/openECA
        private void HandleSendMeasurementsCommand(ClientConnection connection, byte[] buffer, int startIndex, int length)
        {
            int index = startIndex;

            if (length - index < 4)
            {
                throw new Exception("Not enough bytes in buffer to parse measurement count");
            }

            int count = BigEndian.ToInt32(buffer, index);

            index += sizeof(int);

            if (length - index < count * 36)
            {
                throw new Exception("Not enough bytes in buffer to parse all measurements");
            }

            List <IMeasurement> measurements = new List <IMeasurement>(count);

            for (int i = 0; i < count; i++)
            {
                Guid     signalID  = buffer.ToRfcGuid(index); index += 16;
                DateTime timestamp = new DateTime(BigEndian.ToInt64(buffer, index)); index += sizeof(long);
                double   value     = BigEndian.ToDouble(buffer, index); index += sizeof(double);
                MeasurementStateFlags stateFlags = (MeasurementStateFlags)BigEndian.ToInt32(buffer, index); index += sizeof(int);

                measurements.Add(new Measurement()
                {
                    Metadata   = MeasurementKey.LookUpBySignalID(signalID).Metadata,
                    Timestamp  = timestamp,
                    Value      = value,
                    StateFlags = stateFlags
                });
            }

            OnNewMeasurements(measurements);
        }
コード例 #19
0
ファイル: CompactMeasurement.cs プロジェクト: lyrain2009/gsf
        /// <summary>
        /// Maps <see cref="CompactMeasurementStateFlags"/> to <see cref="MeasurementStateFlags"/>.
        /// </summary>
        /// <param name="stateFlags">Flags to map.</param>
        /// <returns><see cref="MeasurementStateFlags"/> mapped from <see cref="CompactMeasurementStateFlags"/>.</returns>
        public static MeasurementStateFlags MapToFullFlags(this CompactMeasurementStateFlags stateFlags)
        {
            MeasurementStateFlags mappedStateFlags = MeasurementStateFlags.Normal;

            if ((stateFlags & CompactMeasurementStateFlags.DataRange) > 0)
            {
                mappedStateFlags |= DataRangeMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.DataQuality) > 0)
            {
                mappedStateFlags |= DataQualityMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.TimeQuality) > 0)
            {
                mappedStateFlags |= TimeQualityMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.SystemIssue) > 0)
            {
                mappedStateFlags |= SystemIssueMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.CalculatedValue) > 0)
            {
                mappedStateFlags |= CalculatedValueMask;
            }

            if ((stateFlags & CompactMeasurementStateFlags.DiscardedValue) > 0)
            {
                mappedStateFlags |= DiscardedValueMask;
            }

            return(mappedStateFlags);
        }
コード例 #20
0
ファイル: CompactMeasurement.cs プロジェクト: lyrain2009/gsf
        /// <summary>
        /// Maps <see cref="MeasurementStateFlags"/> to <see cref="CompactMeasurementStateFlags"/>.
        /// </summary>
        /// <param name="stateFlags">Flags to map.</param>
        /// <returns><see cref="CompactMeasurementStateFlags"/> mapped from <see cref="MeasurementStateFlags"/>.</returns>
        public static CompactMeasurementStateFlags MapToCompactFlags(this MeasurementStateFlags stateFlags)
        {
            CompactMeasurementStateFlags mappedStateFlags = CompactMeasurementStateFlags.NoFlags;

            if ((stateFlags & DataRangeMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.DataRange;
            }

            if ((stateFlags & DataQualityMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.DataQuality;
            }

            if ((stateFlags & TimeQualityMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.TimeQuality;
            }

            if ((stateFlags & SystemIssueMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.SystemIssue;
            }

            if ((stateFlags & CalculatedValueMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.CalculatedValue;
            }

            if ((stateFlags & DiscardedValueMask) > 0)
            {
                mappedStateFlags |= CompactMeasurementStateFlags.DiscardedValue;
            }

            return(mappedStateFlags);
        }
コード例 #21
0
        protected MeasurementStateFlags GetMeasurementStateFlags(MeasurementFlags ecaFlags)
        {
            MeasurementStateFlags tslFlags = MeasurementStateFlags.Normal;

            if (ecaFlags.HasFlag(MeasurementFlags.BadValue))
            {
                tslFlags |= MeasurementStateFlags.BadData;
            }

            if (ecaFlags.HasFlag(MeasurementFlags.BadTime))
            {
                tslFlags |= MeasurementStateFlags.BadTime;
            }

            if (ecaFlags.HasFlag(MeasurementFlags.CalculatedValue))
            {
                tslFlags |= MeasurementStateFlags.CalculatedValue;
            }

            if (ecaFlags.HasFlag(MeasurementFlags.UnreasonableValue))
            {
                tslFlags |= MeasurementStateFlags.OverRangeError | MeasurementStateFlags.UnderRangeError;
            }

            if (ecaFlags.HasFlag(MeasurementFlags.UserDefinedFlag1))
            {
                tslFlags |= MeasurementStateFlags.UserDefinedFlag1;
            }

            if (ecaFlags.HasFlag(MeasurementFlags.UserDefinedFlag2))
            {
                tslFlags |= MeasurementStateFlags.UserDefinedFlag2;
            }

            return(tslFlags);
        }
コード例 #22
0
ファイル: StatusFlags.cs プロジェクト: sotaria/gsf
        /// <summary>
        /// Maps <see cref="MeasurementStateFlags"/> to <see cref="StatusFlags"/>.
        /// </summary>
        /// <param name="stateFlags">Flags to map.</param>
        /// <param name="type">Data type of measurement.</param>
        /// <param name="digitalSet">Flag that determines if digital value is set.</param>
        /// <returns><see cref="StatusFlags"/> mapped from <see cref="MeasurementStateFlags"/>.</returns>
        public static StatusFlags MapToStatusFlags(this MeasurementStateFlags stateFlags, DataType type = DataType.Analog, bool digitalSet = false)
        {
            StatusFlags status = StatusFlags.RTSTAT_UNUSED;

            if ((stateFlags & MeasurementStateFlags.ReceivedAsBad) > 0)
            {
                status |= StatusFlags.RTSTAT_UNRELIABLE;
            }

            if ((stateFlags & MeasurementStateFlags.BadTime) > 0 ||
                (stateFlags & MeasurementStateFlags.SuspectTime) > 0 ||
                (stateFlags & MeasurementStateFlags.LateTimeAlarm) > 0 ||
                (stateFlags & MeasurementStateFlags.FutureTimeAlarm) > 0 ||
                (stateFlags & MeasurementStateFlags.SystemError) > 0 ||
                (stateFlags & MeasurementStateFlags.SystemWarning) > 0)
            {
                status |= StatusFlags.RTSTAT_OOR;
            }

            if (type == DataType.Analog)
            {
                // Point is analog
                if (stateFlags == MeasurementStateFlags.Normal)
                {
                    status = StatusFlags.ANALOG_OK;
                }
                else
                {
                    if ((stateFlags & MeasurementStateFlags.BadData) > 0 ||
                        (stateFlags & MeasurementStateFlags.SuspectData) > 0 ||
                        (stateFlags & MeasurementStateFlags.FlatlineAlarm) > 0 ||
                        (stateFlags & MeasurementStateFlags.ComparisonAlarm) > 0 ||
                        (stateFlags & MeasurementStateFlags.ROCAlarm) > 0 ||
                        (stateFlags & MeasurementStateFlags.CalculationError) > 0 ||
                        (stateFlags & MeasurementStateFlags.CalculationWarning) > 0 ||
                        (stateFlags & MeasurementStateFlags.MeasurementError) > 0)
                    {
                        status |= StatusFlags.ANALOG_UNRELIABLE;
                    }

                    if ((stateFlags & MeasurementStateFlags.OverRangeError) > 0)
                    {
                        status |= StatusFlags.ANALOG_HIGH_OUT_OF_RANGE;
                    }

                    if ((stateFlags & MeasurementStateFlags.UnderRangeError) > 0)
                    {
                        status |= StatusFlags.ANALOG_LOW_OUT_OF_RANGE;
                    }

                    if ((stateFlags & MeasurementStateFlags.AlarmHigh) > 0)
                    {
                        status |= StatusFlags.ANALOG_HIGH_ALARM;
                    }

                    if ((stateFlags & MeasurementStateFlags.AlarmLow) > 0)
                    {
                        status |= StatusFlags.ANALOG_LOW_ALARM;
                    }

                    if ((stateFlags & MeasurementStateFlags.WarningHigh) > 0)
                    {
                        status |= StatusFlags.ANALOG_HIGH_WARNING;
                    }

                    if ((stateFlags & MeasurementStateFlags.WarningLow) > 0)
                    {
                        status |= StatusFlags.ANALOG_LOW_WARNING;
                    }
                }
            }
            else if (type == DataType.Digital)
            {
                // Point is digital
                if (digitalSet)
                {
                    if (stateFlags == MeasurementStateFlags.Normal)
                    {
                        status = StatusFlags.DIGITAL_OK_SET;
                    }
                    else
                    {
                        if ((stateFlags & MeasurementStateFlags.BadData) > 0 ||
                            (stateFlags & MeasurementStateFlags.SuspectData) > 0 ||
                            (stateFlags & MeasurementStateFlags.FlatlineAlarm) > 0 ||
                            (stateFlags & MeasurementStateFlags.ComparisonAlarm) > 0 ||
                            (stateFlags & MeasurementStateFlags.ROCAlarm) > 0 ||
                            (stateFlags & MeasurementStateFlags.CalculationError) > 0 ||
                            (stateFlags & MeasurementStateFlags.CalculationWarning) > 0 ||
                            (stateFlags & MeasurementStateFlags.MeasurementError) > 0)
                        {
                            status |= StatusFlags.DIGITAL_UNRELIABLE_SET;
                        }

                        if ((stateFlags & MeasurementStateFlags.OverRangeError) > 0 ||
                            (stateFlags & MeasurementStateFlags.UnderRangeError) > 0 ||
                            (stateFlags & MeasurementStateFlags.AlarmHigh) > 0 ||
                            (stateFlags & MeasurementStateFlags.AlarmLow) > 0 ||
                            (stateFlags & MeasurementStateFlags.WarningHigh) > 0 ||
                            (stateFlags & MeasurementStateFlags.WarningLow) > 0)
                        {
                            status |= StatusFlags.DIGITAL_WARNING_SET;
                        }
                    }
                }
                else
                {
                    if (stateFlags == MeasurementStateFlags.Normal)
                    {
                        status = StatusFlags.DIGITAL_OK_NOT_SET;
                    }
                    else
                    {
                        if ((stateFlags & MeasurementStateFlags.BadData) > 0 ||
                            (stateFlags & MeasurementStateFlags.SuspectData) > 0 ||
                            (stateFlags & MeasurementStateFlags.FlatlineAlarm) > 0 ||
                            (stateFlags & MeasurementStateFlags.ComparisonAlarm) > 0 ||
                            (stateFlags & MeasurementStateFlags.ROCAlarm) > 0 ||
                            (stateFlags & MeasurementStateFlags.CalculationError) > 0 ||
                            (stateFlags & MeasurementStateFlags.CalculationWarning) > 0 ||
                            (stateFlags & MeasurementStateFlags.MeasurementError) > 0)
                        {
                            status |= StatusFlags.DIGITAL_UNRELIABLE_NOT_SET;
                        }

                        if ((stateFlags & MeasurementStateFlags.OverRangeError) > 0 ||
                            (stateFlags & MeasurementStateFlags.UnderRangeError) > 0 ||
                            (stateFlags & MeasurementStateFlags.AlarmHigh) > 0 ||
                            (stateFlags & MeasurementStateFlags.AlarmLow) > 0 ||
                            (stateFlags & MeasurementStateFlags.WarningHigh) > 0 ||
                            (stateFlags & MeasurementStateFlags.WarningLow) > 0)
                        {
                            status |= StatusFlags.DIGITAL_WARNING_NOT_SET;
                        }
                    }
                }
            }

            return(status);
        }
コード例 #23
0
ファイル: StatusFlags.cs プロジェクト: sotaria/gsf
 /// <summary>
 /// Maps <see cref="MeasurementStateFlags"/> to eDNA status (short value).
 /// </summary>
 /// <param name="stateFlags">Flags to map.</param>
 /// <param name="type">Data type of measurement.</param>
 /// <param name="digitalSet">Flag that determines if digital value is set.</param>
 /// <returns>eDNA status mapped from <see cref="MeasurementStateFlags"/>.</returns>
 public static short MapToStatus(this MeasurementStateFlags stateFlags, DataType type = DataType.Analog, bool digitalSet = false)
 {
     return((short)stateFlags.MapToStatusFlags(type, digitalSet));
 }
コード例 #24
0
            /// <summary>
            /// Starts a query that will read data source values, given a set of point IDs and targets, over a time range.
            /// </summary>
            /// <param name="startTime">Start-time for query.</param>
            /// <param name="stopTime">Stop-time for query.</param>
            /// <param name="interval">Interval from Grafana request.</param>
            /// <param name="includePeaks">Flag that determines if decimated data should include min/max interval peaks over provided time range.</param>
            /// <param name="targetMap">Set of IDs with associated targets to query.</param>
            /// <returns>Queried data source data in terms of value and time.</returns>
            protected override IEnumerable <DataSourceValue> QueryDataSourceValues(DateTime startTime, DateTime stopTime, string interval, bool includePeaks, Dictionary <ulong, string> targetMap)
            {
                SnapServer server = GetAdapterInstance(InstanceName)?.Server?.Host;

                if (server == null)
                {
                    yield break;
                }

                using (SnapClient connection = SnapClient.Connect(server))
                    using (ClientDatabaseBase <HistorianKey, HistorianValue> database = connection.GetDatabase <HistorianKey, HistorianValue>(InstanceName))
                    {
                        if (database == null)
                        {
                            yield break;
                        }

                        if (!TryParseInterval(interval, out TimeSpan resolutionInterval))
                        {
                            Resolution resolution = TrendValueAPI.EstimatePlotResolution(InstanceName, startTime, stopTime, targetMap.Keys);
                            resolutionInterval = resolution.GetInterval();
                        }

                        BaselineTimeInterval timeInterval = BaselineTimeInterval.Second;

                        if (resolutionInterval.Ticks < Ticks.PerMinute)
                        {
                            timeInterval = BaselineTimeInterval.Second;
                        }
                        else if (resolutionInterval.Ticks < Ticks.PerHour)
                        {
                            timeInterval = BaselineTimeInterval.Minute;
                        }
                        else if (resolutionInterval.Ticks == Ticks.PerHour)
                        {
                            timeInterval = BaselineTimeInterval.Hour;
                        }

                        startTime = startTime.BaselinedTimestamp(timeInterval);
                        stopTime  = stopTime.BaselinedTimestamp(timeInterval);

                        if (startTime == stopTime)
                        {
                            stopTime = stopTime.AddSeconds(1.0D);
                        }

                        SeekFilterBase <HistorianKey> timeFilter;

                        // Set timestamp filter resolution
                        if (includePeaks || resolutionInterval == TimeSpan.Zero)
                        {
                            // Full resolution query
                            timeFilter = TimestampSeekFilter.CreateFromRange <HistorianKey>(startTime, stopTime);
                        }
                        else
                        {
                            // Interval query
                            timeFilter = TimestampSeekFilter.CreateFromIntervalData <HistorianKey>(startTime, stopTime, resolutionInterval, new TimeSpan(TimeSpan.TicksPerMillisecond));
                        }

                        // Setup point ID selections
                        MatchFilterBase <HistorianKey, HistorianValue> pointFilter = PointIdMatchFilter.CreateFromList <HistorianKey, HistorianValue>(targetMap.Keys);
                        Dictionary <ulong, ulong> lastTimes = new Dictionary <ulong, ulong>(targetMap.Count);
                        Dictionary <ulong, Peak>  peaks     = new Dictionary <ulong, Peak>(targetMap.Count);
                        ulong resolutionSpan = (ulong)resolutionInterval.Ticks;

                        if (includePeaks)
                        {
                            resolutionSpan *= 2UL;
                        }

                        // Start stream reader for the provided time window and selected points
                        using (TreeStream <HistorianKey, HistorianValue> stream = database.Read(SortedTreeEngineReaderOptions.Default, timeFilter, pointFilter))
                        {
                            HistorianKey   key   = new HistorianKey();
                            HistorianValue value = new HistorianValue();
                            Peak           peak  = Peak.Default;

                            while (stream.Read(key, value))
                            {
                                ulong pointID    = key.PointID;
                                ulong timestamp  = key.Timestamp;
                                float pointValue = value.AsSingle;

                                if (includePeaks)
                                {
                                    peak = peaks.GetOrAdd(pointID, _ => new Peak());
                                    peak.Set(pointValue, timestamp);
                                }

                                if (resolutionSpan > 0UL && timestamp - lastTimes.GetOrAdd(pointID, 0UL) < resolutionSpan)
                                {
                                    continue;
                                }

                                // New value is ready for publication
                                string target = targetMap[pointID];
                                MeasurementStateFlags flags = (MeasurementStateFlags)value.Value3;

                                if (includePeaks)
                                {
                                    if (peak.MinTimestamp > 0UL)
                                    {
                                        yield return(new DataSourceValue
                                        {
                                            Target = target,
                                            Value = peak.Min,
                                            Time = (peak.MinTimestamp - m_baseTicks) / (double)Ticks.PerMillisecond,
                                            Flags = flags
                                        });
                                    }

                                    if (peak.MaxTimestamp != peak.MinTimestamp)
                                    {
                                        yield return(new DataSourceValue
                                        {
                                            Target = target,
                                            Value = peak.Max,
                                            Time = (peak.MaxTimestamp - m_baseTicks) / (double)Ticks.PerMillisecond,
                                            Flags = flags
                                        });
                                    }

                                    peak.Reset();
                                }
                                else
                                {
                                    yield return(new DataSourceValue
                                    {
                                        Target = target,
                                        Value = pointValue,
                                        Time = (timestamp - m_baseTicks) / (double)Ticks.PerMillisecond,
                                        Flags = flags
                                    });
                                }

                                lastTimes[pointID] = timestamp;
                            }
                        }
                    }
            }
コード例 #25
0
        /// <summary>
        /// Queues a collection of measurements for processing.
        /// </summary>
        /// <param name="measurements">Collection of measurements to queue for processing.</param>
        /// <remarks>
        /// Measurements are filtered against the defined <see cref="InputMeasurementKeys"/> so we override method
        /// so that dynamic updates to keys will be synchronized with filtering to prevent interference.
        /// </remarks>
        // IMPORTANT: TSSC is sensitive to order - always make sure this function gets called sequentially, concurrent
        // calls to this function can cause TSSC parsing to get out of sequence and fail
        public override void QueueMeasurementsForProcessing(IEnumerable <IMeasurement> measurements)
        {
            if ((object)measurements == null)
            {
                return;
            }

            if (!m_startTimeSent && measurements.Any())
            {
                m_startTimeSent = true;

                IMeasurement measurement = measurements.FirstOrDefault(m => (object)m != null);
                Ticks        timestamp   = 0;

                if ((object)measurement != null)
                {
                    timestamp = measurement.Timestamp;
                }

                m_parent.SendDataStartTime(m_clientID, timestamp);
            }

            if (m_isNaNFiltered)
            {
                measurements = measurements.Where(measurement => !double.IsNaN(measurement.Value));
            }

            if (!measurements.Any() || !Enabled)
            {
                return;
            }

            if (TrackLatestMeasurements)
            {
                double publishInterval;

                // Keep track of latest measurements
                base.QueueMeasurementsForProcessing(measurements);
                publishInterval = m_publishInterval > 0 ? m_publishInterval : LagTime;

                if (DateTime.UtcNow.Ticks > m_lastPublishTime + Ticks.FromSeconds(publishInterval))
                {
                    List <IMeasurement> currentMeasurements = new List <IMeasurement>();
                    Measurement         newMeasurement;

                    // Create a new set of measurements that represent the latest known values setting value to NaN if it is old
                    foreach (TemporalMeasurement measurement in LatestMeasurements)
                    {
                        MeasurementStateFlags timeQuality = measurement.Timestamp.TimeIsValid(RealTime, measurement.LagTime, measurement.LeadTime)
                            ? MeasurementStateFlags.Normal
                            : MeasurementStateFlags.BadTime;

                        newMeasurement = new Measurement
                        {
                            Metadata   = measurement.Metadata,
                            Value      = measurement.Value,
                            Timestamp  = measurement.Timestamp,
                            StateFlags = measurement.StateFlags | timeQuality
                        };

                        currentMeasurements.Add(newMeasurement);
                    }

                    ProcessMeasurements(currentMeasurements);
                }
            }
            else
            {
                ProcessMeasurements(measurements);
            }
        }