public VICycleDataGroup(DataGroup dataGroup) { m_cycleDataGroups = dataGroup.DataSeries .Select((series, i) => Tuple.Create(i / 4, series)) .GroupBy(tuple => tuple.Item1) .Select(grouping => new DataGroup(grouping.Select(tuple => tuple.Item2))) .Select(group => new CycleDataGroup(group)) .ToList(); }
public DataGroup ToSubGroup(DateTime startTime, DateTime endTime) { DataGroup subGroup = new DataGroup(); foreach (DataSeries dataSeries in m_dataSeries) { subGroup.Add(dataSeries.ToSubSeries(startTime, endTime)); } return(subGroup); }
public DataGroup ToSubGroup(int startIndex, int endIndex) { DataGroup subGroup = new DataGroup(); foreach (DataSeries dataSeries in m_dataSeries) { subGroup.Add(dataSeries.ToSubSeries(startIndex, endIndex)); } return(subGroup); }
public VICycleDataGroup(DataGroup dataGroup) { m_cycleDataGroups = dataGroup.DataSeries .Select((dataSeries, index) => new { DataSeries = dataSeries, Index = index }) .GroupBy(obj => obj.Index / 4) .Where(grouping => grouping.Count() >= 4) .Select(grouping => grouping.Select(obj => obj.DataSeries)) .Select(grouping => new CycleDataGroup(new DataGroup(grouping))) .ToList(); MapIndexes(); }
public static DataGroup Combine(params DataGroup[] dataGroups) { DataGroup combination = new DataGroup(); foreach (DataGroup dataGroup in dataGroups) { foreach (DataSeries dataSeries in dataGroup.DataSeries) { combination.Add(dataSeries); } } return(combination); }
private void DetectDisturbances(DataGroup dataGroup, VICycleDataGroup viCycleDataGroup) { List <Range <int> > aPhaseDisturbanceRanges = DetectDisturbanceRanges(ToPerUnit(viCycleDataGroup.VA?.RMS)); List <Range <int> > bPhaseDisturbanceRanges = DetectDisturbanceRanges(ToPerUnit(viCycleDataGroup.VB?.RMS)); List <Range <int> > cPhaseDisturbanceRanges = DetectDisturbanceRanges(ToPerUnit(viCycleDataGroup.VC?.RMS)); List <Range <int> > abPhaseDisturbanceRanges = DetectDisturbanceRanges(ToPerUnit(viCycleDataGroup.VAB?.RMS)); List <Range <int> > bcPhaseDisturbanceRanges = DetectDisturbanceRanges(ToPerUnit(viCycleDataGroup.VBC?.RMS)); List <Range <int> > caPhaseDisturbanceRanges = DetectDisturbanceRanges(ToPerUnit(viCycleDataGroup.VCA?.RMS)); List <Disturbance> disturbanceList = aPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VA.RMS, range, Phase.AN)) .Concat(bPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VB.RMS, range, Phase.BN))) .Concat(cPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VC.RMS, range, Phase.CN))) .Concat(abPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VAB.RMS, range, Phase.AB))) .Concat(bcPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VBC.RMS, range, Phase.BC))) .Concat(caPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VCA.RMS, range, Phase.CA))) .ToList(); IEnumerable <Range <int> > allDisturbanceRanges = aPhaseDisturbanceRanges .Concat(bPhaseDisturbanceRanges) .Concat(cPhaseDisturbanceRanges) .Concat(abPhaseDisturbanceRanges) .Concat(bcPhaseDisturbanceRanges) .Concat(caPhaseDisturbanceRanges); IEnumerable <Disturbance> worstDisturbances = Range <int> .MergeAllOverlapping(allDisturbanceRanges) .Select(range => { Disturbance worst = null; foreach (Disturbance disturbance in disturbanceList.Where(disturbance => ToRange(disturbance).Overlaps(range))) { if ((object)worst == null || m_isMoreSevere(disturbance.PerUnitMagnitude, worst.PerUnitMagnitude)) { worst = disturbance; } } worst = worst.Clone(); worst.Phase = Phase.Worst; return(worst); }); disturbanceList.AddRange(worstDisturbances); if (disturbanceList.Any()) { m_disturbances.Add(dataGroup, disturbanceList); } }
public VICycleDataGroup(DataGroup dataGroup) { m_vIndices = new List <VIndices>(); m_asset = dataGroup.Asset; m_cycleDataGroups = dataGroup.DataSeries .Select((dataSeries, index) => new { DataSeries = dataSeries, Index = index }) .GroupBy(obj => obj.Index / 4) .Where(grouping => grouping.Count() >= 4) .Select(grouping => grouping.Select(obj => obj.DataSeries)) .Select(grouping => new CycleDataGroup(new DataGroup(grouping, dataGroup.Asset), dataGroup.Asset)) .ToList(); MapIndexes(); }
public VIDataGroup(DataGroup dataGroup) { // Get all necessary voltage and current channels in the proper order List <DataSeries> viSeriesList = Enumerable.Range(0, 7) .GroupJoin(dataGroup.DataSeries.Where(IsInstantaneous), i => i, GetIndex, (i, series) => series.FirstOrDefault()) .ToList(); // Validate that no channels are missing if (viSeriesList.Any(series => (object)series == null)) { throw new InvalidOperationException("Cannot create VIDataGroup from an incomplete set of voltage/current channels"); } // Create the data group from the complete // set of voltage/current channels m_dataGroup = new DataGroup(viSeriesList); }
private void DetectDisturbances(DataGroup dataGroup, VICycleDataGroup viCycleDataGroup) { double nominalVoltage = dataGroup.Line.VoltageKV * 1000.0D / Sqrt3; double nominalVoltageReciprocal = 1.0D / nominalVoltage; DataSeries vAll = GetVAllSeries(viCycleDataGroup); List <Range <int> > aPhaseDisturbanceRanges = DetectDisturbanceRanges(viCycleDataGroup.VA.RMS.Multiply(nominalVoltageReciprocal)); List <Range <int> > bPhaseDisturbanceRanges = DetectDisturbanceRanges(viCycleDataGroup.VB.RMS.Multiply(nominalVoltageReciprocal)); List <Range <int> > cPhaseDisturbanceRanges = DetectDisturbanceRanges(viCycleDataGroup.VC.RMS.Multiply(nominalVoltageReciprocal)); List <Range <int> > allDisturbanceRanges = DetectDisturbanceRanges(vAll.Multiply(nominalVoltageReciprocal)); List <Disturbance> disturbanceList = aPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VA.RMS, range, Phase.AN)) .Concat(bPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VB.RMS, range, Phase.BN))) .Concat(cPhaseDisturbanceRanges.Select(range => ToDisturbance(viCycleDataGroup.VC.RMS, range, Phase.CN))) .Concat(allDisturbanceRanges.Select(range => ToDisturbance(vAll, range, Phase.None))) .ToList(); m_disturbances.Add(dataGroup, disturbanceList); }
private Range <int> ToRange(DataGroup dataGroup, ReportedDisturbance disturbance) { if (dataGroup.Samples == 0) { return(null); } DateTime startTime = disturbance.Time; DateTime endTime = startTime + disturbance.Duration; TimeSpan eventSpan = dataGroup.EndTime - dataGroup.StartTime; TimeSpan startSpan = startTime - dataGroup.StartTime; TimeSpan endSpan = endTime - dataGroup.EndTime; int startIndex = (int)(startSpan.TotalSeconds / eventSpan.TotalSeconds * dataGroup.Samples); int endIndex = (int)(endSpan.TotalSeconds / eventSpan.TotalSeconds * dataGroup.Samples); return(new Range <int>(startIndex, endIndex)); }
public void Initialize(MeterDataSet meterDataSet) { ConnectionStringParser.ParseConnectionString(meterDataSet.ConnectionString, this); m_disturbances = new Dictionary <DataGroup, List <Disturbance> >(); CycleDataResource cycleDataResource = meterDataSet.GetResource <CycleDataResource>(); int lineCount = meterDataSet.Meter.MeterLines.Count; for (int i = 0; i < cycleDataResource.DataGroups.Count; i++) { DataGroup dataGroup = cycleDataResource.DataGroups[i]; VICycleDataGroup viCycleDataGroup = cycleDataResource.VICycleDataGroups[i]; Range <DateTime> eventDateRange = new Range <DateTime>(dataGroup.StartTime, dataGroup.EndTime); if (lineCount == 1 && dataGroup.Disturbances.Count > 0) { ProcessReportedDisturbances(meterDataSet.Meter, dataGroup); } else { DetectDisturbances(dataGroup, viCycleDataGroup); } } DataGroupsResource dataGroupsResource = meterDataSet.GetResource <DataGroupsResource>(); foreach (DataGroup dataGroup in dataGroupsResource.DataGroups) { if (dataGroup.DataSeries.Count > 0) { continue; } if (lineCount == 1 && dataGroup.Disturbances.Count > 0) { ProcessReportedDisturbances(meterDataSet.Meter, dataGroup); } } }
// Static Methods private static Series GetSeriesInfo(MeterInfoDataContext meterInfo, Meter meter, DataGroup dataGroup, string measurementTypeName, string phaseName) { int lineID; string measurementCharacteristicName; string seriesTypeName; char typeDesignation; char phaseDesignation; string channelName; DataContextLookup <ChannelKey, Channel> channelLookup; DataContextLookup <SeriesKey, Series> seriesLookup; DataContextLookup <string, MeasurementType> measurementTypeLookup; DataContextLookup <string, MeasurementCharacteristic> measurementCharacteristicLookup; DataContextLookup <string, Phase> phaseLookup; DataContextLookup <string, SeriesType> seriesTypeLookup; ChannelKey channelKey; SeriesKey seriesKey; lineID = dataGroup.Line.ID; measurementCharacteristicName = "Instantaneous"; seriesTypeName = "Values"; typeDesignation = (measurementTypeName == "Current") ? 'I' : measurementTypeName[0]; phaseDesignation = (phaseName == "RES") ? 'R' : phaseName[0]; channelName = string.Concat(typeDesignation, phaseDesignation); channelLookup = new DataContextLookup <ChannelKey, Channel>(meterInfo, channel => new ChannelKey(channel)) .WithFilterExpression(channel => channel.MeterID == meter.ID) .WithFilterExpression(channel => channel.LineID == dataGroup.Line.ID) .WithFilterExpression(channel => channel.MeasurementType.Name == measurementTypeName) .WithFilterExpression(channel => channel.MeasurementCharacteristic.Name == measurementCharacteristicName) .WithFilterExpression(channel => channel.Phase.Name == phaseName); seriesLookup = new DataContextLookup <SeriesKey, Series>(meterInfo, series => new SeriesKey(series)) .WithFilterExpression(series => series.Channel.Meter.ID == meter.ID) .WithFilterExpression(series => series.Channel.Line.ID == dataGroup.Line.ID) .WithFilterExpression(series => series.Channel.MeasurementType.Name == measurementTypeName) .WithFilterExpression(series => series.Channel.MeasurementCharacteristic.Name == measurementCharacteristicName) .WithFilterExpression(series => series.Channel.Phase.Name == phaseName) .WithFilterExpression(series => series.SeriesType.Name == seriesTypeName); measurementTypeLookup = new DataContextLookup <string, MeasurementType>(meterInfo, measurementType => measurementType.Name); measurementCharacteristicLookup = new DataContextLookup <string, MeasurementCharacteristic>(meterInfo, measurementCharacteristic => measurementCharacteristic.Name); phaseLookup = new DataContextLookup <string, Phase>(meterInfo, phase => phase.Name); seriesTypeLookup = new DataContextLookup <string, SeriesType>(meterInfo, seriesType => seriesType.Name); channelKey = new ChannelKey(lineID, 0, channelName, measurementTypeName, measurementCharacteristicName, phaseName); seriesKey = new SeriesKey(channelKey, seriesTypeName); return(seriesLookup.GetOrAdd(seriesKey, key => { SeriesType seriesType = seriesTypeLookup.GetOrAdd(key.SeriesType, name => new SeriesType() { Name = name, Description = name }); Channel channel = channelLookup.GetOrAdd(channelKey, chKey => { MeasurementType measurementType = measurementTypeLookup.GetOrAdd(chKey.MeasurementType, name => new MeasurementType() { Name = name, Description = name }); MeasurementCharacteristic measurementCharacteristic = measurementCharacteristicLookup.GetOrAdd(chKey.MeasurementCharacteristic, name => new MeasurementCharacteristic() { Name = name, Description = name }); Phase phase = phaseLookup.GetOrAdd(chKey.Phase, name => new Phase() { Name = name, Description = name }); return new Channel() { Meter = meter, Line = dataGroup.Line, MeasurementType = measurementType, MeasurementCharacteristic = measurementCharacteristic, Phase = phase, Name = chKey.Name, SamplesPerHour = dataGroup.SamplesPerHour, PerUnitValue = 0, HarmonicGroup = 0, Description = string.Concat(measurementCharacteristic.Name, " ", measurementType.Name, " ", phase.Name), Enabled = 1 }; }); return new Series() { SeriesType = seriesType, Channel = channel, SourceIndexes = string.Empty }; })); }
private static Series GetSeriesInfo(MeterInfoDataContext meterInfo, Meter meter, DataGroup dataGroup, int index) { Dictionary <int, string> measurementTypeNameLookup = new Dictionary <int, string>() { { VAIndex, "Voltage" }, { VBIndex, "Voltage" }, { VCIndex, "Voltage" }, { IAIndex, "Current" }, { IBIndex, "Current" }, { ICIndex, "Current" }, { IRIndex, "Current" } }; Dictionary <int, string> phaseNameLookup = new Dictionary <int, string>() { { VAIndex, "AN" }, { VBIndex, "BN" }, { VCIndex, "CN" }, { IAIndex, "AN" }, { IBIndex, "BN" }, { ICIndex, "CN" }, { IRIndex, "RES" } }; int lineID; string measurementTypeName; string measurementCharacteristicName; string phaseName; string seriesTypeName; string channelName; DataContextLookup <ChannelKey, Channel> channelLookup; DataContextLookup <SeriesKey, Series> seriesLookup; DataContextLookup <string, MeasurementType> measurementTypeLookup; DataContextLookup <string, MeasurementCharacteristic> measurementCharacteristicLookup; DataContextLookup <string, Phase> phaseLookup; DataContextLookup <string, SeriesType> seriesTypeLookup; SeriesKey seriesKey; ChannelKey channelKey; lineID = dataGroup.Line.ID; measurementTypeName = measurementTypeNameLookup[index]; measurementCharacteristicName = "Instantaneous"; phaseName = phaseNameLookup[index]; seriesTypeName = "Values"; channelName = string.Concat(measurementTypeName, " ", phaseName); channelLookup = new DataContextLookup <ChannelKey, Channel>(meterInfo, GetChannelKey) .WithFilterExpression(channel => channel.MeterID == meter.ID) .WithFilterExpression(channel => channel.LineID == dataGroup.Line.ID); seriesLookup = new DataContextLookup <SeriesKey, Series>(meterInfo, GetSeriesKey) .WithFilterExpression(series => series.Channel.Meter.ID == meter.ID) .WithFilterExpression(series => series.Channel.Line.ID == dataGroup.Line.ID); measurementTypeLookup = new DataContextLookup <string, MeasurementType>(meterInfo, measurementType => measurementType.Name); measurementCharacteristicLookup = new DataContextLookup <string, MeasurementCharacteristic>(meterInfo, measurementCharacteristic => measurementCharacteristic.Name); phaseLookup = new DataContextLookup <string, Phase>(meterInfo, phase => phase.Name); seriesTypeLookup = new DataContextLookup <string, SeriesType>(meterInfo, seriesType => seriesType.Name); seriesKey = Tuple.Create(lineID, 0, channelName, measurementTypeName, measurementCharacteristicName, phaseName, seriesTypeName); channelKey = Tuple.Create(lineID, 0, channelName, measurementTypeName, measurementCharacteristicName, phaseName); return(seriesLookup.GetOrAdd(seriesKey, key => { SeriesType seriesType = seriesTypeLookup.GetOrAdd(seriesTypeName, name => new SeriesType() { Name = name, Description = name }); Channel channel = channelLookup.GetOrAdd(channelKey, chKey => { MeasurementType measurementType = measurementTypeLookup.GetOrAdd(measurementTypeName, name => new MeasurementType() { Name = name, Description = name }); MeasurementCharacteristic measurementCharacteristic = measurementCharacteristicLookup.GetOrAdd(measurementCharacteristicName, name => new MeasurementCharacteristic() { Name = name, Description = name }); Phase phase = phaseLookup.GetOrAdd(phaseName, name => new Phase() { Name = name, Description = name }); return new Channel() { Meter = meter, Line = dataGroup.Line, MeasurementType = measurementType, MeasurementCharacteristic = measurementCharacteristic, Phase = phase, Name = string.Concat(measurementType.Name, " ", phase.Name), SamplesPerHour = dataGroup.SamplesPerHour, PerUnitValue = 0, HarmonicGroup = 0, Description = string.Concat(measurementCharacteristic.Name, " ", measurementType.Name, " ", phase.Name), Enabled = 1 }; }); return new Series() { SeriesType = seriesType, Channel = channel, SourceIndexes = string.Empty }; })); }
public static CycleDataGroup ToCycleDataGroup(DataSeries dataSeries, double frequency) { DataGroup dataGroup = new DataGroup(); DataSeries rmsSeries = new DataSeries(); DataSeries phaseSeries = new DataSeries(); DataSeries peakSeries = new DataSeries(); DataSeries errorSeries = new DataSeries(); int samplesPerCycle; double[] yValues; double[] tValues; double sum; DateTime cycleTime; SineWave sineFit; if ((object)dataSeries == null) { return(new CycleDataGroup(dataGroup)); } // Set series info to the source series info rmsSeries.SeriesInfo = dataSeries.SeriesInfo; phaseSeries.SeriesInfo = dataSeries.SeriesInfo; peakSeries.SeriesInfo = dataSeries.SeriesInfo; errorSeries.SeriesInfo = dataSeries.SeriesInfo; // Get samples per cycle of the data series based on the given frequency samplesPerCycle = CalculateSamplesPerCycle(dataSeries, frequency); // Initialize arrays of y-values and t-values for calculating cycle data yValues = new double[samplesPerCycle]; tValues = new double[samplesPerCycle]; for (int i = 0; i <= dataSeries.DataPoints.Count - samplesPerCycle; i++) { // Use the time of the first data point in the cycle as the time of the cycle cycleTime = dataSeries.DataPoints[i].Time; sum = 0.0D; // Copy values from the original data series into the y-value and t-value arrays for (int j = 0; j < samplesPerCycle; j++) { yValues[j] = dataSeries.DataPoints[i + j].Value; tValues[j] = (dataSeries.DataPoints[i + j].Time - cycleTime).TotalSeconds; sum += yValues[j] * yValues[j]; } // Use a curve fitting algorithm to estimate the sine wave over this cycle sineFit = WaveFit.SineFit(yValues, tValues, frequency); // Add data points to each of the cycle data series rmsSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = Math.Sqrt(sum / samplesPerCycle) }); phaseSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = sineFit.Phase }); peakSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = sineFit.Amplitude }); errorSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = tValues .Select(sineFit.CalculateY) .Zip(yValues, (estimate, value) => Math.Abs(estimate - value)) .Sum() }); } // Add a series to the data group for each series of cycle data dataGroup.Add(rmsSeries); dataGroup.Add(phaseSeries); dataGroup.Add(peakSeries); dataGroup.Add(errorSeries); return(new CycleDataGroup(dataGroup)); }
public static CycleDataGroup ToCycleDataGroup(DataSeries dataSeries, double frequency) { DataGroup dataGroup = new DataGroup(); DataSeries rmsSeries = new DataSeries(); DataSeries phaseSeries = new DataSeries(); DataSeries peakSeries = new DataSeries(); DataSeries errorSeries = new DataSeries(); int samplesPerCycle; double[] yValues; double[] tValues; double sum; DateTime cycleTime; SineWave sineFit; if ((object)dataSeries == null) { return(null); } // Set series info to the source series info rmsSeries.SeriesInfo = dataSeries.SeriesInfo; phaseSeries.SeriesInfo = dataSeries.SeriesInfo; peakSeries.SeriesInfo = dataSeries.SeriesInfo; errorSeries.SeriesInfo = dataSeries.SeriesInfo; // Get samples per cycle of the data series based on the given frequency samplesPerCycle = CalculateSamplesPerCycle(dataSeries, frequency); // Initialize arrays of y-values and t-values for calculating cycle data yValues = new double[samplesPerCycle]; tValues = new double[samplesPerCycle]; // Obtain a list of time gaps in the data series List <int> gapIndexes = Enumerable.Range(0, dataSeries.DataPoints.Count - 1) .Where(index => { DataPoint p1 = dataSeries[index]; DataPoint p2 = dataSeries[index + 1]; double cycleDiff = (p2.Time - p1.Time).TotalSeconds * frequency; // Detect gaps larger than a quarter cycle. // Tolerance of 0.000062 calculated // assuming 3.999 samples per cycle return(cycleDiff > 0.250062); }) .ToList(); for (int i = 0; i <= dataSeries.DataPoints.Count - samplesPerCycle; i++) { // If the cycle following i contains a data gap, do not calculate cycle data if (gapIndexes.Any(index => i <= index && (i + samplesPerCycle - 1) > index)) { continue; } // Use the time of the first data point in the cycle as the time of the cycle cycleTime = dataSeries.DataPoints[i].Time; sum = 0.0D; // Copy values from the original data series into the y-value and t-value arrays for (int j = 0; j < samplesPerCycle; j++) { yValues[j] = dataSeries.DataPoints[i + j].Value; tValues[j] = (dataSeries.DataPoints[i + j].Time - cycleTime).TotalSeconds; sum += yValues[j] * yValues[j]; } // Use a curve fitting algorithm to estimate the sine wave over this cycle sineFit = WaveFit.SineFit(yValues, tValues, frequency); // Add data points to each of the cycle data series rmsSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = Math.Sqrt(sum / samplesPerCycle) }); phaseSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = sineFit.Phase }); peakSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = sineFit.Amplitude }); errorSeries.DataPoints.Add(new DataPoint() { Time = cycleTime, Value = tValues .Select(sineFit.CalculateY) .Zip(yValues, (estimate, value) => Math.Abs(estimate - value)) .Sum() }); } // Add a series to the data group for each series of cycle data dataGroup.Add(rmsSeries); dataGroup.Add(phaseSeries); dataGroup.Add(peakSeries); dataGroup.Add(errorSeries); return(new CycleDataGroup(dataGroup)); }
// Static Methods private static Series GetSeriesInfo(Meter meter, DataGroup dataGroup, string measurementTypeName, string phaseName, int assetID) { 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(assetID, 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) { Channel dbChannel = meter.Channels .FirstOrDefault(channel => channelKey.Equals(new ChannelKey(channel))); //need to get Asset based on the asset of the datagroup or the connected assets Asset asset = dataGroup.Asset; if (asset.ID != assetID) { List <Asset> connectedAssets = asset.ConnectedAssets.ToList(); asset = connectedAssets.Find(item => item.ID == assetID); } if ((object)dbChannel == null) { MeasurementType measurementType = new MeasurementType() { Name = measurementTypeName }; MeasurementCharacteristic measurementCharacteristic = new MeasurementCharacteristic() { Name = measurementCharacteristicName }; Phase phase = new Phase() { Name = phaseName }; dbChannel = new Channel() { MeterID = meter.ID, AssetID = assetID, MeasurementTypeID = measurementType.ID, MeasurementCharacteristicID = measurementCharacteristic.ID, PhaseID = phase.ID, Name = channelKey.Name, SamplesPerHour = dataGroup.SamplesPerHour, Description = string.Concat(measurementCharacteristicName, " ", measurementTypeName, " ", phaseName), Enabled = true, Meter = meter, Asset = asset, MeasurementType = measurementType, MeasurementCharacteristic = measurementCharacteristic, Phase = phase, Series = new List <Series>() }; meter.Channels.Add(dbChannel); } SeriesType seriesType = new SeriesType() { Name = seriesTypeName }; dbSeries = new Series() { ChannelID = dbChannel.ID, SeriesTypeID = seriesType.ID, SourceIndexes = string.Empty, Channel = dbChannel, SeriesType = seriesType }; dbChannel.Series.Add(dbSeries); } return(dbSeries); }
public VIDataGroup(DataGroup dataGroup) { // Initialize each of // the indexes to -1 m_vIndices = new List <VIndices>(); m_iaIndex = -1; m_ibIndex = -1; m_icIndex = -1; m_irIndex = -1; // Initialize the data group m_dataGroup = new DataGroup(dataGroup.DataSeries, dataGroup.Asset); // List of Indices matching channel type List <int> vaIndices = new List <int>(); List <int> vbIndices = new List <int>(); List <int> vcIndices = new List <int>(); List <int> vabIndices = new List <int>(); List <int> vbcIndices = new List <int>(); List <int> vcaIndices = new List <int>(); List <int> iaIndices = new List <int>(); List <int> ibIndices = new List <int>(); List <int> icIndices = new List <int>(); List <int> iresIndices = new List <int>(); for (int i = 0; i < dataGroup.DataSeries.Count; i++) { if (isVoltage("AN", dataGroup[i])) { vaIndices.Add(i); } else if (isVoltage("BN", dataGroup[i])) { vbIndices.Add(i); } else if (isVoltage("CN", dataGroup[i])) { vcIndices.Add(i); } else if (isVoltage("AB", dataGroup[i])) { vabIndices.Add(i); } else if (isVoltage("BC", dataGroup[i])) { vbcIndices.Add(i); } else if (isVoltage("CA", dataGroup[i])) { vcaIndices.Add(i); } else if (isCurrent("AN", dataGroup[i])) { iaIndices.Add(i); } else if (isCurrent("BN", dataGroup[i])) { ibIndices.Add(i); } else if (isCurrent("CN", dataGroup[i])) { icIndices.Add(i); } else if (isCurrent("RES", dataGroup[i])) { iresIndices.Add(i); } } //Walk through all Va and try to get corresponding Vb and Vc... List <int?> ProcessedIndices = new List <int?>(); foreach (int?VaIndex in vaIndices) { int assetID = dataGroup[(int)VaIndex].SeriesInfo.Channel.AssetID; int VbIndex = vbIndices.Cast <int?>().FirstOrDefault(i => dataGroup[(int)i].SeriesInfo.Channel.AssetID == assetID && !ProcessedIndices.Contains(i)) ?? -1; int VcIndex = vcIndices.Cast <int?>().FirstOrDefault(i => dataGroup[(int)i].SeriesInfo.Channel.AssetID == assetID && !ProcessedIndices.Contains(i)) ?? -1; int VabIndex = vabIndices.Cast <int?>().FirstOrDefault(i => dataGroup[(int)i].SeriesInfo.Channel.AssetID == assetID && !ProcessedIndices.Contains(i)) ?? -1; int VbcIndex = vbcIndices.Cast <int?>().FirstOrDefault(i => dataGroup[(int)i].SeriesInfo.Channel.AssetID == assetID && !ProcessedIndices.Contains(i)) ?? -1; int VcaIndex = vcaIndices.Cast <int?>().FirstOrDefault(i => dataGroup[(int)i].SeriesInfo.Channel.AssetID == assetID && !ProcessedIndices.Contains(i)) ?? -1; VIndices set = new VIndices(); ProcessedIndices.Add(VaIndex); set.Va = (int)VaIndex; if (VbIndex > -1) { ProcessedIndices.Add(VbIndex); set.Vb = VbIndex; } if (VcIndex > -1) { ProcessedIndices.Add(VcIndex); set.Vc = VcIndex; } if (VabIndex > -1) { ProcessedIndices.Add(VabIndex); set.Vab = VabIndex; } if (VbcIndex > -1) { ProcessedIndices.Add(VbcIndex); set.Vbc = VbcIndex; } if (VcaIndex > -1) { ProcessedIndices.Add(VcaIndex); set.Vca = VcaIndex; } if (assetID == dataGroup.Asset.ID) { set.distance = 0; } else { set.distance = dataGroup.Asset.DistanceToAsset(assetID); } m_vIndices.Add(set); } // Start by matching //Check if a voltage and current channnel exist on this asset if (iaIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).Count() > 0) { m_iaIndex = iaIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).First(); } if (ibIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).Count() > 0) { m_ibIndex = ibIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).First(); } if (icIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).Count() > 0) { m_icIndex = icIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).First(); } if (iresIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).Count() > 0) { m_irIndex = iresIndices.Where(i => dataGroup[i].SeriesInfo.Channel.AssetID == dataGroup.Asset.ID).First(); } // use one of the connected Assets List <int> connectedAssets = dataGroup.Asset.ConnectedAssets.Select(item => item.ID).ToList(); if (m_iaIndex == -1 && iaIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).Count() > 0) { m_iaIndex = iaIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).First(); } if (m_ibIndex == -1 && ibIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).Count() > 0) { m_ibIndex = ibIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).First(); } if (m_icIndex == -1 && icIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).Count() > 0) { m_icIndex = icIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).First(); } if (m_irIndex == -1 && iresIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).Count() > 0) { m_irIndex = iresIndices.Where(i => connectedAssets.Contains(dataGroup[i].SeriesInfo.Channel.AssetID)).First(); } if (m_iaIndex == -1 && iaIndices.Count() > 0) { m_iaIndex = iaIndices.First(); } if (m_ibIndex == -1 && ibIndices.Count() > 0) { m_ibIndex = ibIndices.First(); } if (m_ibIndex == -1 && ibIndices.Count() > 0) { m_ibIndex = icIndices.First(); } if (m_irIndex == -1 && iresIndices.Count() > 0) { m_irIndex = iresIndices.First(); } if (m_vIndices.Count() == 0) { m_vIndices.Add(new VIndices()); } CalculateMissingCurrentChannel(); CalculateMissingLLVoltageChannels(); //sort by all available Channels and number of Hops to actual Asset m_vIndices.Sort((a, b) => { if (b.allVoltagesDefined && !a.allVoltagesDefined) { return(1); } if (a.allVoltagesDefined && !b.allVoltagesDefined) { return(-1); } return(a.distance.CompareTo(b.distance)); }); }
private void ProcessReportedDisturbances(Meter meter, DataGroup dataGroup) { Line line = dataGroup.Line; if ((object)line == null) { if (meter.MeterLocation.MeterLocationLines.Count != 1) { return; } line = meter.MeterLocation.MeterLocationLines.Single().Line; } List <Disturbance> disturbanceList = dataGroup.Disturbances .Select(disturbance => ToDisturbance(line, disturbance)) .Where(IsDisturbed) .ToList(); if (dataGroup.Samples > 0) { DateTime startTime = dataGroup.StartTime; DateTime endTime = dataGroup.EndTime; TimeSpan duration = (endTime - startTime); foreach (Disturbance disturbance in disturbanceList) { TimeSpan startDuration = disturbance.StartTime - startTime; TimeSpan endDuration = disturbance.EndTime - startTime; disturbance.StartIndex = (int)((startDuration.TotalSeconds / duration.TotalSeconds) * dataGroup.Samples); disturbance.EndIndex = (int)((endDuration.TotalSeconds / duration.TotalSeconds) * dataGroup.Samples); } } IEnumerable <Range <DateTime> > allDisturbanceRanges = disturbanceList .Select(ToDateRange); IEnumerable <Disturbance> worstDisturbances = Range <DateTime> .MergeAllOverlapping(allDisturbanceRanges) .Select(range => { Disturbance worst = null; foreach (Disturbance disturbance in disturbanceList.Where(disturbance => ToDateRange(disturbance).Overlaps(range))) { if ((object)worst == null || m_isMoreSevere(disturbance.PerUnitMagnitude, worst.PerUnitMagnitude)) { worst = disturbance; } } worst = worst.Clone(); worst.Phase = Phase.Worst; return(worst); }); disturbanceList.AddRange(worstDisturbances); if (disturbanceList.Any()) { m_disturbances.Add(dataGroup, disturbanceList); } }
// Static Methods public static DataSeries AddMissingCurrentSeries(MeterInfoDataContext meterInfo, Meter meter, DataGroup dataGroup) { DataSeries missingSeries = null; // Get all necessary voltage and current channels in the proper order List <DataSeries> viSeriesList = Enumerable.Range(VAIndex, IRIndex + 1) .GroupJoin(dataGroup.DataSeries.Where(IsInstantaneous), i => i, GetIndex, (i, series) => series.FirstOrDefault()) .ToList(); // Validate that no more than one current channel is missing if (viSeriesList.Count(series => (object)series == null) > 1) { return(null); } // Attempt to fill in missing current channels // based on the relation IR = IA + IB + IC if ((object)viSeriesList[IAIndex] == null) { missingSeries = viSeriesList[IRIndex]; missingSeries = missingSeries.Add(viSeriesList[IBIndex].Negate()); missingSeries = missingSeries.Add(viSeriesList[ICIndex].Negate()); missingSeries.SeriesInfo = GetSeriesInfo(meterInfo, meter, dataGroup, IAIndex); missingSeries.SeriesInfo.Channel.Line = viSeriesList[IBIndex].SeriesInfo.Channel.Line; viSeriesList[IAIndex] = missingSeries; } else if ((object)viSeriesList[IBIndex] == null) { missingSeries = viSeriesList[IRIndex]; missingSeries = missingSeries.Add(viSeriesList[IAIndex].Negate()); missingSeries = missingSeries.Add(viSeriesList[ICIndex].Negate()); missingSeries.SeriesInfo = GetSeriesInfo(meterInfo, meter, dataGroup, IBIndex); missingSeries.SeriesInfo.Channel.Line = viSeriesList[IAIndex].SeriesInfo.Channel.Line; viSeriesList[IBIndex] = missingSeries; } else if ((object)viSeriesList[ICIndex] == null) { missingSeries = viSeriesList[IRIndex]; missingSeries = missingSeries.Add(viSeriesList[IAIndex].Negate()); missingSeries = missingSeries.Add(viSeriesList[IBIndex].Negate()); missingSeries.SeriesInfo = GetSeriesInfo(meterInfo, meter, dataGroup, ICIndex); missingSeries.SeriesInfo.Channel.Line = viSeriesList[IAIndex].SeriesInfo.Channel.Line; viSeriesList[ICIndex] = missingSeries; } else if ((object)viSeriesList[IRIndex] == null) { missingSeries = viSeriesList[IAIndex]; missingSeries = missingSeries.Add(viSeriesList[IBIndex]); missingSeries = missingSeries.Add(viSeriesList[ICIndex]); missingSeries.SeriesInfo = GetSeriesInfo(meterInfo, meter, dataGroup, IRIndex); missingSeries.SeriesInfo.Channel.Line = viSeriesList[IAIndex].SeriesInfo.Channel.Line; viSeriesList[IRIndex] = missingSeries; } if ((object)missingSeries != null) { dataGroup.Add(missingSeries); } return(missingSeries); }
// 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); }
public CycleDataGroup(DataGroup dataGroup) { m_dataGroup = dataGroup; }
public CycleDataGroup(DataGroup dataGroup, Asset asset) { m_dataGroup = dataGroup; m_asset = asset; }
public VIDataGroup(DataGroup dataGroup) { string[] instantaneousSeriesTypes = { "Values", "Instantaneous" }; // Initialize each of // the indexes to -1 m_vaIndex = -1; m_vbIndex = -1; m_vcIndex = -1; m_vabIndex = -1; m_vbcIndex = -1; m_vcaIndex = -1; m_iaIndex = -1; m_ibIndex = -1; m_icIndex = -1; m_irIndex = -1; // Initialize the data group m_dataGroup = new DataGroup(dataGroup.DataSeries); for (int i = 0; i < dataGroup.DataSeries.Count; i++) { string measurementType = dataGroup[i].SeriesInfo.Channel.MeasurementType.Name; string measurementCharacteristic = dataGroup[i].SeriesInfo.Channel.MeasurementCharacteristic.Name; string seriesType = dataGroup[i].SeriesInfo.SeriesType.Name; string phase = dataGroup[i].SeriesInfo.Channel.Phase.Name; // If the data group is not instantaneous, do not use it in the VIDataGroup if (measurementCharacteristic != "Instantaneous") { continue; } // If the data group is not instantaneous, do not use it in the VIDataGroup if (!instantaneousSeriesTypes.Contains(seriesType)) { continue; } // Assign the proper indexes for the seven VIDataGroup // channels by checking the name of the channel if (measurementType == "Voltage" && phase == "AN") { m_vaIndex = i; } else if (measurementType == "Voltage" && phase == "BN") { m_vbIndex = i; } else if (measurementType == "Voltage" && phase == "CN") { m_vcIndex = i; } else if (measurementType == "Voltage" && phase == "AB") { m_vabIndex = i; } else if (measurementType == "Voltage" && phase == "BC") { m_vbcIndex = i; } else if (measurementType == "Voltage" && phase == "CA") { m_vcaIndex = i; } else if (measurementType == "Current" && phase == "AN") { m_iaIndex = i; } else if (measurementType == "Current" && phase == "BN") { m_ibIndex = i; } else if (measurementType == "Current" && phase == "CN") { m_icIndex = i; } else if (measurementType == "Current" && phase == "RES") { m_irIndex = i; } } CalculateMissingLLVoltageChannels(); }
public static Event GetEvent(this TableOperations <Event> eventTable, FileGroup fileGroup, DataGroup dataGroup) { int fileGroupID = fileGroup.ID; int lineID = dataGroup.Line.ID; DateTime startTime = dataGroup.StartTime; DateTime endTime = dataGroup.EndTime; int samples = dataGroup.Samples; IDbDataParameter startTimeParameter = new SqlParameter() { ParameterName = nameof(dataGroup.StartTime), DbType = DbType.DateTime2, Value = startTime }; IDbDataParameter endTimeParameter = new SqlParameter() { ParameterName = nameof(dataGroup.EndTime), DbType = DbType.DateTime2, Value = endTime }; RecordRestriction recordRestriction = new RecordRestriction("FileGroupID = {0}", fileGroupID) & new RecordRestriction("LineID = {0}", lineID) & new RecordRestriction("StartTime = {0}", startTimeParameter) & new RecordRestriction("EndTime = {0}", endTimeParameter) & new RecordRestriction("Samples = {0}", samples); return(eventTable.QueryRecord(recordRestriction)); }