/// <summary> /// Merge the data from the given source to the destination structure /// </summary> /// <param name="lpDestination" type="Itron.Metering.DeviceDataTypes.LoadProfilePulseData"> /// </param> /// <param name="lpSource" type="Itron.Metering.DeviceDataTypes.LoadProfileData"> /// </param> /// <param name="dtCurrentInterval" type="System.DateTime"> /// </param> /// <remarks> /// Revision History /// MM/DD/YY Who Version Issue# Description /// -------- --- ------- ------ --------------------------------------------- /// 12/15/08 mah 9.50.26 CQ124360 Incremented the interval end time to advance /// to the next interval /// /// </remarks> private void MergeContributorData(LoadProfilePulseData lpDestination, LoadProfileData lpSource, ref DateTime dtCurrentInterval) { int nIntervalIndex = lpSource.GetIntervalIndexAt(dtCurrentInterval); while (nIntervalIndex < lpSource.NumberIntervals) { // We found useful data - now add all that we can to the result data. // We don't have to worry about the end date since the whole purpose of // aggregation is to join as much data as possible LPInterval nextInterval = lpSource.Intervals[nIntervalIndex]; lpDestination.AddInterval( nextInterval.Data, nextInterval.ChannelStatuses, nextInterval.IntervalStatus, nextInterval.Time, DisplayScaleOptions.UNITS); dtCurrentInterval = lpDestination.EndTime; nIntervalIndex++; } // Advance the clock to the next interval dtCurrentInterval = dtCurrentInterval.AddMinutes((double)IntervalLength); }
/// <summary> /// Adds all of the intervals in the specified blocks. /// </summary> /// <param name="loadProfileData">The load profile object to add the intervals to.</param> /// <param name="loadProfileBlocks">The load profile blocks to add.</param> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 10/06/08 RCG 2.00.00 N/A Created private void AddIntervals(ref LoadProfileData loadProfileData, LPBlockDataRecord[] loadProfileBlocks) { for (int iBlock = 0; iBlock < loadProfileBlocks.Length; iBlock++) { LPBlockDataRecord CurrentBlock = loadProfileBlocks[iBlock]; LPIntervalDataRecord LastInterval = CurrentBlock.Intervals[CurrentBlock.Intervals.Length - 1]; for (int iInterval = 0; iInterval < CurrentBlock.Intervals.Length; iInterval++) { LPIntervalDataRecord CurrentInterval = CurrentBlock.Intervals[iInterval]; DateTime IntervalTime; if (iInterval + 1 < CurrentBlock.Intervals.Length) { // Figure out the time of the interval. IntervalTime = DetermineIntervalTime(CurrentBlock, iInterval, loadProfileData.IntervalDuration); IntervalTime = AdjustTimeForDST(IntervalTime, CurrentInterval, CurrentBlock.Intervals[iInterval + 1], LastInterval); } else { // We already know the time of the last interval. IntervalTime = (DateTime)CurrentBlock.BlockEndTime; } loadProfileData.AddInterval(CurrentInterval.IntervalData, ConvertChannelStatuses(CurrentInterval), ConvertIntervalStatus(CurrentInterval), IntervalTime, DisplayScaleOptions.UNITS); } } }
/// <summary> /// Get the all of the Profile Data from the specified set of tables /// </summary> /// <param name="actualLimitingTable">The actual limiting table for the data set</param> /// <param name="controlTable">The control table for the data set</param> /// <param name="statusTable">The status table for the data set</param> /// <param name="dataSetTable">The data set table for the data set</param> /// <returns>The profile data that has been read.</returns> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 12/06/11 RCG 2.53.20 N/A Created // 06/15/12 jrf 2.60.32 199972 Adding logging statements to help debug issue next time we see it. // protected LoadProfileData GetProfileData(StdTable61 actualLimitingTable, StdTable62 controlTable, StdTable63 statusTable, StdTable64 dataSetTable) { LoadProfileData LPData = null; LPSetActualLimits SetLimits = actualLimitingTable.GetSetLimits(dataSetTable.DataSet); LPSetDataSelection SetDataSelection = controlTable.GetDataSelection(dataSetTable.DataSet); LPBlockDataRecord[] Blocks; LPBlockDataRecord FirstBlock; LPBlockDataRecord LastBlock; LPSetStatusRecord SetStatus; ushort NumberOfBlocks; ushort FirstBlockIndex; m_Logger.WriteLine(Logger.LoggingLevel.Functional, "Getting Profile Data"); SetStatus = statusTable.GetSetStatusRecord(dataSetTable.DataSet); m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Number of Blocks: " + SetStatus.NumberOfValidBlocks.ToString(CultureInfo.InvariantCulture)); m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Number of Intervals: " + SetStatus.NumberOfValidIntervals.ToString(CultureInfo.InvariantCulture)); if (SetStatus.NumberOfValidBlocks > 0 && SetStatus.NumberOfValidIntervals > 0) { OnShowProgress(new ShowProgressEventArgs(1, SetStatus.NumberOfValidBlocks, "Reading Load Profile data...", "Reading Load Profile data...")); // Read the first and last blocks GetFirstAndLastBlock(actualLimitingTable, statusTable, dataSetTable, out FirstBlock, out LastBlock, out SetStatus); // Read the rest of the blocks using the last block status NumberOfBlocks = SetStatus.NumberOfValidBlocks; Blocks = new LPBlockDataRecord[NumberOfBlocks]; Blocks[0] = FirstBlock; if (NumberOfBlocks > 1) { Blocks[NumberOfBlocks - 1] = LastBlock; FirstBlockIndex = (ushort)((SetStatus.LastBlockElement + 1) % NumberOfBlocks); for (ushort RelativeBlockIndex = 1; RelativeBlockIndex < NumberOfBlocks - 1; RelativeBlockIndex++) { ushort ActualBlockIndex = (ushort)((FirstBlockIndex + RelativeBlockIndex) % NumberOfBlocks); m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Reading Block # " + ActualBlockIndex.ToString(CultureInfo.InvariantCulture)); Blocks[RelativeBlockIndex] = ReadLPBlock(dataSetTable, ActualBlockIndex, SetLimits.IntervalsPerBlock); OnStepProgress(new ProgressEventArgs()); } } OnHideProgress(new EventArgs()); // Create the LoadProfileData object. LPData = CreateLoadProfileDataObject(Blocks, SetLimits, SetDataSelection); } return(LPData); }
/// <summary> /// Adds the channels to the LoadProfilData object. /// </summary> /// <param name="loadProfileData">The LoadProfileData object to add the channels to.</param> /// <param name="setLimits">The set limits for the data set</param> /// <param name="setDataSelection">The data selection for the data set</param> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 10/03/08 RCG 2.00.00 N/A Created // 12/12/11 RCG 2.53.20 Modified for Extended LP and IP support private void AddChannels(ref LoadProfileData loadProfileData, LPSetActualLimits setLimits, LPSetDataSelection setDataSelection) { List <string> ChannelNames = DetermineChannelNames(setDataSelection); List <float> PulseWeights = DeterminePulseWeights(setLimits, setDataSelection); for (int iChannel = 0; iChannel < setLimits.NumberOfChannels; iChannel++) { loadProfileData.AddChannel(ChannelNames[iChannel], PulseWeights[iChannel], 1.0f); } }
/// <summary> /// This method returns the index of the load profile interval that ends on the /// given date/time. If the given contributor does not contain profile data for /// the given date/time, then a value of -1 will be returned /// </summary> /// <param name="lpContributor" type="Itron.Metering.DeviceDataTypes.LoadProfileData"> /// </param> /// <param name="dtTarget" type="System.DateTime"> /// </param> /// <remarks> /// Revision History /// MM/DD/YY Who Version Issue# Description /// -------- --- ------- ------ --------------------------------------------- /// 08/25/08 mah 9.50.00 Created /// /// </remarks> protected int FindIntervalIndex(LoadProfileData lpContributor, DateTime dtTarget) { int nIntervalIndex = 0; Boolean boolDateFound = false; while (nIntervalIndex < lpContributor.NumberIntervals && !boolDateFound) { if (lpContributor.Intervals[nIntervalIndex].Time == dtTarget) { boolDateFound = true; } else { nIntervalIndex++; } } if (!boolDateFound) { nIntervalIndex = -1; } return(nIntervalIndex); }
/// <summary> /// Gets the load profile data between the specified dates. /// </summary> /// <param name="startDate">The start date of the load profile data to get.</param> /// <param name="endDate">The end date of the load profile data to get.</param> /// <param name="actualLimitingTable">The actual limiting table for the data set</param> /// <param name="controlTable">The control table for the data set</param> /// <param name="statusTable">The status table for the data set</param> /// <param name="dataSetTable">The data set table for the data set</param> /// <returns>The load profile data from the dates specified.</returns> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 12/06/11 RCG 2.53.20 N/A Created public LoadProfileData GetProfileData(DateTime startDate, DateTime endDate, StdTable61 actualLimitingTable, StdTable62 controlTable, StdTable63 statusTable, StdTable64 dataSetTable) { LPSetActualLimits SetLimits = actualLimitingTable.GetSetLimits(dataSetTable.DataSet); LPBlockDataRecord FirstBlock; LPBlockDataRecord LastBlock; LPBlockDataRecord[] Blocks; LPSetStatusRecord SetStatus; LoadProfileData LPData = null; int StartBlockIndex; int EndBlockIndex; int FirstBlockIndex; SetStatus = statusTable.GetSetStatusRecord(dataSetTable.DataSet); if (SetStatus != null) { if (SetStatus.NumberOfValidBlocks > 1 && SetStatus.NumberOfValidIntervals > 0) { OnShowProgress(new ShowProgressEventArgs(1, 2, "Determining blocks to read...", "Determining blocks to read...")); // Get the first and last blocks in order to determine the blocks we need to read. GetFirstAndLastBlock(actualLimitingTable, statusTable, dataSetTable, out FirstBlock, out LastBlock, out SetStatus); OnStepProgress(new ProgressEventArgs()); // Determine which blocks to read StartBlockIndex = DetermineStartBlockIndex(SetLimits, SetStatus, FirstBlock, startDate); EndBlockIndex = DetermineEndBlockIndex(SetLimits, SetStatus, LastBlock, endDate); Blocks = new LPBlockDataRecord[EndBlockIndex - StartBlockIndex + 1]; FirstBlockIndex = (SetStatus.LastBlockElement + 1) % SetStatus.NumberOfValidBlocks; OnHideProgress(new EventArgs()); OnShowProgress(new ShowProgressEventArgs(1, EndBlockIndex - StartBlockIndex, "Reading Load Profile data...", "Reading Load Profile data...")); // Read the blocks for (int RelativeBlockIndex = StartBlockIndex; RelativeBlockIndex <= EndBlockIndex; RelativeBlockIndex++) { int BlockArrayIndex = RelativeBlockIndex - StartBlockIndex; OnStepProgress(new ProgressEventArgs()); // We already have the first and last blocks so just add those if included. if (RelativeBlockIndex == 0) { Blocks[BlockArrayIndex] = FirstBlock; } else if (RelativeBlockIndex == SetStatus.NumberOfValidBlocks - 1) { // The last block Blocks[BlockArrayIndex] = LastBlock; } else { // We need to read the block ushort ActualBlockIndex = (ushort)((FirstBlockIndex + RelativeBlockIndex) % SetStatus.NumberOfValidBlocks); Blocks[BlockArrayIndex] = ReadLPBlock(dataSetTable, ActualBlockIndex, SetLimits.IntervalsPerBlock); } } OnStepProgress(new ProgressEventArgs("Creating Load Profile object...")); // Create the LoadProfileData object. LPData = CreateLoadProfileDataObject(Blocks, SetLimits, controlTable.GetDataSelection(dataSetTable.DataSet)); OnStepProgress(new ProgressEventArgs("Removing additional intervals...")); // Trim out intervals that were not requested. LPData.Intervals.RemoveAll(delegate(LPInterval interval) { return(interval.Time < startDate || interval.Time > endDate); }); OnHideProgress(new EventArgs()); } else if (SetStatus.NumberOfValidBlocks == 1) { OnShowProgress(new ShowProgressEventArgs(1, 3, "Reading Load Profile data...", "Reading Load Profile data...")); // Just get the first block the trim will take care of anything outside the range FirstBlock = GetFirstBlock(actualLimitingTable, statusTable, dataSetTable, out SetStatus); OnStepProgress(new ProgressEventArgs()); LPData = CreateLoadProfileDataObject(new LPBlockDataRecord[] { FirstBlock }, SetLimits, controlTable.GetDataSelection(dataSetTable.DataSet)); OnStepProgress(new ProgressEventArgs()); // Trim out intervals that were not requested. LPData.Intervals.RemoveAll(delegate(LPInterval interval) { return(interval.Time < startDate || interval.Time > endDate); }); OnStepProgress(new ProgressEventArgs()); OnHideProgress(new EventArgs()); } } return(LPData); }
/// <summary> /// Constructor used when writing a CRF file /// </summary> /// <param name="LPData">Load Profile Data to write to CRF file</param> public CRFLPDataType(LoadProfileData LPData) : base() { m_LPData = LPData; }