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);
                    }
                }
            }
        }
Example #2
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);
        }
        public override void Execute(MeterDataSet meterDataSet)
        {
            LightningDataResource lightningDataResource = meterDataSet.GetResource <LightningDataResource>();

            if (lightningDataResource.LightningStrikeLookup.Count == 0)
            {
                return;
            }

            using (AdoDataConnection connection = meterDataSet.CreateDbConnection())
            {
                foreach (var kvp in lightningDataResource.LightningStrikeLookup)
                {
                    DataGroup dataGroup = kvp.Key;
                    List <ILightningStrike> lightningStrikes = kvp.Value;

                    TableOperations <Event> eventTable = new TableOperations <Event>(connection);
                    Event evt = eventTable.GetEvent(meterDataSet.FileGroup, dataGroup);

                    if (evt == null)
                    {
                        continue;
                    }

                    foreach (ILightningStrike lightningStrike in lightningStrikes)
                    {
                        const string Query =
                            "INSERT INTO LightningStrike " +
                            "( " +
                            "    EventID, " +
                            "    Service, " +
                            "    UTCTime, " +
                            "    DisplayTime, " +
                            "    Amplitude, " +
                            "    Latitude, " +
                            "    Longitude " +
                            ") " +
                            "VALUES({0}, {1}, {2}, {3}, {4}, {5}, {6})";

                        object[] parameters =
                        {
                            evt.ID,
                            lightningStrike.Service,
                            ToDateTime2(connection,     lightningStrike.UTCTime),
                            lightningStrike.DisplayTime,
                            lightningStrike.Amplitude,
                            lightningStrike.Latitude,
                            lightningStrike.Longitude
                        };

                        connection.ExecuteNonQuery(Query, parameters);
                    }
                }
            }
        }
        public override void Execute(MeterDataSet meterDataSet)
        {
            FaultDataResource faultDataResource = meterDataSet.GetResource <FaultDataResource>();
            string            stationKey        = meterDataSet.Meter.MeterLocation.AssetKey;

            foreach (var kvp in faultDataResource.FaultLookup)
            {
                DataGroup dataGroup = kvp.Key;
                DataAnalysis.FaultGroup faultGroup = kvp.Value;
                string lineKey = dataGroup.Line.AssetKey;

                for (int i = 0; i < faultGroup.Faults.Count; i++)
                {
                    int faultNumber          = i + 1;
                    DataAnalysis.Fault fault = faultGroup.Faults[i];

                    if (fault.IsSuppressed)
                    {
                        continue;
                    }

                    string distance = fault.Summaries
                                      .Where(summary => summary.IsValid)
                                      .Where(summary => summary.IsSelectedAlgorithm)
                                      .Select(summary => summary.Distance.ToString("0.###"))
                                      .FirstOrDefault();

                    if (distance == null)
                    {
                        return;
                    }

                    string    url           = string.Format(Settings.URLFormat, stationKey, lineKey, distance);
                    string    structureInfo = GetStructureInfo(url);
                    DataTable structureData = ToDataTable(structureInfo);

                    if (structureData.Rows.Count == 0)
                    {
                        return;
                    }

                    Func <string, string> fieldMappingLookup = FieldMappingLookup;
                    string assetKeyField     = fieldMappingLookup("AssetKey");
                    string latitudeKeyField  = fieldMappingLookup("Latitude");
                    string longitudeKeyField = fieldMappingLookup("Longitude");

                    if (!structureData.Columns.Contains(assetKeyField))
                    {
                        return;
                    }

                    using (AdoDataConnection connection = meterDataSet.CreateDbConnection())
                    {
                        TableOperations <Event> eventTable = new TableOperations <Event>(connection);
                        Event evt            = eventTable.GetEvent(meterDataSet.FileGroup, dataGroup);
                        int   faultSummaryID = connection.ExecuteScalar <int>(FaultSummaryQuery, evt.ID, faultNumber);

                        TableOperations <Structure> structureTable = new TableOperations <Structure>(connection);

                        foreach (DataRow row in structureData.Rows)
                        {
                            string assetKey  = row.Field <string>(assetKeyField);
                            string latitude  = null;
                            string longitude = null;

                            if (structureData.Columns.Contains(latitudeKeyField))
                            {
                                latitude = row.Field <string>(latitudeKeyField);
                            }

                            if (structureData.Columns.Contains(longitudeKeyField))
                            {
                                longitude = row.Field <string>(longitudeKeyField);
                            }

                            Structure structure = structureTable.QueryRecordWhere("AssetKey = {0}", assetKey)
                                                  ?? new Structure()
                            {
                                AssetKey = assetKey
                            };

                            structure.LineID = dataGroup.Line.ID;

                            if (double.TryParse(latitude, out double lat))
                            {
                                structure.Latitude = lat;
                            }

                            if (double.TryParse(longitude, out double lon))
                            {
                                structure.Longitude = lon;
                            }

                            structureTable.AddNewOrUpdateRecord(structure);

                            if (structure.ID == 0)
                            {
                                structure.ID = connection.ExecuteScalar <int>("SELECT @@IDENTITY");
                            }

                            if (faultSummaryID != 0)
                            {
                                connection.ExecuteNonQuery("INSERT INTO NearestStructure(FaultSummaryID, StructureID) VALUES({0}, {1})", faultSummaryID, structure.ID);
                            }
                        }
                    }
                }
            }
        }
