Пример #1
0
 private List <FaultLocationAlgorithm> GetFaultLocationAlgorithms(FaultLocationInfoDataContext faultLocationInfo)
 {
     return(faultLocationInfo.FaultLocationAlgorithms
            .OrderBy(dbAlgorithm => dbAlgorithm.ExecutionOrder)
            .ThenBy(dbAlgorithm => dbAlgorithm.ID)
            .Select(dbAlgorithm => LoadAlgorithm <FaultLocationAlgorithm>(dbAlgorithm.AssemblyName, dbAlgorithm.TypeName, dbAlgorithm.MethodName))
            .ToList());
 }
Пример #2
0
        private static void LoadFaultLocationAlgorithms(XElement analyticsElement, FaultLocationInfoDataContext faultLocationInfo)
        {
            List <FaultLocationAlgorithm> oldFaultLocationAlgorithms = faultLocationInfo.FaultLocationAlgorithms.ToList();

            List <FaultLocationAlgorithm> newFaultLocationAlgorithms = analyticsElement
                                                                       .Elements("faultLocation")
                                                                       .Select(ToFaultLocationAlgorithm)
                                                                       .ToList();

            faultLocationInfo.FaultLocationAlgorithms.InsertAllOnSubmit(newFaultLocationAlgorithms
                                                                        .Where(algorithm1 => !oldFaultLocationAlgorithms.Any(algorithm2 => IsMatch(algorithm1, algorithm2))));

            faultLocationInfo.FaultLocationAlgorithms.DeleteAllOnSubmit(oldFaultLocationAlgorithms
                                                                        .Where(algorithm1 => !newFaultLocationAlgorithms.Any(algorithm2 => IsMatch(algorithm1, algorithm2))));
        }
Пример #3
0
        public static void Write(string connectionString, int eventID, string originalFilePath, string filePath)
        {
            MeterInfoDataContext         meterInfo         = new MeterInfoDataContext(connectionString);
            FaultLocationInfoDataContext faultLocationInfo = new FaultLocationInfoDataContext(connectionString);

            MeterData.EventRow eventRow;

            Meter     meter;
            DataGroup waveFormData;

            FaultLocationData.FaultCurveDataTable faultCurveTable;
            List <FaultSegment> segments;

            using (EventTableAdapter eventAdapter = new EventTableAdapter())
            {
                eventAdapter.Connection.ConnectionString = connectionString;
                eventRow = eventAdapter.GetDataByID(eventID).FirstOrDefault();
            }

            if ((object)eventRow == null)
            {
                throw new InvalidOperationException(string.Format("Event with ID {0} not found", eventID));
            }

            meter = meterInfo.Meters.FirstOrDefault(dbMeter => dbMeter.ID == eventRow.MeterID);

            waveFormData = new DataGroup();
            waveFormData.FromData(meter, eventRow.Data);

            using (FaultCurveTableAdapter faultCurveAdapter = new FaultCurveTableAdapter())
            {
                faultCurveAdapter.Connection.ConnectionString = connectionString;
                faultCurveTable = faultCurveAdapter.GetDataBy(eventID);
            }

            segments = faultLocationInfo.FaultSegments
                       .Where(segment => segment.EventID == eventID)
                       .OrderBy(segment => segment.StartSample)
                       .ToList();

            Write(meter, waveFormData, faultCurveTable, segments, originalFilePath, filePath);
        }
Пример #4
0
    public static List <FlotSeries> GetFlotInfo(int eventID)
    {
        using (DbAdapterContainer dbAdapterContainer = new DbAdapterContainer(ConnectionString))
            using (AdoDataConnection connection = new AdoDataConnection(dbAdapterContainer.Connection, typeof(SqlDataAdapter), false))
            {
                EventTableAdapter            eventAdapter = dbAdapterContainer.GetAdapter <EventTableAdapter>();
                MeterInfoDataContext         meterInfo    = dbAdapterContainer.GetAdapter <MeterInfoDataContext>();
                FaultLocationInfoDataContext faultInfo    = dbAdapterContainer.GetAdapter <FaultLocationInfoDataContext>();

                MeterData.EventRow eventRow = eventAdapter.GetDataByID(eventID).FirstOrDefault();

                if ((object)eventRow == null)
                {
                    return(new List <FlotSeries>());
                }

                return(GetWaveformInfo(meterInfo.Series, eventRow.MeterID, eventRow.LineID)
                       .Select(ToFlotSeries)
                       .Concat(CycleDataInfo)
                       .Concat(GetFaultCurveInfo(connection, eventID).Select(ToFlotSeries))
                       .ToList());
            }
    }
