Ejemplo n.º 1
0
        private BreakerOperation GetBreakerOperation(AdoDataConnection connection, int eventID, string breakerNumber, BreakerTiming breakerTiming, PhaseTiming aPhaseTiming, PhaseTiming bPhaseTiming, PhaseTiming cPhaseTiming)
        {
            TableOperations <Phase> phaseTable = new TableOperations <Phase>(connection);
            TableOperations <openXDA.Model.BreakerOperationType> breakerOperationTypeTable = new TableOperations <openXDA.Model.BreakerOperationType>(connection);

            double maxTiming          = GetMaxTiming(breakerTiming, aPhaseTiming, bPhaseTiming, cPhaseTiming);
            string phase              = GetLatestPhase(aPhaseTiming, bPhaseTiming, cPhaseTiming);
            BreakerOperationType type = GetBreakerOperationType(maxTiming, breakerTiming.Speed);

            return(new BreakerOperation()
            {
                EventID = eventID,
                PhaseID = phaseTable.GetOrAdd(phase).ID,
                BreakerOperationTypeID = breakerOperationTypeTable.GetOrAdd(type.ToString()).ID,
                BreakerNumber = breakerNumber,
                TripCoilEnergized = breakerTiming.TimeEnergized.Time,
                StatusBitSet = breakerTiming.IsValid ? breakerTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                StatusBitChatter = breakerTiming.StatusChatter,
                APhaseCleared = aPhaseTiming.IsValid ? aPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                BPhaseCleared = bPhaseTiming.IsValid ? bPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                CPhaseCleared = cPhaseTiming.IsValid ? cPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                BreakerTiming = NotNaN(maxTiming),
                StatusTiming = NotNaN(breakerTiming.Timing),
                APhaseBreakerTiming = NotNaN(aPhaseTiming.Timing),
                BPhaseBreakerTiming = NotNaN(bPhaseTiming.Timing),
                CPhaseBreakerTiming = NotNaN(cPhaseTiming.Timing),
                DcOffsetDetected = (aPhaseTiming.DcOffsetDetected || bPhaseTiming.DcOffsetDetected || cPhaseTiming.DcOffsetDetected),
                BreakerSpeed = NotNaN(breakerTiming.Speed)
            });
        }