Example #5
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);
                            }
                        }
                    }
                }
            }
Example #6
0
        private void IdentifyBreakerOperations(AdoDataConnection connection, FileGroup fileGroup, DataGroup dataGroup, VIDataGroup viDataGroup, VICycleDataGroup viCycleDataGroup)
        {
            TableOperations <Event>            eventTable            = new TableOperations <Event>(connection);
            TableOperations <BreakerChannel>   breakerChannelTable   = new TableOperations <BreakerChannel>(connection);
            TableOperations <BreakerOperation> breakerOperationTable = new TableOperations <BreakerOperation>(connection);

            List <int> channelIDs = dataGroup.DataSeries
                                    .Select(dataSeries => dataSeries.SeriesInfo.ChannelID)
                                    .Distinct()
                                    .ToList();

            if (channelIDs.Count == 0)
            {
                return;
            }

            List <string> breakerNumbers = breakerChannelTable
                                           .QueryRecordsWhere($"ChannelID IN ({string.Join(",", channelIDs)})")
                                           .Select(breakerChannel => breakerChannel.BreakerNumber)
                                           .Distinct()
                                           .ToList();

            // If the breaker currents are defined for breaker-and-a-half or ring bus configurations,
            // skip this data group so that timing is only applied to the breaker currents
            if (breakerNumbers.Count > 1 && breakerNumbers.Any(num => m_breakerCurrents.Contains(num)))
            {
                return;
            }

            Event evt = eventTable.GetEvent(fileGroup, dataGroup);

            if ((object)evt == null)
            {
                return;
            }

            foreach (string breakerNumber in breakerNumbers)
            {
                double breakerSpeed = connection.ExecuteScalar(double.NaN, "SELECT Speed FROM Breaker WHERE AssetKey = {0}", breakerNumber.TrimStart('0'));

                Func <DataSeries, bool> digitalFilter = dataSeries =>
                {
                    int channelID = dataSeries.SeriesInfo.ChannelID;

                    RecordRestriction recordRestriction =
                        new RecordRestriction("ChannelID = {0}", channelID) &
                        new RecordRestriction("BreakerNumber = {0}", breakerNumber);

                    int breakerChannelCount = breakerChannelTable.QueryRecordCount(recordRestriction);

                    return(breakerChannelCount > 0);
                };

                List <DataSeries> breakerDigitals = dataGroup.DataSeries
                                                    .Where(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementType.Name == "Digital")
                                                    .Where(digitalFilter)
                                                    .ToList();

                List <DataSeries> tripCoilEnergizedChannels = breakerDigitals
                                                              .Where(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementCharacteristic.Name == "TCE")
                                                              .ToList();

                DataSeries breakerStatusChannel = breakerDigitals
                                                  .FirstOrDefault(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementCharacteristic.Name == "BreakerStatus");

                List <XValue> tripCoilEnergizedTriggers = Range <XValue> .MergeAllOverlapping(tripCoilEnergizedChannels.SelectMany(FindTCERanges))
                                                          .Select(range => range.Start)
                                                          .ToList();

                foreach (XValue tripCoilEnergizedTrigger in tripCoilEnergizedTriggers)
                {
                    BreakerTiming breakerTiming = new BreakerTiming(tripCoilEnergizedTrigger, breakerStatusChannel, m_systemFrequency, breakerSpeed, m_breakerSettings.MinWaitBeforeReclose);

                    PhaseTiming aPhaseTiming = new PhaseTiming(viDataGroup.IA, viCycleDataGroup.IA, breakerTiming, m_breakerSettings, m_systemFrequency);
                    PhaseTiming bPhaseTiming = new PhaseTiming(viDataGroup.IB, viCycleDataGroup.IB, breakerTiming, m_breakerSettings, m_systemFrequency);
                    PhaseTiming cPhaseTiming = new PhaseTiming(viDataGroup.IC, viCycleDataGroup.IC, breakerTiming, m_breakerSettings, m_systemFrequency);

                    BreakerOperation breakerOperation = GetBreakerOperation(connection, evt.ID, breakerNumber, breakerTiming, aPhaseTiming, bPhaseTiming, cPhaseTiming);
                    breakerOperationTable.AddNewRecord(breakerOperation);
                }
            }
        }