Пример #5
0
        public static List <FlotSeries> GetFlotInfo(int eventID)
        {
            using (DbAdapterContainer dbAdapterContainer = new DbAdapterContainer(ConnectionString))
                using (AdoDataConnection connection = new AdoDataConnection(dbAdapterContainer.Connection, typeof(SqlDataAdapter), false))
                {
                    EventTableAdapter            eventAdapter = dbAdapterContainer.GetAdapter <EventTableAdapter>();
                    MeterInfoDataContext         meterInfo    = dbAdapterContainer.GetAdapter <MeterInfoDataContext>();
                    FaultLocationInfoDataContext faultInfo    = dbAdapterContainer.GetAdapter <FaultLocationInfoDataContext>();

                    MeterData.EventRow eventRow = eventAdapter.GetDataByID(eventID).FirstOrDefault();

                    if ((object)eventRow == null)
                    {
                        return(new List <FlotSeries>());
                    }

                    List <Series> waveformInfo = GetWaveformInfo(meterInfo.Series, eventRow.MeterID, eventRow.LineID);

                    var lookup = waveformInfo
                                 .Where(info => info.Channel.MeasurementCharacteristic.Name == "Instantaneous")
                                 .Where(info => new string[] { "Instantaneous", "Values" }.Contains(info.SeriesType.Name))
                                 .Select(info => new { MeasurementType = info.Channel.MeasurementType.Name, Phase = info.Channel.Phase.Name })
                                 .Distinct()
                                 .ToDictionary(info => info);

                    IEnumerable <FlotSeries> cycleDataInfo = CycleDataInfo
                                                             .Where(info => lookup.ContainsKey(new { info.MeasurementType, info.Phase }))
                                                             .Select(info => info.Clone());

                    return(GetWaveformInfo(meterInfo.Series, eventRow.MeterID, eventRow.LineID)
                           .Select(ToFlotSeries)
                           .Concat(cycleDataInfo)
                           .Concat(GetFaultCurveInfo(connection, eventID).Select(ToFlotSeries))
                           .ToList());
                }
        }
