/// <summary> /// /// </summary> /// <param name="lpResult" type="Itron.Metering.DeviceDataTypes.LoadProfilePulseData"> /// </param> /// <param name="dtCurrentInterval" type="System.DateTime"> /// </param> /// <param name="dtGapEndTime" type="System.DateTime"> /// </param> /// <remarks> /// Revision History /// MM/DD/YY Who Version Issue# Description /// -------- --- ------- ------ --------------------------------------------- /// 08/26/08 mah 9.50.00 Created /// /// </remarks> private void FillDataGap(LoadProfilePulseData lpResult, ref DateTime dtCurrentInterval, DateTime dtGapEndTime) { double[] dblIntervalData = new double[NumProfileChannels]; String[] strChannelStatus = new String[NumProfileChannels]; String strIntervalStatus = "K"; // Every interval in the gap will have a value of 0 with an empty channel // status for (int nChannelIndex = 0; nChannelIndex < NumProfileChannels; nChannelIndex++) { dblIntervalData[nChannelIndex] = 0.0; strChannelStatus[nChannelIndex] = ""; } // Now simply walk through the time period defined by the gap and adding // one interval at a time while (dtCurrentInterval < dtGapEndTime) { lpResult.AddInterval(dblIntervalData, strChannelStatus, strIntervalStatus, dtCurrentInterval, DisplayScaleOptions.UNITS); // Advance the clock one interval at a time. dtCurrentInterval = dtCurrentInterval.AddMinutes((double)IntervalLength); } }
/// <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> /// Creates the LoadProfileData object from the specified blocks. /// </summary> /// <param name="loadProfileBlocks">The list of blocks to use to create the object ordered by date.</param> /// <param name="setLimits">The set limits for the data set</param> /// <param name="setDataSelection">The data selection for the data set</param> /// <returns>The LoadProfileData object.</returns> // 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 LoadProfileData CreateLoadProfileDataObject(LPBlockDataRecord[] loadProfileBlocks, LPSetActualLimits setLimits, LPSetDataSelection setDataSelection) { LoadProfileData LPData = new LoadProfilePulseData(setLimits.IntervalLength); AddChannels(ref LPData, setLimits, setDataSelection); AddIntervals(ref LPData, loadProfileBlocks); return(LPData); }
/// <summary> /// /// </summary> /// <param name="lpResult" type="Itron.Metering.DeviceDataTypes.LoadProfilePulseData"> /// </param> /// <returns> /// A Itron.Metering.Datafiles.AggregrateContributors.AggregationResult value... /// </returns> /// <remarks> /// Revision History /// MM/DD/YY Who Version Issue# Description /// -------- --- ------- ------ --------------------------------------------- /// 12/19/08 mah 9.50.00 CQ142242 Added conditional to prevent infinite loop /// </remarks> private AggregationResult Join(out LoadProfilePulseData lpResult) { lpResult = null; AggregationResult Result = Validate(); if (Result == AggregationResult.Success) { lpResult = new LoadProfilePulseData(IntervalLength); // Add the appropriate number of channels for (int nChannelIndex = 0; nChannelIndex < NumProfileChannels; nChannelIndex++) { // The channels will assume the same name as the first contributor lpResult.AddChannel(m_lstDataSources[0].LPData.Channels[nChannelIndex].ChannelName, (float)1.0, (float)1.0); } DateTime dtCurrentInterval = ProfileStartTime; DateTime dtLastInterval = ProfileEndTime; // It is most efficient if we start by sorting the contributors // in order of their start times. This allows us to easily determine // where gaps exist in the data and fill them as we go m_lstDataSources.Sort(CompareStartTime); int nContributorIndex = 0; // We may or may not need all contributors - the best way to know when // we are done is by looking at the last interval in the result set. // Once we have the last interval, we can stop while ((dtCurrentInterval < dtLastInterval) && (nContributorIndex < m_lstDataSources.Count)) { // Start by trying to find a data source that contains the interval we // are looking for. Note that the call to GetIntervalIndexAt will return an // index greater than number of intervals in the data set if the interval is not // found int nIntervalIndex = m_lstDataSources[nContributorIndex].LPData.GetIntervalIndexAt(dtCurrentInterval); if (nIntervalIndex < m_lstDataSources[nContributorIndex].LPData.NumberIntervals) { // OK, we found the interval we were looking for. Since we are just joining // data we should be joining pulse data so try to get a reference to a pulse // data object. If we can't get one just use what we already have. LoadProfilePulseData LPPulseData = m_lstDataSources[nContributorIndex].LPData as LoadProfilePulseData; if (LPPulseData != null) { MergeContributorData(lpResult, LPPulseData, ref dtCurrentInterval); } else { MergeContributorData(lpResult, m_lstDataSources[nContributorIndex].LPData, ref dtCurrentInterval); } // Move on to the next contributor - at this point we should have retrieved // all of the information that we could from the current data source. The next // set of data will either come from the next contributor or it will be a data // gap nContributorIndex++; } else if (dtCurrentInterval > m_lstDataSources[nContributorIndex].LPData.StartTime) { // No gap here - just go to the next contributor - MAH 12/19/08 nContributorIndex++; } else // we found a gap in the data! We need to add filler { FillDataGap(lpResult, ref dtCurrentInterval, m_lstDataSources[nContributorIndex].LPData.StartTime); } } } return(Result); }