Ejemplo n.º 2
0
        private void LoadRestrikeAnalysis(MeterDataSet meterDataSet)
        {
            BreakerDataResource breakerDataResource = meterDataSet.GetResource <BreakerDataResource>();

            foreach (var kvp in breakerDataResource.RestrikeLookup)
            {
                DataGroup dataGroup = kvp.Key;
                List <BreakerDataResource.Restrike> restrikes = kvp.Value;

                using (AdoDataConnection connection = meterDataSet.CreateDbConnection())
                {
                    TableOperations <Event>           eventTable           = new TableOperations <Event>(connection);
                    TableOperations <Phase>           phaseTable           = new TableOperations <Phase>(connection);
                    TableOperations <BreakerRestrike> breakerRestrikeTable = new TableOperations <BreakerRestrike>(connection);

                    Event evt = eventTable.GetEvent(meterDataSet.FileGroup, dataGroup);

                    foreach (BreakerDataResource.Restrike restrike in restrikes)
                    {
                        Phase           phase           = phaseTable.GetOrAdd(restrike.Phase.ToString());
                        BreakerRestrike breakerRestrike = ProcessRestrike(restrike, phase, evt, new VIDataGroup(dataGroup));
                        breakerRestrikeTable.AddNewRecord(breakerRestrike);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public override void Execute(MeterDataSet meterDataSet)
        {
            BreakerDataResource breakerDataResource = meterDataSet.GetResource <BreakerDataResource>();

            foreach (var kvp in breakerDataResource.RestrikeLookup)
            {
                DataGroup dataGroup = kvp.Key;
                List <BreakerDataResource.Restrike> restrikes = kvp.Value;

                using (AdoDataConnection connection = meterDataSet.CreateDbConnection())
                {
                    TableOperations <Event>           eventTable           = new TableOperations <Event>(connection);
                    TableOperations <Phase>           phaseTable           = new TableOperations <Phase>(connection);
                    TableOperations <BreakerRestrike> breakerRestrikeTable = new TableOperations <BreakerRestrike>(connection);

                    Event evt = eventTable.GetEvent(meterDataSet.FileGroup, dataGroup);

                    foreach (BreakerDataResource.Restrike restrike in restrikes)
                    {
                        Phase           phase           = phaseTable.GetOrAdd(restrike.Phase.ToString());
                        BreakerRestrike breakerRestrike = new BreakerRestrike();
                        breakerRestrike.EventID   = evt.ID;
                        breakerRestrike.PhaseID   = phase.ID;
                        breakerRestrike.Sample    = restrike.Sample;
                        breakerRestrike.Timestamp = restrike.Timestamp;
                        breakerRestrikeTable.AddNewRecord(breakerRestrike);
                    }
                }
            }

            LoadGTCRestrikeData(meterDataSet);
        }
Ejemplo n.º 4
0
        public void AddFieldValue(AdoDataConnection connection, string name, string value, string description = null)
        {
            TableOperations <FileGroupField> fileGroupFieldTable = new TableOperations <FileGroupField>(connection);
            FileGroupField fileGroupField = fileGroupFieldTable.GetOrAdd(name, description);

            TableOperations <FileGroupFieldValue> fileGroupFieldValueTable = new TableOperations <FileGroupFieldValue>(connection);
            FileGroupFieldValue fileGroupFieldValue = new FileGroupFieldValue();

            fileGroupFieldValue.FileGroupID      = ID;
            fileGroupFieldValue.FileGroupFieldID = fileGroupField.ID;
            fileGroupFieldValue.Value            = value;
            fileGroupFieldValueTable.AddNewRecord(fileGroupFieldValue);
        }
Ejemplo n.º 5
0
        private DbDisturbance GetDisturbanceRow(AdoDataConnection connection, Disturbance disturbance)
        {
            TableOperations <EventType> eventTypeTable = new TableOperations <EventType>(connection);
            EventType eventType = eventTypeTable.GetOrAdd(disturbance.EventType.ToString());

            TableOperations <Phase> phaseTable = new TableOperations <Phase>(connection);
            Phase phase = phaseTable.GetOrAdd(disturbance.Phase.ToString());

            DbDisturbance dbDisturbance = new DbDisturbance();

            dbDisturbance.EventTypeID      = eventType.ID;
            dbDisturbance.PhaseID          = phase.ID;
            dbDisturbance.Magnitude        = disturbance.Magnitude;
            dbDisturbance.PerUnitMagnitude = ToDbFloat(disturbance.PerUnitMagnitude);
            dbDisturbance.StartTime        = disturbance.StartTime;
            dbDisturbance.EndTime          = disturbance.EndTime;
            dbDisturbance.DurationSeconds  = disturbance.DurationSeconds;
            dbDisturbance.DurationCycles   = disturbance.GetDurationCycles(m_systemFrequency);
            dbDisturbance.StartIndex       = disturbance.StartIndex;
            dbDisturbance.EndIndex         = disturbance.EndIndex;

            return(dbDisturbance);
        }
Ejemplo n.º 6
0
        // Static Methods
        private static Series GetSeriesInfo(Meter meter, DataGroup dataGroup, string measurementTypeName, string phaseName)
        {
            int    lineID = dataGroup.Line.ID;
            string measurementCharacteristicName = "Instantaneous";
            string seriesTypeName = "Values";

            char   typeDesignation  = (measurementTypeName == "Current") ? 'I' : measurementTypeName[0];
            string phaseDesignation = (phaseName == "RES") ? "R" : phaseName.TrimEnd('N');
            string channelName      = string.Concat(typeDesignation, phaseDesignation);

            ChannelKey channelKey = new ChannelKey(lineID, 0, channelName, measurementTypeName, measurementCharacteristicName, phaseName);
            SeriesKey  seriesKey  = new SeriesKey(channelKey, seriesTypeName);

            Series dbSeries = meter.Channels
                              .SelectMany(channel => channel.Series)
                              .FirstOrDefault(series => seriesKey.Equals(new SeriesKey(series)));

            if ((object)dbSeries == null)
            {
                using (AdoDataConnection connection = meter.ConnectionFactory())
                {
                    Channel dbChannel = meter.Channels
                                        .FirstOrDefault(channel => channelKey.Equals(new ChannelKey(channel)));

                    if ((object)dbChannel == null)
                    {
                        TableOperations <Channel>                   channelTable                   = new TableOperations <Channel>(connection);
                        TableOperations <MeasurementType>           measurementTypeTable           = new TableOperations <MeasurementType>(connection);
                        TableOperations <MeasurementCharacteristic> measurementCharacteristicTable = new TableOperations <MeasurementCharacteristic>(connection);
                        TableOperations <Phase> phaseTable = new TableOperations <Phase>(connection);

                        MeasurementType           measurementType           = measurementTypeTable.GetOrAdd(measurementTypeName);
                        MeasurementCharacteristic measurementCharacteristic = measurementCharacteristicTable.GetOrAdd(measurementCharacteristicName);
                        Phase phase = phaseTable.GetOrAdd(phaseName);

                        dbChannel = new Channel()
                        {
                            MeterID                     = meter.ID,
                            LineID                      = lineID,
                            MeasurementTypeID           = measurementType.ID,
                            MeasurementCharacteristicID = measurementCharacteristic.ID,
                            PhaseID                     = phase.ID,
                            Name           = channelKey.Name,
                            SamplesPerHour = dataGroup.SamplesPerHour,
                            Description    = string.Concat(measurementCharacteristicName, " ", measurementTypeName, " ", phaseName),
                            Enabled        = true
                        };

                        channelTable.AddNewRecord(dbChannel);
                        dbChannel.ID   = connection.ExecuteScalar <int>("SELECT @@IDENTITY");
                        meter.Channels = null;
                    }

                    TableOperations <Series>     seriesTable     = new TableOperations <Series>(connection);
                    TableOperations <SeriesType> seriesTypeTable = new TableOperations <SeriesType>(connection);
                    SeriesType seriesType = seriesTypeTable.GetOrAdd(seriesTypeName);

                    dbSeries = new Series()
                    {
                        ChannelID     = dbChannel.ID,
                        SeriesTypeID  = seriesType.ID,
                        SourceIndexes = string.Empty
                    };

                    seriesTable.AddNewRecord(dbSeries);
                    dbSeries.ID      = connection.ExecuteScalar <int>("SELECT @@IDENTITY");
                    dbChannel.Series = null;

                    dbSeries = meter.Channels
                               .SelectMany(channel => channel.Series)
                               .First(series => seriesKey.Equals(new SeriesKey(series)));
                }
            }

            return(dbSeries);
        }
Ejemplo n.º 7
0
            public void SummarizeFault()
            {
                using (AdoDataConnection connection = MeterDataSet.CreateDbConnection())
                {
                    TableOperations <Event>       eventTable       = new TableOperations <Event>(connection);
                    TableOperations <SegmentType> segmentTypeTable = new TableOperations <SegmentType>(connection);

                    TableOperations <openXDA.Model.FaultGroup> faultGroupTable   = new TableOperations <openXDA.Model.FaultGroup>(connection);
                    TableOperations <FaultSegment>             faultSegmentTable = new TableOperations <FaultSegment>(connection);
                    TableOperations <FaultSummary>             faultSummaryTable = new TableOperations <FaultSummary>(connection);

                    Event       evt = eventTable.GetEvent(MeterDataSet.FileGroup, DataGroup);
                    SegmentType faultSegmentType = segmentTypeTable.GetOrAdd("Fault");

                    // Create a fault group row for the whole group of faults
                    if (FaultGroup.FaultDetectionLogicResult != false || FaultGroup.FaultValidationLogicResult != false)
                    {
                        faultGroupTable.AddNewRecord(CreateFaultGroup(evt.ID, FaultGroup));
                    }

                    for (int faultIndex = 0; faultIndex < FaultGroup.Faults.Count; faultIndex++)
                    {
                        Fault fault = FaultGroup.Faults[faultIndex];

                        // Create a fault segment for the fault itself
                        faultSegmentTable.AddNewRecord(CreateFaultSegment(evt.ID, fault, faultSegmentType));

                        // Create fault segments for each fault type found within the fault
                        foreach (Fault.Segment segment in fault.Segments)
                        {
                            string      segmentTypeName = string.Format("{0} Fault", segment.FaultType).Replace("ABC", "3-Phase");
                            SegmentType segmentType     = segmentTypeTable.GetOrAdd(segmentTypeName);
                            faultSegmentTable.AddNewRecord(CreateFaultSegment(evt.ID, segment, segmentType));
                        }

                        // Create the fault summary rows for this fault
                        foreach (FaultSummary faultSummary in CreateFaultSummaries(evt.ID, faultIndex + 1, fault))
                        {
                            faultSummaryTable.AddNewRecord(faultSummary);
                        }
                    }

                    // Generate fault curves for each algorithm used to analyze the fault
                    TableOperations <FaultCurve>          faultCurveTable          = new TableOperations <FaultCurve>(connection);
                    TableOperations <FaultCurveStatistic> faultCurveStatisticTable = new TableOperations <FaultCurveStatistic>(connection);

                    if (FaultGroup.Faults.Any())
                    {
                        for (int i = 0; i < FaultGroup.Faults[0].Curves.Count; i++)
                        {
                            FaultCurve faultCurve = CreateFaultCurve(evt.ID, i);
                            faultCurveTable.AddNewRecord(faultCurve);
                            faultCurve.ID = connection.ExecuteScalar <int>("SELECT @@IDENTITY");

                            for (int faultIndex = 0; faultIndex < FaultGroup.Faults.Count; faultIndex++)
                            {
                                Fault fault = FaultGroup.Faults[faultIndex];

                                if (fault.Curves[i].Series.DataPoints.Count == 0)
                                {
                                    continue;
                                }

                                FaultCurveStatistic faultCurveStatistic = new FaultCurveStatistic()
                                {
                                    FaultCurveID      = faultCurve.ID,
                                    FaultNumber       = faultIndex + 1,
                                    Maximum           = ToDbFloat(fault.Curves[i].Maximum),
                                    Minimum           = ToDbFloat(fault.Curves[i].Minimum),
                                    Average           = ToDbFloat(fault.Curves[i].Average),
                                    StandardDeviation = ToDbFloat(fault.Curves[i].StandardDeviation)
                                };

                                faultCurveStatisticTable.AddNewRecord(faultCurveStatistic);
                            }
                        }
                    }
                }
            }
Ejemplo n.º 8
0
        private List <Event> GetEvents(AdoDataConnection connection, MeterDataSet meterDataSet, List <DataGroup> dataGroups, List <VICycleDataGroup> viCycleDataGroups, Dictionary <DataGroup, EventClassification> eventClassifications)
        {
            int count = dataGroups
                        .Where(dataGroup => dataGroup.Classification != DataClassification.Trend)
                        .Where(dataGroup => dataGroup.Classification != DataClassification.Unknown)
                        .Where(dataGroup => eventClassifications.ContainsKey(dataGroup))
                        .Count();

            if (count == 0)
            {
                Log.Info($"No events found for file '{meterDataSet.FilePath}'.");
                return(new List <Event>());
            }

            Log.Info(string.Format("Processing {0} events...", count));

            List <Event> events = new List <Event>(count);

            TableOperations <Event>     eventTable     = new TableOperations <Event>(connection);
            TableOperations <EventType> eventTypeTable = new TableOperations <EventType>(connection);
            TableOperations <EventData> eventDataTable = new TableOperations <EventData>(connection);
            TableOperations <Incident>  incidentTable  = new TableOperations <Incident>(connection);

            for (int i = 0; i < dataGroups.Count; i++)
            {
                DataGroup           dataGroup = dataGroups[i];
                EventClassification eventClassification;

                if (dataGroup.Classification == DataClassification.Trend)
                {
                    continue;
                }

                if (dataGroup.Classification == DataClassification.Unknown)
                {
                    continue;
                }

                if (!eventClassifications.TryGetValue(dataGroup, out eventClassification))
                {
                    continue;
                }

                if ((object)dataGroup.Line == null && meterDataSet.Meter.MeterLocation.MeterLocationLines.Count != 1)
                {
                    continue;
                }

                Line line = dataGroup.Line ?? meterDataSet.Meter.MeterLocation.MeterLocationLines.Single().Line;

                if (eventTable.QueryRecordCountWhere("StartTime = {0} AND EndTime = {1} AND Samples = {2} AND MeterID = {3} AND LineID = {4}", dataGroup.StartTime, dataGroup.EndTime, dataGroup.Samples, meterDataSet.Meter.ID, line.ID) > 0)
                {
                    continue;
                }

                EventType eventType = eventTypeTable.GetOrAdd(eventClassification.ToString());
                Incident  incident  = incidentTable.QueryRecordWhere("MeterID = {0} AND {1} BETWEEN StartTime AND EndTime", meterDataSet.Meter.ID, ToDateTime2(connection, dataGroup.StartTime));

                Event evt = new Event()
                {
                    FileGroupID      = meterDataSet.FileGroup.ID,
                    MeterID          = meterDataSet.Meter.ID,
                    LineID           = line.ID,
                    EventTypeID      = eventType.ID,
                    EventDataID      = null,
                    IncidentID       = incident.ID,
                    Name             = string.Empty,
                    StartTime        = dataGroup.StartTime,
                    EndTime          = dataGroup.EndTime,
                    Samples          = dataGroup.Samples,
                    TimeZoneOffset   = (int)m_timeZone.GetUtcOffset(dataGroup.StartTime).TotalMinutes,
                    SamplesPerSecond = 0,
                    SamplesPerCycle  = 0
                };

                if (dataGroup.Samples > 0)
                {
                    evt.EventData = new EventData()
                    {
                        FileGroupID         = meterDataSet.FileGroup.ID,
                        RunTimeID           = i,
                        TimeDomainData      = dataGroup.ToData(),
                        FrequencyDomainData = viCycleDataGroups[i].ToDataGroup().ToData(),
                        MarkedForDeletion   = 0
                    };

                    evt.SamplesPerSecond = (int)Math.Round(dataGroup.SamplesPerSecond);
                    evt.SamplesPerCycle  = Transform.CalculateSamplesPerCycle(dataGroup.SamplesPerSecond, m_systemFrequency);
                }

                events.Add(evt);
            }

            Log.Info(string.Format("Finished processing {0} events.", count));

            return(events);
        }
Ejemplo n.º 9
0
        private void AddUndefinedChannels(MeterDataSet meterDataSet)
        {
            List <DataSeries> undefinedDataSeries = meterDataSet.DataSeries
                                                    .Concat(meterDataSet.Digitals)
                                                    .Where(dataSeries => (object)dataSeries.SeriesInfo.Channel.Line == null)
                                                    .ToList();

            if (undefinedDataSeries.Count <= 0)
            {
                return;
            }

            Meter meter = meterDataSet.Meter;

            if (meter.MeterLines.Count == 0)
            {
                Log.Warn($"Unable to automatically add channels to meter {meterDataSet.Meter.Name} because there are no lines associated with that meter.");
                return;
            }

            if (meter.MeterLines.Count > 1)
            {
                Log.Warn($"Unable to automatically add channels to meter {meterDataSet.Meter.Name} because there are too many lines associated with that meter.");
                return;
            }

            Line line = meter.MeterLines
                        .Select(meterLine => meterLine.Line)
                        .Single();

            foreach (DataSeries series in undefinedDataSeries)
            {
                series.SeriesInfo.Channel.LineID = line.ID;
            }

            using (AdoDataConnection connection = meterDataSet.CreateDbConnection())
            {
                TableOperations <MeasurementType>           measurementTypeTable           = new TableOperations <MeasurementType>(connection);
                TableOperations <MeasurementCharacteristic> measurementCharacteristicTable = new TableOperations <MeasurementCharacteristic>(connection);
                TableOperations <Phase>      phaseTable      = new TableOperations <Phase>(connection);
                TableOperations <SeriesType> seriesTypeTable = new TableOperations <SeriesType>(connection);

                Dictionary <string, MeasurementType> measurementTypeLookup = undefinedDataSeries
                                                                             .Select(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementType)
                                                                             .DistinctBy(measurementType => measurementType.Name)
                                                                             .Select(measurementType => measurementTypeTable.GetOrAdd(measurementType.Name, measurementType.Description))
                                                                             .ToDictionary(measurementType => measurementType.Name);

                Dictionary <string, MeasurementCharacteristic> measurementCharacteristicLookup = undefinedDataSeries
                                                                                                 .Select(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementCharacteristic)
                                                                                                 .DistinctBy(measurementCharacteristic => measurementCharacteristic.Name)
                                                                                                 .Select(measurementCharacteristic => measurementCharacteristicTable.GetOrAdd(measurementCharacteristic.Name, measurementCharacteristic.Description))
                                                                                                 .ToDictionary(measurementCharacteristic => measurementCharacteristic.Name);

                Dictionary <string, Phase> phaseLookup = undefinedDataSeries
                                                         .Select(dataSeries => dataSeries.SeriesInfo.Channel.Phase)
                                                         .DistinctBy(phase => phase.Name)
                                                         .Select(phase => phaseTable.GetOrAdd(phase.Name, phase.Description))
                                                         .ToDictionary(phase => phase.Name);

                Dictionary <string, SeriesType> seriesTypeLookup = undefinedDataSeries
                                                                   .Select(dataSeries => dataSeries.SeriesInfo.SeriesType)
                                                                   .DistinctBy(seriesType => seriesType.Name)
                                                                   .Select(seriesType => seriesTypeTable.GetOrAdd(seriesType.Name, seriesType.Description))
                                                                   .ToDictionary(seriesType => seriesType.Name);

                Dictionary <ChannelKey, Channel> channelLookup = meter.Channels
                                                                 .GroupBy(channel => new ChannelKey(channel))
                                                                 .ToDictionary(grouping =>
                {
                    if (grouping.Count() > 1)
                    {
                        Log.Warn($"Detected duplicate channel key: {grouping.First().ID}");
                    }

                    return(grouping.Key);
                }, grouping => grouping.First());

                List <Channel> undefinedChannels = undefinedDataSeries
                                                   .Select(dataSeries => dataSeries.SeriesInfo.Channel)
                                                   .GroupBy(channel => new ChannelKey(channel))
                                                   .Where(grouping => !channelLookup.ContainsKey(grouping.Key))
                                                   .Select(grouping => grouping.First())
                                                   .ToList();

                TableOperations <Channel> channelTable = new TableOperations <Channel>(connection);

                // Add all undefined channels to the database
                foreach (Channel channel in undefinedChannels)
                {
                    string measurementTypeName           = channel.MeasurementType.Name;
                    string measurementCharacteristicName = channel.MeasurementCharacteristic.Name;
                    string phaseName = channel.Phase.Name;

                    channel.MeterID                     = meter.ID;
                    channel.LineID                      = line.ID;
                    channel.MeasurementTypeID           = measurementTypeLookup[measurementTypeName].ID;
                    channel.MeasurementCharacteristicID = measurementCharacteristicLookup[measurementCharacteristicName].ID;
                    channel.PhaseID                     = phaseLookup[phaseName].ID;
                    channel.Enabled                     = true;

                    // If the per-unit value was not specified in the input file,
                    // we can obtain the per-unit value from the line configuration
                    // if the channel happens to be an instantaneous or RMS voltage
                    if (!channel.PerUnitValue.HasValue)
                    {
                        if (IsVoltage(channel))
                        {
                            if (IsLineToNeutral(channel))
                            {
                                channel.PerUnitValue = (line.VoltageKV * 1000.0D) / Sqrt3;
                            }
                            else if (IsLineToLine(channel))
                            {
                                channel.PerUnitValue = line.VoltageKV * 1000.0D;
                            }
                        }
                    }

                    channelTable.AddNewRecord(channel);
                }

                if (undefinedChannels.Count > 0)
                {
                    // Refresh the channel lookup to
                    // include all the new channels
                    meter.Channels = null;

                    channelLookup = meter.Channels
                                    .GroupBy(channel => new ChannelKey(channel))
                                    .ToDictionary(grouping => grouping.Key, grouping => grouping.First());
                }

                Dictionary <SeriesKey, Series> seriesLookup = meter.Channels
                                                              .SelectMany(channel => channel.Series)
                                                              .Where(series => series.SourceIndexes == "")
                                                              .GroupBy(series => new SeriesKey(series))
                                                              .ToDictionary(grouping =>
                {
                    if (grouping.Count() > 1)
                    {
                        Log.Warn($"Detected duplicate series key: {grouping.First().ID}");
                    }

                    return(grouping.Key);
                }, grouping => grouping.First());

                List <Series> undefinedSeries = undefinedDataSeries
                                                .SelectMany(dataSeries => dataSeries.SeriesInfo.Channel.Series)
                                                .GroupBy(series => new SeriesKey(series))
                                                .Where(grouping => !seriesLookup.ContainsKey(grouping.Key))
                                                .Select(grouping => grouping.First())
                                                .ToList();

                TableOperations <Series> seriesTable = new TableOperations <Series>(connection);

                // Add all undefined series objects to the database
                foreach (Series series in undefinedSeries)
                {
                    ChannelKey channelKey     = new ChannelKey(series.Channel);
                    string     seriesTypeName = series.SeriesType.Name;

                    series.ChannelID     = channelLookup[channelKey].ID;
                    series.SeriesTypeID  = seriesTypeLookup[seriesTypeName].ID;
                    series.SourceIndexes = "";

                    seriesTable.AddNewRecord(series);
                }

                if (undefinedSeries.Count > 0)
                {
                    // Refresh the series lookup to
                    // include all the new series
                    foreach (Channel channel in meter.Channels)
                    {
                        channel.Series = null;
                    }

                    seriesLookup = meter.Channels
                                   .SelectMany(channel => channel.Series)
                                   .GroupBy(series => new SeriesKey(series))
                                   .ToDictionary(grouping => grouping.Key, grouping => grouping.First());
                }

                // Update all undefined data series to reference the new database objects
                foreach (DataSeries dataSeries in undefinedDataSeries)
                {
                    SeriesKey seriesKey = new SeriesKey(dataSeries.SeriesInfo);
                    Series    series    = seriesLookup[seriesKey];
                    dataSeries.SeriesInfo = series;
                }
            }
        }
Ejemplo n.º 10
0
        private Series GetSeriesInfo(Meter meter, ChannelKey channelKey, SeriesKey seriesKey)
        {
            Series dbSeries = meter.Channels
                              .SelectMany(channel => channel.Series)
                              .FirstOrDefault(series => seriesKey.Equals(new SeriesKey(series)));

            if ((object)dbSeries == null)
            {
                using (AdoDataConnection connection = meter.ConnectionFactory())
                {
                    Channel dbChannel = meter.Channels
                                        .FirstOrDefault(channel => channelKey.Equals(new ChannelKey(channel)));

                    if ((object)dbChannel == null)
                    {
                        TableOperations <Channel>                   channelTable                   = new TableOperations <Channel>(connection);
                        TableOperations <MeasurementType>           measurementTypeTable           = new TableOperations <MeasurementType>(connection);
                        TableOperations <MeasurementCharacteristic> measurementCharacteristicTable = new TableOperations <MeasurementCharacteristic>(connection);
                        TableOperations <Phase> phaseTable = new TableOperations <Phase>(connection);

                        MeasurementType           measurementType           = measurementTypeTable.GetOrAdd(channelKey.MeasurementType);
                        MeasurementCharacteristic measurementCharacteristic = measurementCharacteristicTable.GetOrAdd(channelKey.MeasurementCharacteristic);
                        Phase phase = phaseTable.GetOrAdd(channelKey.Phase);

                        dbChannel = new Channel()
                        {
                            MeterID                     = meter.ID,
                            LineID                      = channelKey.LineID,
                            MeasurementTypeID           = measurementType.ID,
                            MeasurementCharacteristicID = measurementCharacteristic.ID,
                            PhaseID                     = phase.ID,
                            Name           = channelKey.Name,
                            SamplesPerHour = 0,
                            Description    = string.Concat(channelKey.MeasurementCharacteristic, " ", channelKey.MeasurementType, " ", channelKey.Phase),
                            Enabled        = true
                        };

                        channelTable.AddNewRecord(dbChannel);
                        dbChannel.ID   = connection.ExecuteScalar <int>("SELECT @@IDENTITY");
                        meter.Channels = null;
                    }
                    TableOperations <Series>     seriesTable     = new TableOperations <Series>(connection);
                    TableOperations <SeriesType> seriesTypeTable = new TableOperations <SeriesType>(connection);
                    SeriesType seriesType = seriesTypeTable.GetOrAdd(seriesKey.SeriesType);

                    dbSeries = new Series()
                    {
                        ChannelID     = dbChannel.ID,
                        SeriesTypeID  = seriesType.ID,
                        SourceIndexes = string.Empty
                    };

                    seriesTable.AddNewRecord(dbSeries);
                    dbSeries.ID      = connection.ExecuteScalar <int>("SELECT @@IDENTITY");
                    dbChannel.Series = null;

                    dbSeries = meter.Channels
                               .SelectMany(channel => channel.Series)
                               .First(series => seriesKey.Equals(new SeriesKey(series)));
                }
            }

            return(dbSeries);
        }