Пример #6
0
        private static void Migrate(string connectionString, string deviceDefinitionsFile)
        {
            LookupTables lookupTables;

            MeterLocation     meterLocation;
            MeterLocation     remoteMeterLocation;
            MeterLocationLine localLink;
            MeterLocationLine remoteLink;

            Meter         meter;
            Line          line;
            Series        series;
            Channel       channel;
            OutputChannel outputChannel;

            Dictionary <string, Tuple <Series, OutputChannel> > channelLookup;
            Tuple <Series, OutputChannel> tuple;
            string channelKey;
            int    outputChannelIndex;

            LineImpedance   lineImpedance;
            SourceImpedance localSourceImpedance;
            SourceImpedance remoteSourceImpedance;

            XDocument       document       = XDocument.Load(deviceDefinitionsFile);
            List <XElement> deviceElements = document.Elements().Elements("device").ToList();
            XElement        deviceAttributes;
            XElement        impedancesElement;

            List <Tuple <Line, LineImpedance> > lineImpedances = new List <Tuple <Line, LineImpedance> >();
            List <Tuple <MeterLocationLine, SourceImpedance> > sourceImpedances = new List <Tuple <MeterLocationLine, SourceImpedance> >();
            List <Tuple <Series, OutputChannel> > outputChannels = new List <Tuple <Series, OutputChannel> >();

            ProgressTracker progressTracker = new ProgressTracker(deviceElements.Count);

            using (MeterInfoDataContext meterInfo = new MeterInfoDataContext(connectionString))
                using (FaultLocationInfoDataContext faultLocationInfo = new FaultLocationInfoDataContext(connectionString))
                {
                    // Load existing fault location configuration from the database
                    progressTracker.StartPendingMessage("Loading existing fault location configuration from database...");
                    lookupTables = new LookupTables(meterInfo, faultLocationInfo);
                    lookupTables.CreateLookups(document);
                    progressTracker.EndPendingMessage();

                    // Load updates to fault location algorithms into the database
                    progressTracker.StartPendingMessage("Loading updates to fault location algorithms into the database...");

                    foreach (XElement analyticsElement in document.Elements().Elements("analytics"))
                    {
                        LoadFaultLocationAlgorithms(analyticsElement, faultLocationInfo);
                    }

                    faultLocationInfo.SubmitChanges();

                    progressTracker.EndPendingMessage();

                    // Load updates to device configuration into the database
                    progressTracker.WriteMessage(string.Format("Beginning migration of {0} device configurations...", deviceElements.Count));

                    foreach (XElement deviceElement in deviceElements)
                    {
                        lineImpedances.Clear();
                        sourceImpedances.Clear();
                        outputChannels.Clear();

                        // Get the element representing a device's attributes
                        deviceAttributes = deviceElement.Element("attributes") ?? new XElement("attributes");

                        // Attempt to find existing configuration for this device and update the meter with any changes to the device's attributes
                        meter = lookupTables.MeterLookup.GetOrAdd((string)deviceElement.Attribute("id"), assetKey => new Meter()
                        {
                            AssetKey = assetKey
                        });
                        LoadMeterAttributes(meter, deviceAttributes);

                        // Now that we know what meter we are processing, display a message to indicate that we are parsing this meter's configuration
                        progressTracker.StartPendingMessage(string.Format("Loading configuration for meter {0} ({1})...", meter.Name, meter.AssetKey));

                        // Attempt to find existing configuration for the location of the meter and update with configuration changes
                        meterLocation = lookupTables.MeterLocationLookup.GetOrAdd((string)deviceAttributes.Element("stationID"), assetKey => new MeterLocation()
                        {
                            AssetKey = assetKey
                        });
                        LoadMeterLocationAttributes(meterLocation, deviceAttributes);

                        // Link the meter location to the meter
                        meter.MeterLocation = meterLocation;

                        // Load updates to line configuration into the database
                        foreach (XElement lineElement in deviceElement.Elements("lines").Elements("line"))
                        {
                            // Attempt to find existing configuration for the line and update with configuration changes
                            line = lookupTables.LineLookup.GetOrAdd((string)lineElement.Attribute("id"), assetKey => new Line()
                            {
                                AssetKey = assetKey
                            });
                            LoadLineAttributes(line, lineElement);

                            // Provide a link between this line and the location housing the meter
                            Link(meter, line, lineElement, lookupTables.MeterLineLookup);
                            localLink = Link(meterLocation, line, lookupTables.MeterLocationLineLookup);

                            if ((string)lineElement.Element("endStationID") != null)
                            {
                                // Attempt to find existing configuration for the location of the other end of the line and update with configuration changes
                                remoteMeterLocation = lookupTables.MeterLocationLookup.GetOrAdd((string)lineElement.Element("endStationID"), assetKey => new MeterLocation()
                                {
                                    AssetKey = assetKey
                                });
                                LoadRemoteMeterLocationAttributes(remoteMeterLocation, lineElement);

                                // Provide a link between this line and the remote location
                                remoteLink = Link(remoteMeterLocation, line, lookupTables.MeterLocationLineLookup);
                            }
                            else
                            {
                                // Set remote meter location to null so we
                                // know later that there isn't one defined
                                remoteMeterLocation = null;
                                remoteLink          = null;
                            }

                            // Get a lookup table for the channels monitoring this line
                            channelLookup      = lookupTables.GetChannelLookup(meter, line);
                            outputChannelIndex = 0;

                            foreach (XElement channelElement in lineElement.Elements("channels").Elements())
                            {
                                channelKey = channelElement.Name.LocalName;

                                // Attempt to find an existing channel corresponding to this element
                                if (channelLookup.TryGetValue(channelKey, out tuple))
                                {
                                    series        = tuple.Item1;
                                    channel       = series.Channel;
                                    outputChannel = tuple.Item2;
                                }
                                else
                                {
                                    channel       = new Channel();
                                    series        = new Series();
                                    outputChannel = new OutputChannel();

                                    channelLookup.Add(channelKey, Tuple.Create(series, outputChannel));
                                }

                                // Load updates to channel configuration into the database
                                LoadChannelAttributes(meter, line, remoteMeterLocation, channel, channelKey, lookupTables);
                                LoadSeriesAttributes(channel, series, channelElement, lookupTables);

                                outputChannel.ChannelKey = channelKey;
                                outputChannel.LoadOrder  = outputChannelIndex;
                                outputChannels.Add(Tuple.Create(series, outputChannel));

                                outputChannelIndex++;
                            }

                            impedancesElement = lineElement.Element("impedances") ?? new XElement("impedances");

                            // Attempt to find existing impedance configuration for the line and update with configuration changes
                            lineImpedance = lookupTables.LineImpedanceLookup.GetOrAdd(line, ln => new LineImpedance());
                            LoadLineImpedanceAttributes(lineImpedance, impedancesElement);
                            lineImpedances.Add(Tuple.Create(line, lineImpedance));

                            // Attempt to find existing impedance configuration for the meter's location and update with configuration changes
                            localSourceImpedance = lookupTables.SourceImpedanceLookup.GetOrAdd(localLink, location => new SourceImpedance());
                            LoadLocalSourceImpedanceAttributes(localSourceImpedance, impedancesElement);
                            sourceImpedances.Add(Tuple.Create(localLink, localSourceImpedance));

                            if ((object)remoteLink != null)
                            {
                                // Attempt to find existing impedance configuration for the remote location and update with configuration changes
                                remoteSourceImpedance = lookupTables.SourceImpedanceLookup.GetOrAdd(remoteLink, location => new SourceImpedance());
                                LoadRemoteSourceImpedanceAttributes(remoteSourceImpedance, impedancesElement);
                                sourceImpedances.Add(Tuple.Create(remoteLink, remoteSourceImpedance));
                            }
                        }

                        if (meter.ID == 0)
                        {
                            meterInfo.Meters.InsertOnSubmit(meter);
                        }

                        meterInfo.SubmitChanges();

                        // Load updates to line impedance configuration into the database
                        foreach (Tuple <Line, LineImpedance> mapping in lineImpedances)
                        {
                            line                 = mapping.Item1;
                            lineImpedance        = mapping.Item2;
                            lineImpedance.LineID = line.ID;

                            if (lineImpedance.ID == 0)
                            {
                                faultLocationInfo.LineImpedances.InsertOnSubmit(lineImpedance);
                            }
                        }

                        // Load updates to source impedance configuration into the database
                        foreach (Tuple <MeterLocationLine, SourceImpedance> mapping in sourceImpedances)
                        {
                            localLink            = mapping.Item1;
                            localSourceImpedance = mapping.Item2;
                            localSourceImpedance.MeterLocationLineID = localLink.ID;

                            if (localSourceImpedance.ID == 0 && (localSourceImpedance.RSrc != 0.0D || localSourceImpedance.XSrc != 0.0D))
                            {
                                faultLocationInfo.SourceImpedances.InsertOnSubmit(localSourceImpedance);
                            }
                        }

                        // Load updates to source impedance configuration into the database
                        foreach (Tuple <Series, OutputChannel> mapping in outputChannels)
                        {
                            series                 = mapping.Item1;
                            outputChannel          = mapping.Item2;
                            outputChannel.SeriesID = series.ID;

                            if (outputChannel.ID == 0)
                            {
                                faultLocationInfo.OutputChannels.InsertOnSubmit(outputChannel);
                            }
                        }

                        faultLocationInfo.SubmitChanges();

                        progressTracker.EndPendingMessage();

                        // Increment the progress counter
                        progressTracker.MakeProgress();
                    }
                }
        }
