/// <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);
        }
Beispiel #3
0
        /// <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);
        }