// Note: The following source codes are for TOU and DST reconfiguration. // Note: Due to circular dependency issue, those codes are here temporarily, later we need to do reflection. /// <summary> /// This method imports the TOU configuration into the file. /// </summary> /// <param name="strTOUFileName">The TOU schedule file name.</param> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 11/16/10 jrf 2.45.13 Created // 12/01/10 deo 9.70.12 fix for CQ165091 private void ImportTOU(string strTOUFileName) { CTOUSchedule TOUSchedule = new CTOUSchedule(strTOUFileName); int[] aiIndex1 = { 0 }; int[] aiIndex2 = { 0, 0 }; int[] aiIndex3 = { 0, 0, 0 }; //TODO: Update CentronTblEnum values based on updates Steve makes... //Calendar ID m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_CALENDAR_ID, null, TOUSchedule.TOUID); //DemandReset/Season Change Options int SeasonChgOption = 1; // Demand reset at the season change. m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_DEMAND_RESET, null, (byte)SeasonChgOption); //DST Hour m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_DST_HOUR, null, 0); //DST Minute m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_DST_MINUTE, null, 0); //DST Offset m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_DST_OFFSET, null, 0); //Calendar Years for (int iYear = 0; iYear < TOUSchedule.Years.Count; iYear++) { CYear Year = TOUSchedule.Years[iYear]; aiIndex1[0] = iYear; aiIndex2[0] = iYear; //Year m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_CALENDAR_YEAR, aiIndex1, Year.Year - 2000); //Day Events for (int iEvent = 0; iEvent < TOUSchedule.Years[iYear].Events.Count; iEvent++) { CEvent Event = Year.Events[iEvent]; aiIndex2[1] = iEvent; byte bytCalEvent = 0; // Translate TOU schedule event to CalendarConfig event // fix for CQ 165091 if (Itron.Metering.TOU.eEventType.HOLIDAY == Event.Type) { bytCalEvent = (byte)CalendarEvent.CalendarEventType.HOLIDAY + 1; } else if (Itron.Metering.TOU.eEventType.SEASON == Event.Type) { bytCalEvent = (byte)((int)CalendarEvent.CalendarEventType.SEASON1 + Event.Index + 1); } else { bytCalEvent = 0; } //Event m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_CALENDAR_EVENT, aiIndex2, bytCalEvent); //Month m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_CALENDAR_MONTH, aiIndex2, Event.Date.Month - 1); //Day Of Month m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_CALENDAR_DAY_OF_MONTH, aiIndex2, Event.Date.Day - 1); } } //This value is the same for all seasons ushort usDayToDayType = GetTypicalWeek(TOUSchedule); //Seasons for (int iSeason = 0; iSeason < TOUSchedule.Seasons.Count; iSeason++) { CSeason Season = TOUSchedule.Seasons[iSeason]; int iTODEvent = 0; int iPatternIndex = 0; bool blnEventsNeedSorting = false; TOUConfig.TOU_Season ConfigSeason = new TOUConfig.TOU_Season(24, 4); aiIndex1[SEASON_INDEX] = iSeason; aiIndex3[SEASON_INDEX] = iSeason; //Programmed m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_PROGRAMMED, aiIndex1, 1); //Day to Day Types m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_DAY_TO_DAY_TYPE, aiIndex1, usDayToDayType); // Configure the normal daytypes (0..2) for (int DaytypeIndex = 0; DaytypeIndex < Season.NormalDays.Count; DaytypeIndex++) { // Get the index of the pattern in the schedule's // pattern collection that's assigned to this // daytype, so we can add its switchpoints iPatternIndex = TOUSchedule.Patterns.SearchID( Season.NormalDays[DaytypeIndex]); iTODEvent = 0; for (int EventIndex = 0; EventIndex < TOUSchedule.Patterns[iPatternIndex].SwitchPoints.Count; EventIndex++) { // Outputs switchpoints are a special case. A start and end // event must be added for outputs. CSwitchPoint SP = TOUSchedule.Patterns[iPatternIndex].SwitchPoints[EventIndex]; ConfigSeason.TimeOfDayEvents[DaytypeIndex, iTODEvent++] = GetDayEvent(SP); // Unlike rate switchpoints, outputs can overlap, so we // have to add the end point too. if (eSwitchPointType.OUTPUT == SP.SwitchPointType) { ConfigSeason.TimeOfDayEvents[DaytypeIndex, iTODEvent++] = GetOutputOffEvent(SP); // We'll need to sort the events since we added one blnEventsNeedSorting = true; } } // For each switchpoint } // Configure the Holiday daytype if it exists if (0 != Season.Holidays.Count) { // Get the index of the pattern in the schedule's // pattern collection that's assigned to this // (holiday) daytype, so we can add its switchpoints iPatternIndex = TOUSchedule.Patterns.SearchID(Season.Holidays[0]); iTODEvent = 0; for (int EventIndex = 0; EventIndex < TOUSchedule.Patterns[iPatternIndex].SwitchPoints.Count; EventIndex++) { // Outputs switchpoints are a special case. A start and end // event must be added for outputs. CSwitchPoint SP = TOUSchedule.Patterns[iPatternIndex].SwitchPoints[EventIndex]; ConfigSeason.TimeOfDayEvents[TOUConfig.HOLIDAY_TYPE_INDEX, iTODEvent++] = GetDayEvent(SP); // Unlike rate switchpoints, outputs can overlap, so we // have to add the end point too. if (eSwitchPointType.OUTPUT == SP.SwitchPointType) { ConfigSeason.TimeOfDayEvents[TOUConfig.HOLIDAY_TYPE_INDEX, iTODEvent++] = GetOutputOffEvent(SP); // We'll need to sort the events since we added one blnEventsNeedSorting = true; } } // For each switchpoint } // Sort the events if we added any if (blnEventsNeedSorting) { ConfigSeason.Sort(); } for (int DaytypeIndex = 0; DaytypeIndex < ConfigSeason.TimeOfDayEvents.GetLength(0); DaytypeIndex++) { for (int EventIndex = 0; EventIndex < ConfigSeason.TimeOfDayEvents.GetLength(1); EventIndex++) { TOUConfig.DayEvent DayEvt = ConfigSeason.TimeOfDayEvents[DaytypeIndex, EventIndex]; aiIndex3[DAY_TYPE_INDEX] = DaytypeIndex; aiIndex3[DAY_TYPE_EVENT_INDEX] = EventIndex; m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_TOU_DAY_TYPE_RATE_EVENT, aiIndex3, DayEvt.EventType); m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_TOU_DAY_TYPE_HOUR, aiIndex3, DayEvt.Hour); m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_TOU_DAY_TYPE_MINUTE, aiIndex3, DayEvt.Minute); } } if (0 != Season.Holidays.Count) { for (int EventIndex = 0; EventIndex < ConfigSeason.TimeOfDayEvents.GetLength(1); EventIndex++) { TOUConfig.DayEvent DayEvt = ConfigSeason.TimeOfDayEvents[TOUConfig.HOLIDAY_TYPE_INDEX, EventIndex]; aiIndex3[DAY_TYPE_INDEX] = TOUConfig.HOLIDAY_TYPE_INDEX; aiIndex3[DAY_TYPE_EVENT_INDEX] = EventIndex; m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_TOU_DAY_TYPE_RATE_EVENT, aiIndex3, DayEvt.EventType); m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_TOU_DAY_TYPE_HOUR, aiIndex3, DayEvt.Hour); m_TOUTables.SetValue(CentronTblEnum.MFGTBL42_TOU_DAY_TYPE_MINUTE, aiIndex3, DayEvt.Minute); } } } }
/// <summary> /// Reads the TOU Schedule from the meter into a TOUSchedule object /// </summary> /// <returns>The TOU Schedule object.</returns> // Revision History // MM/DD/YY who Version Issue# Description // -------- --- ------- ------ --------------------------------------- // 01/04/07 RCG 8.00.04 Made more generic and promoted from CENTRON_AMI // 04/13/07 RCG 8.00.31 2919 Adding support for Output events. // 03/10/08 KRC 1.50.02 Adding Ability to create TOU Schedule from EDL file // 12/03/10 DEO 9.70.13 Promoted from ANSIDevice public static CTOUSchedule ReadCENTRON2TOUSchedule(TOUConfig TOUConfigTable, CalendarConfig CalendarConfigTable) { Int16Collection NormalDays; Int16Collection HolidayDays; ANSITOUSchedule TOUSchedule = new ANSITOUSchedule(); TOUConfig.TOU_Season CurrentSeason; int iNextEventCounter = 0; int iPatternID = 0; try { // First set up the typical week so that we know which day corresponds to which daytype if (TOUConfigTable.NumberOfSupportedSeasons > 0) { CurrentSeason = TOUConfigTable.Seasons[0]; // We have to assume that the Typical week is that same for all seasons. NOTE: The Day to Daytype is 1 based // so we need to subtract 1 TOUSchedule.TypicalWeek[(int)eTypicalDay.SUNDAY] = TOUSchedule.NormalDays[CurrentSeason.TypicalSunday]; TOUSchedule.TypicalWeek[(int)eTypicalDay.MONDAY] = TOUSchedule.NormalDays[CurrentSeason.TypicalMonday]; TOUSchedule.TypicalWeek[(int)eTypicalDay.TUESDAY] = TOUSchedule.NormalDays[CurrentSeason.TypicalTuesday]; TOUSchedule.TypicalWeek[(int)eTypicalDay.WEDNESDAY] = TOUSchedule.NormalDays[CurrentSeason.TypicalWednesday]; TOUSchedule.TypicalWeek[(int)eTypicalDay.THURSDAY] = TOUSchedule.NormalDays[CurrentSeason.TypicalThursday]; TOUSchedule.TypicalWeek[(int)eTypicalDay.FRIDAY] = TOUSchedule.NormalDays[CurrentSeason.TypicalFriday]; TOUSchedule.TypicalWeek[(int)eTypicalDay.SATURDAY] = TOUSchedule.NormalDays[CurrentSeason.TypicalSaturday]; } for (int iSeasonCounter = 0; iSeasonCounter < TOUConfigTable.NumberOfSupportedSeasons; iSeasonCounter++) { // Get the Season that we are dealing with. CurrentSeason = TOUConfigTable.Seasons[iSeasonCounter]; NormalDays = new Int16Collection(); HolidayDays = new Int16Collection(); for (int iDayTypeCounter = 0; iDayTypeCounter < TOUConfigTable.DayTypesPerSeason; iDayTypeCounter++) { CSwitchPointCollection SPColl = new CSwitchPointCollection(); for (int iEventCounter = 0; iEventCounter < TOUConfigTable.EventsPerDayType; iEventCounter++) { // Get the Day Event TOUConfig.DayEvent DayEvent = CurrentSeason.TimeOfDayEvents[iDayTypeCounter, iEventCounter]; ushort usEvent = DayEvent.Event; if (usEvent != (ushort)TOUConfig.DayEvent.TOUEvent.NoMoreChanges) { if (IsRateChangeEvent(usEvent) == true) { // We have a valid Event, so proceed with createing a SwitchPoint int iHour = (int)DayEvent.Hour; int iMinute = (int)DayEvent.Minute; int iStartTime = (iHour * 60) + iMinute; int iEndTime = 24 * 60; iNextEventCounter = iEventCounter + 1; while (iNextEventCounter < TOUConfigTable.EventsPerDayType) { TOUConfig.DayEvent NextDayEvent = CurrentSeason.TimeOfDayEvents[iDayTypeCounter, iNextEventCounter]; if (IsRateChangeEvent(NextDayEvent.Event) == true) { iHour = (int)NextDayEvent.Hour; iMinute = (int)NextDayEvent.Minute; iEndTime = (iHour * 60) + iMinute; // We need to stop looking once we find the next rate change event. break; } iNextEventCounter++; } // Add the rate change event int iRateIndex = GetRateIndex(usEvent); // Finally figure out the Switchpoint type CSwitchPoint SchedSwitchPoint = new CSwitchPoint(iStartTime, iEndTime, iRateIndex, eSwitchPointType.RATE); SPColl.Add(SchedSwitchPoint); } else if (IsOutputOnEvent(usEvent) == true) { // We have a valid output on Event, so proceed with createing a SwitchPoint int iHour = (int)DayEvent.Hour; int iMinute = (int)DayEvent.Minute; int iStartTime = (iHour * 60) + iMinute; int iEndTime = 24 * 60; int iOutputIndex = GetOutputIndex(usEvent); // Find the OutputOff event for this rate if one exists iNextEventCounter = iEventCounter + 1; while (iNextEventCounter < TOUConfigTable.EventsPerDayType) { TOUConfig.DayEvent NextDayEvent = CurrentSeason.TimeOfDayEvents[iDayTypeCounter, iNextEventCounter]; if (IsOutputOffEvent(NextDayEvent.Event) == true) { // Check to see if the index matches if (iOutputIndex == GetOutputIndex(NextDayEvent.Event)) { iHour = (int)NextDayEvent.Hour; iMinute = (int)NextDayEvent.Minute; iEndTime = (iHour * 60) + iMinute; // We need to stop looking once we find the next rate change event. break; } } iNextEventCounter++; } // Finally figure out the Switchpoint type CSwitchPoint SchedSwitchPoint = new CSwitchPoint(iStartTime, iEndTime, iOutputIndex, eSwitchPointType.OUTPUT); SPColl.Add(SchedSwitchPoint); } // We do not need to handle the OutputOff event since they get handled by the OutputOn check } } // Since we have no way of knowing whether the the patterns for the current season are related // to the patterns in other seasons we need to add the patterns regardless of whether or not it // has already been duplicated in another season // To keep the patterns unique we need to add in an offset for the season number iPatternID = iDayTypeCounter + iSeasonCounter * TOUConfigTable.DayTypesPerSeason; CPattern SchedPattern = new CPattern(iPatternID, "Pattern " + iDayTypeCounter.ToString(CultureInfo.InvariantCulture), SPColl); NormalDays.Add((short)iPatternID); // The Day to Daytype conversions are 1's based so subract 1 if (iDayTypeCounter == CurrentSeason.TypicalHoliday) { // This Day Type is a holiday HolidayDays.Add((short)iPatternID); } TOUSchedule.Patterns.Add(SchedPattern); } // Add the season to the schedule CSeason SchedSeason = new CSeason(iSeasonCounter + 1, "Season " + (iSeasonCounter + 1).ToString(CultureInfo.InvariantCulture), NormalDays, HolidayDays); TOUSchedule.Seasons.Add(SchedSeason); } // Now deal with the Calendar part of the config TOUSchedule.TOUID = CalendarConfigTable.CalendarID; for (int iYearCounter = 0; iYearCounter < CalendarConfigTable.MaxYears; iYearCounter++) { CEventCollection EventColl = new CEventCollection(); CalendarEvent[] CalEvents = CalendarConfigTable.Years[iYearCounter].Events; int iYear = 2000 + (int)CalendarConfigTable.Years[iYearCounter].Year; // Start at Index 2, which is the first non-DST Event for (int iDayEvent = CalendarConfigTable.DSTEventsPerYear; iDayEvent < CalendarConfigTable.EventsPerYear; iDayEvent++) { eEventType eType = CalendarConfigTable.GetEventType(CalEvents[iDayEvent].Type); int iEventIndex = iDayEvent; if (eEventType.NO_EVENT != eType) { // It is a valid event DateTime dtDate = new DateTime(iYear, CalEvents[iDayEvent].Month + 1, CalEvents[iDayEvent].Day + 1); // Determine the index for the event if (eType == eEventType.SEASON) { iEventIndex = CalEvents[iDayEvent].Type - (int)CalendarEvent.CalendarEventType.SEASON1 - 1; } else if (eType == eEventType.HOLIDAY) { // Determine which Holiday day type to use // Currently the ANSI devices only support 1 holiday day type so this is always 0 iEventIndex = 0; } CEvent Event = new CEvent(dtDate, eType, iEventIndex, "Event " + iDayEvent.ToString(CultureInfo.InvariantCulture)); EventColl.Add(Event); } } CYear Year = new CYear(iYear, EventColl); TOUSchedule.Years.Add(Year); // It may be possible that some of the years are not filled in so we need to // make sure that the year is valid by checking to see if the next year is // greater than the current if (iYearCounter + 1 < CalendarConfigTable.MaxYears && (int)CalendarConfigTable.Years[iYearCounter + 1].Year + 2000 < iYear) { break; } } } catch (Exception e) { throw (e); } return(TOUSchedule); }
public static void GetSeason() { // ------------------------------------------------------------------ season = new CSeason(); }