Пример #7
0
 private Dictionary <MeterLocationLine, SourceImpedance> GetSourceImpedanceLookup(IEnumerable <MeterLocationLine> meterLocationLines, FaultLocationInfoDataContext faultLocationInfo)
 {
     return(faultLocationInfo.SourceImpedances
            .Join(meterLocationLines, impedance => impedance.MeterLocationLineID, meterLocationLine => meterLocationLine.ID, Tuple.Create)
            .ToDictionary(tuple => tuple.Item2, tuple => tuple.Item1));
 }
Пример #8
0
 private Dictionary <Line, LineImpedance> GetLineImpedanceLookup(IEnumerable <Line> lines, FaultLocationInfoDataContext faultLocationInfo)
 {
     return(faultLocationInfo.LineImpedances
            .Join(lines, impedance => impedance.LineID, line => line.ID, Tuple.Create)
            .ToDictionary(tuple => tuple.Item2, tuple => tuple.Item1));
 }
Пример #9
0
 public LookupTables(MeterInfoDataContext meterInfo, FaultLocationInfoDataContext faultLocationInfo)
 {
     m_meterInfo         = meterInfo;
     m_faultLocationInfo = faultLocationInfo;
 }
Пример #10
0
        public List <FlotSeries> GetFlotData(int eventID, List <int> seriesIndexes)
        {
            List <FlotSeries> flotSeriesList = new List <FlotSeries>();

            using (DbAdapterContainer dbAdapterContainer = new DbAdapterContainer(ConnectionString))
                using (AdoDataConnection connection = new AdoDataConnection(dbAdapterContainer.Connection, typeof(SqlDataAdapter), false))
                {
                    EventTableAdapter            eventAdapter      = dbAdapterContainer.GetAdapter <EventTableAdapter>();
                    EventDataTableAdapter        eventDataAdapter  = dbAdapterContainer.GetAdapter <EventDataTableAdapter>();
                    FaultCurveTableAdapter       faultCurveAdapter = dbAdapterContainer.GetAdapter <FaultCurveTableAdapter>();
                    MeterInfoDataContext         meterInfo         = dbAdapterContainer.GetAdapter <MeterInfoDataContext>();
                    FaultLocationInfoDataContext faultLocationInfo = dbAdapterContainer.GetAdapter <FaultLocationInfoDataContext>();

                    MeterData.EventRow eventRow = eventAdapter.GetDataByID(eventID).FirstOrDefault();
                    Meter meter = meterInfo.Meters.First(m => m.ID == eventRow.MeterID);

                    List <FlotSeries> flotInfo = GetFlotInfo(eventID);
                    DateTime          epoch    = new DateTime(1970, 1, 1);

                    Lazy <Dictionary <int, DataSeries> > waveformData = new Lazy <Dictionary <int, DataSeries> >(() =>
                    {
                        return(ToDataGroup(meter, eventDataAdapter.GetTimeDomainData(eventRow.EventDataID)).DataSeries
                               .ToDictionary(dataSeries => dataSeries.SeriesInfo.ID));
                    });

                    Lazy <DataGroup> cycleData = new Lazy <DataGroup>(() => ToDataGroup(meter, eventDataAdapter.GetFrequencyDomainData(eventRow.EventDataID)));

                    Lazy <Dictionary <string, DataSeries> > faultCurveData = new Lazy <Dictionary <string, DataSeries> >(() =>
                    {
                        return(faultCurveAdapter
                               .GetDataBy(eventRow.ID)
                               .Select(faultCurve => new
                        {
                            Algorithm = faultCurve.Algorithm,
                            DataGroup = ToDataGroup(meter, faultCurve.Data)
                        })
                               .Where(obj => obj.DataGroup.DataSeries.Count > 0)
                               .ToDictionary(obj => obj.Algorithm, obj => obj.DataGroup[0]));
                    });

                    foreach (int index in seriesIndexes)
                    {
                        DataSeries dataSeries = null;
                        FlotSeries flotSeries;

                        if (index >= flotInfo.Count)
                        {
                            continue;
                        }

                        flotSeries = flotInfo[index];

                        if (flotSeries.FlotType == FlotSeriesType.Waveform)
                        {
                            if (!waveformData.Value.TryGetValue(flotSeries.SeriesID, out dataSeries))
                            {
                                continue;
                            }
                        }
                        else if (flotSeries.FlotType == FlotSeriesType.Cycle)
                        {
                            dataSeries = cycleData.Value.DataSeries
                                         .Where(series => series.SeriesInfo.Channel.MeasurementType.Name == flotSeries.MeasurementType)
                                         .Where(series => series.SeriesInfo.Channel.Phase.Name == flotSeries.Phase)
                                         .Skip(flotSeries.SeriesID)
                                         .FirstOrDefault();

                            if ((object)dataSeries == null)
                            {
                                continue;
                            }
                        }
                        else if (flotSeries.FlotType == FlotSeriesType.Fault)
                        {
                            string algorithm = flotSeries.ChannelName;

                            if (!faultCurveData.Value.TryGetValue(algorithm, out dataSeries))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }

                        foreach (DataPoint dataPoint in dataSeries.DataPoints)
                        {
                            if (!double.IsNaN(dataPoint.Value))
                            {
                                flotSeries.DataPoints.Add(new double[] { dataPoint.Time.Subtract(epoch).TotalMilliseconds, dataPoint.Value });
                            }
                        }

                        flotSeriesList.Add(flotSeries);
                    }
                }

            return(flotSeriesList);
        }
Пример #11
0
    public List <FlotSeries> GetFlotData(int eventID, List <int> seriesIndexes)
    {
        List <FlotSeries> flotSeriesList = new List <FlotSeries>();

        using (DbAdapterContainer dbAdapterContainer = new DbAdapterContainer(ConnectionString))
            using (AdoDataConnection connection = new AdoDataConnection(dbAdapterContainer.Connection, typeof(SqlDataAdapter), false))
            {
                EventTableAdapter            eventAdapter      = dbAdapterContainer.GetAdapter <EventTableAdapter>();
                EventDataTableAdapter        eventDataAdapter  = dbAdapterContainer.GetAdapter <EventDataTableAdapter>();
                FaultCurveTableAdapter       faultCurveAdapter = dbAdapterContainer.GetAdapter <FaultCurveTableAdapter>();
                MeterInfoDataContext         meterInfo         = dbAdapterContainer.GetAdapter <MeterInfoDataContext>();
                FaultLocationInfoDataContext faultLocationInfo = dbAdapterContainer.GetAdapter <FaultLocationInfoDataContext>();

                MeterData.EventRow eventRow = eventAdapter.GetDataByID(eventID).FirstOrDefault();
                Meter meter = meterInfo.Meters.First(m => m.ID == eventRow.MeterID);

                List <Series> waveformInfo   = GetWaveformInfo(meterInfo.Series, eventRow.MeterID, eventRow.LineID);
                List <string> faultCurveInfo = GetFaultCurveInfo(connection, eventID);
                DateTime      epoch          = new DateTime(1970, 1, 1);

                Lazy <Dictionary <int, DataSeries> > waveformData = new Lazy <Dictionary <int, DataSeries> >(() =>
                {
                    return(ToDataGroup(meter, eventDataAdapter.GetTimeDomainData(eventRow.EventDataID)).DataSeries
                           .ToDictionary(dataSeries => dataSeries.SeriesInfo.ID));
                });

                Lazy <DataGroup> cycleData = new Lazy <DataGroup>(() => ToDataGroup(meter, eventDataAdapter.GetFrequencyDomainData(eventRow.EventDataID)));

                Lazy <Dictionary <string, DataSeries> > faultCurveData = new Lazy <Dictionary <string, DataSeries> >(() =>
                {
                    return(faultCurveAdapter
                           .GetDataBy(eventRow.ID)
                           .Select(faultCurve => new
                    {
                        Algorithm = faultCurve.Algorithm,
                        DataGroup = ToDataGroup(meter, faultCurve.Data)
                    })
                           .Where(obj => obj.DataGroup.DataSeries.Count > 0)
                           .ToDictionary(obj => obj.Algorithm, obj => obj.DataGroup[0]));
                });

                foreach (int index in seriesIndexes)
                {
                    DataSeries dataSeries = null;
                    FlotSeries flotSeries = null;

                    int waveformIndex   = index;
                    int cycleIndex      = waveformIndex - waveformInfo.Count;
                    int faultCurveIndex = cycleIndex - CycleDataInfo.Count;

                    if (waveformIndex < waveformInfo.Count)
                    {
                        if (!waveformData.Value.TryGetValue(waveformInfo[index].ID, out dataSeries))
                        {
                            continue;
                        }

                        flotSeries = ToFlotSeries(waveformInfo[index]);
                    }
                    else if (cycleIndex < CycleDataInfo.Count)
                    {
                        if (cycleIndex >= cycleData.Value.DataSeries.Count)
                        {
                            continue;
                        }

                        dataSeries = cycleData.Value[cycleIndex];

                        flotSeries = new FlotSeries()
                        {
                            MeasurementType           = CycleDataInfo[cycleIndex].MeasurementType,
                            MeasurementCharacteristic = CycleDataInfo[cycleIndex].MeasurementCharacteristic,
                            Phase      = CycleDataInfo[cycleIndex].Phase,
                            SeriesType = CycleDataInfo[cycleIndex].SeriesType
                        };
                    }
                    else if (faultCurveIndex < faultCurveInfo.Count)
                    {
                        string algorithm = faultCurveInfo[faultCurveIndex];

                        if (!faultCurveData.Value.TryGetValue(algorithm, out dataSeries))
                        {
                            continue;
                        }

                        flotSeries = ToFlotSeries(faultCurveInfo[faultCurveIndex]);
                    }
                    else
                    {
                        continue;
                    }

                    foreach (DataPoint dataPoint in dataSeries.DataPoints)
                    {
                        if (!double.IsNaN(dataPoint.Value))
                        {
                            flotSeries.DataPoints.Add(new double[] { dataPoint.Time.Subtract(epoch).TotalMilliseconds, dataPoint.Value });
                        }
                    }

                    flotSeriesList.Add(flotSeries);
                }
            }

        return(flotSeriesList);
    }
Пример #12
0
        private bool?CheckFaultDetectionLogic(MeterDataSet meterDataSet, DataGroup dataGroup)
        {
            MeterInfoDataContext         meterInfo = m_dbAdapterContainer.GetAdapter <MeterInfoDataContext>();
            FaultLocationInfoDataContext faultInfo = m_dbAdapterContainer.GetAdapter <FaultLocationInfoDataContext>();

            string expressionText;
            int    meterLineID;

            expressionText = null;

            // Find MeterLine record corresponding to the meter that produced
            // the data and the line associated with the data group
            meterLineID = meterInfo.MeterLines
                          .Where(meterLine => meterLine.MeterID == meterDataSet.Meter.ID)
                          .Where(meterLine => meterLine.LineID == dataGroup.Line.ID)
                          .Select(meterLine => (int?)meterLine.ID)
                          .FirstOrDefault() ?? -1;

            if (meterLineID > 0)
            {
                // Find fault detection logic defined for the meter and line
                expressionText = faultInfo.FaultDetectionLogics
                                 .Where(logic => logic.MeterLineID == meterLineID)
                                 .Select(logic => logic.Expression)
                                 .FirstOrDefault();
            }

            try
            {
                if ((object)expressionText == null)
                {
                    throw new Exception($"Expression text is not defined for line '{dataGroup.Line.AssetKey}'.");
                }

                // Parse fault detection logic into a boolean expression
                BooleanExpression expression = new BooleanExpression(expressionText);

                // Put digital values into a lookup table
                Dictionary <string, bool> digitalLookup = dataGroup.DataSeries
                                                          .Where(series => series.SeriesInfo.Channel.MeasurementType.Name.Equals("Digital", StringComparison.OrdinalIgnoreCase))
                                                          .GroupBy(series => series.SeriesInfo.Channel.Name)
                                                          .Where(grouping => grouping.Count() == 1)
                                                          .ToDictionary(grouping => grouping.Key, grouping => grouping.Single().DataPoints.Any(dataPoint => Convert.ToBoolean(dataPoint.Value)), StringComparer.OrdinalIgnoreCase);

                // Apply the digital values to the variables in the boolean expression
                foreach (BooleanExpression.Variable variable in expression.Variables)
                {
                    if (!digitalLookup.TryGetValue(variable.Identifier, out variable.Value))
                    {
                        throw new Exception($"Channel '{variable.Identifier}' that was required for fault detection logic was missing from the meter data set.");
                    }
                }

                // Evaluate the boolean expression
                return(expression.Evaluate());
            }
            catch (Exception ex)
            {
                // Log the exception as a warning
                Log.Warn(ex.Message, ex);
                return(null);
            }
        }
Пример #13
0
 public override void Prepare(DbAdapterContainer dbAdapterContainer)
 {
     m_meterInfo         = dbAdapterContainer.GetAdapter <MeterInfoDataContext>();
     m_faultLocationInfo = dbAdapterContainer.GetAdapter <FaultLocationInfoDataContext>();
 }