boost::optional<openstudio::model::ModelObject> ReverseTranslator::translateSchedule(const QDomElement& element, const QDomDocument& doc, openstudio::model::Model& model) { QDomElement nameElement = element.firstChildElement("Name"); QDomElement typeElement = element.firstChildElement("Type"); OS_ASSERT(!nameElement.isNull()); std::string name = escapeName(nameElement.text()); model::ScheduleYear scheduleYear(model); scheduleYear.setName(name); OS_ASSERT(!typeElement.isNull()); std::string type = escapeName(typeElement.text()); boost::optional<model::ScheduleTypeLimits> scheduleTypeLimits = model.getModelObjectByName<model::ScheduleTypeLimits>(type); if (scheduleTypeLimits){ scheduleYear.setScheduleTypeLimits(*scheduleTypeLimits); } QDomNodeList endMonthElements = element.elementsByTagName("EndMonth"); QDomNodeList endDayElements = element.elementsByTagName("EndDay"); QDomNodeList schWeekRefElements = element.elementsByTagName("SchWeekRef"); OS_ASSERT(endMonthElements.count() == endDayElements.count()); OS_ASSERT(endMonthElements.count() == schWeekRefElements.count()); for (int i = 0; i < endMonthElements.count(); i++){ QDomElement endMonthElement = endMonthElements.at(i).toElement(); QDomElement endDayElement = endDayElements.at(i).toElement(); QDomElement schWeekRefElement = schWeekRefElements.at(i).toElement(); boost::optional<model::ScheduleWeek> scheduleWeek = model.getModelObjectByName<model::ScheduleWeek>(escapeName(schWeekRefElement.text())); if (scheduleWeek){ boost::optional<model::YearDescription> yearDescription = model.getOptionalUniqueModelObject<model::YearDescription>(); if (yearDescription){ MonthOfYear monthOfYear(endMonthElement.text().toUInt()); unsigned dayOfMonth = endDayElement.text().toUInt(); Date untilDate(monthOfYear, dayOfMonth, yearDescription->assumedYear()); scheduleYear.addScheduleWeek(untilDate, *scheduleWeek); }else{ MonthOfYear monthOfYear(endMonthElement.text().toUInt()); unsigned dayOfMonth = endDayElement.text().toUInt(); Date untilDate(monthOfYear, dayOfMonth); scheduleYear.addScheduleWeek(untilDate, *scheduleWeek); } } } return scheduleYear; }
boost::optional<openstudio::model::ModelObject> ReverseTranslator::translateSchedule(const QDomElement& element, const QDomDocument& doc, openstudio::model::Model& model) { QDomElement nameElement = element.firstChildElement("Name"); QDomElement typeElement = element.firstChildElement("Type"); std::string name; if (nameElement.isNull()){ LOG(Error, "Sch element 'Name' is empty.") } else{ name = escapeName(nameElement.text()); } if (typeElement.isNull()){ LOG(Error, "Sch element 'Type' is empty for Sch named '" << name << "'. ScheduleYear will not be created"); return boost::none; } std::string type = escapeName(typeElement.text()); QDomNodeList endMonthElements = element.elementsByTagName("EndMonth"); QDomNodeList endDayElements = element.elementsByTagName("EndDay"); QDomNodeList schWeekRefElements = element.elementsByTagName("SchWeekRef"); if (endMonthElements.count() != endDayElements.count()){ LOG(Error, "Number of 'EndMonth' elements not equal to number of 'EndDay' elements for Sch named '" << name << "'. ScheduleYear will not be created"); return boost::none; } if (endMonthElements.count() != schWeekRefElements.count()){ LOG(Error, "Number of 'EndMonth' elements not equal to number of 'SchWeekRef' elements for Sch named '" << name << "'. ScheduleYear will not be created"); return boost::none; } model::ScheduleYear scheduleYear(model); scheduleYear.setName(name); boost::optional<model::ScheduleTypeLimits> scheduleTypeLimits = model.getModelObjectByName<model::ScheduleTypeLimits>(type); if (scheduleTypeLimits){ scheduleYear.setScheduleTypeLimits(*scheduleTypeLimits); } for (int i = 0; i < endMonthElements.count(); i++){ QDomElement endMonthElement = endMonthElements.at(i).toElement(); QDomElement endDayElement = endDayElements.at(i).toElement(); QDomElement schWeekRefElement = schWeekRefElements.at(i).toElement(); boost::optional<model::ScheduleWeek> scheduleWeek = model.getModelObjectByName<model::ScheduleWeek>(escapeName(schWeekRefElement.text())); if (scheduleWeek){ boost::optional<model::YearDescription> yearDescription = model.getOptionalUniqueModelObject<model::YearDescription>(); if (yearDescription){ MonthOfYear monthOfYear(endMonthElement.text().toUInt()); unsigned dayOfMonth = endDayElement.text().toUInt(); Date untilDate(monthOfYear, dayOfMonth, yearDescription->assumedYear()); scheduleYear.addScheduleWeek(untilDate, *scheduleWeek); }else{ MonthOfYear monthOfYear(endMonthElement.text().toUInt()); unsigned dayOfMonth = endDayElement.text().toUInt(); Date untilDate(monthOfYear, dayOfMonth); scheduleYear.addScheduleWeek(untilDate, *scheduleWeek); } } } return scheduleYear; }
boost::optional<IdfObject> ForwardTranslator::translateScheduleRuleset( ScheduleRuleset & modelObject ) { IdfObject scheduleYear( openstudio::IddObjectType::Schedule_Year ); std::string scheduleYearName = modelObject.name().get(); scheduleYear.setName(scheduleYearName); boost::optional<ScheduleTypeLimits> scheduleTypeLimits = modelObject.scheduleTypeLimits(); if (scheduleTypeLimits){ boost::optional<IdfObject> idfObject = translateAndMapModelObject(*scheduleTypeLimits); if (idfObject){ scheduleYear.setString(Schedule_YearFields::ScheduleTypeLimitsName, idfObject->name().get()); } } try { ScheduleDay defaultDaySchedule = modelObject.defaultDaySchedule(); ScheduleDay summerDesignDaySchedule = modelObject.summerDesignDaySchedule(); ScheduleDay winterDesignDaySchedule = modelObject.winterDesignDaySchedule(); // initialize day of week schedules ScheduleDay sundaySchedule = defaultDaySchedule; ScheduleDay mondaySchedule = defaultDaySchedule; ScheduleDay tuesdaySchedule = defaultDaySchedule; ScheduleDay wednesdaySchedule = defaultDaySchedule; ScheduleDay thursdaySchedule = defaultDaySchedule; ScheduleDay fridaySchedule = defaultDaySchedule; ScheduleDay saturdaySchedule = defaultDaySchedule; // these are not yet exposed ScheduleDay holidayDaySchedule = defaultDaySchedule; ScheduleDay customDay1Schedule = defaultDaySchedule; ScheduleDay customDay2Schedule = defaultDaySchedule; // loop over entire year model::YearDescription yd = modelObject.model().getUniqueModelObject<model::YearDescription>(); openstudio::Date jan1 = yd.makeDate(MonthOfYear::Jan, 1); openstudio::Date dec31 = yd.makeDate(MonthOfYear::Dec, 31); // this is the current date we are at in the year openstudio::Date date = jan1; // this is the week schedule for the week ending on the last saturday before the current date boost::optional<WeekScheduleStruct> weekSchedule; // this is the week schedule for the week before weekSchedule boost::optional<WeekScheduleStruct> lastWeekSchedule; // this is the saturday on which lastWeekSchedule ends openstudio::Date lastDate; // iterate over the schedule for each day of the year std::vector<ScheduleDay> daySchedules = modelObject.getDaySchedules(jan1, dec31); for (ScheduleDay& daySchedule : daySchedules){ // translate the day schedule translateAndMapModelObject(daySchedule); // set day of week schedule switch(date.dayOfWeek().value()){ case DayOfWeek::Sunday: sundaySchedule = daySchedule; break; case DayOfWeek::Monday: mondaySchedule = daySchedule; break; case DayOfWeek::Tuesday: tuesdaySchedule = daySchedule; break; case DayOfWeek::Wednesday: wednesdaySchedule = daySchedule; break; case DayOfWeek::Thursday: thursdaySchedule = daySchedule; break; case DayOfWeek::Friday: fridaySchedule = daySchedule; break; case DayOfWeek::Saturday: saturdaySchedule = daySchedule; break; default: OS_ASSERT(false); } // update week schedules each saturday if((date.dayOfWeek().value() == DayOfWeek::Saturday)){ // set last week schedule before we overwrite week schedule lastDate = date - Time(7); lastWeekSchedule = weekSchedule; // set the week schedule weekSchedule = WeekScheduleStruct(); weekSchedule->sundaySchedule = sundaySchedule.name().get(); weekSchedule->mondaySchedule = mondaySchedule.name().get(); weekSchedule->tuesdaySchedule = tuesdaySchedule.name().get(); weekSchedule->wednesdaySchedule = wednesdaySchedule.name().get(); weekSchedule->thursdaySchedule = thursdaySchedule.name().get(); weekSchedule->fridaySchedule = fridaySchedule.name().get(); weekSchedule->saturdaySchedule = saturdaySchedule.name().get(); weekSchedule->holidayDaySchedule = holidayDaySchedule.name().get(); weekSchedule->summerDesignDaySchedule = summerDesignDaySchedule.name().get(); weekSchedule->winterDesignDaySchedule = winterDesignDaySchedule.name().get(); weekSchedule->customDay1Schedule = customDay1Schedule.name().get(); weekSchedule->customDay2Schedule = customDay2Schedule.name().get(); // check if this schedule is equal to last week schedule if (weekSchedule && lastWeekSchedule && ( !(weekSchedule.get() == lastWeekSchedule.get()) )){ // if not write out last week schedule // get last extensible group, if any, to find start date otherwise use jan1 openstudio::Date startDate; std::vector<IdfExtensibleGroup> extensibleGroups = scheduleYear.extensibleGroups(); if (extensibleGroups.empty()){ startDate = jan1; }else{ // day after last end date boost::optional<int> startMonth = extensibleGroups.back().getInt(3,true); OS_ASSERT(startMonth); boost::optional<int> startDay = extensibleGroups.back().getInt(4,true); OS_ASSERT(startDay); startDate = yd.makeDate(*startMonth, *startDay) + Time(1); } OS_ASSERT(startDate <= lastDate); // Name the schedule week lastWeekSchedule->setName(scheduleYearName, startDate, lastDate); // add the values std::vector<std::string> values; values.push_back(lastWeekSchedule->name); values.push_back(boost::lexical_cast<std::string>(startDate.monthOfYear().value())); values.push_back(boost::lexical_cast<std::string>(startDate.dayOfMonth())); values.push_back(boost::lexical_cast<std::string>(lastDate.monthOfYear().value())); values.push_back(boost::lexical_cast<std::string>(lastDate.dayOfMonth())); IdfExtensibleGroup test = scheduleYear.pushExtensibleGroup(values); OS_ASSERT(!test.empty()); // Write the schedule m_idfObjects.push_back(lastWeekSchedule->toIdfObject()); } } // if last day of year update and write out current week schedule if (date == dec31){ // we may now think of date as being the next saturday on or after 12/31 // set last week schedule before we overwrite week schedule lastDate = date - Time(1); while (lastDate.dayOfWeek().value() != DayOfWeek::Saturday){ lastDate = lastDate - Time(1); lastWeekSchedule = weekSchedule; } // set the week schedule, some of these dates may extend past 12/31 weekSchedule = WeekScheduleStruct(); weekSchedule->sundaySchedule = sundaySchedule.name().get(); weekSchedule->mondaySchedule = mondaySchedule.name().get(); weekSchedule->tuesdaySchedule = tuesdaySchedule.name().get(); weekSchedule->wednesdaySchedule = wednesdaySchedule.name().get(); weekSchedule->thursdaySchedule = thursdaySchedule.name().get(); weekSchedule->fridaySchedule = fridaySchedule.name().get(); weekSchedule->saturdaySchedule = saturdaySchedule.name().get(); weekSchedule->holidayDaySchedule = holidayDaySchedule.name().get(); weekSchedule->summerDesignDaySchedule = summerDesignDaySchedule.name().get(); weekSchedule->winterDesignDaySchedule = winterDesignDaySchedule.name().get(); weekSchedule->customDay1Schedule = customDay1Schedule.name().get(); weekSchedule->customDay2Schedule = customDay2Schedule.name().get(); // check if this schedule is equal to last week schedule if (weekSchedule && lastWeekSchedule && ( !(weekSchedule.get() == lastWeekSchedule.get()) )){ // if not write out last week schedule // get last extensible group, if any, to find start date otherwise use jan1 openstudio::Date startDate; std::vector<IdfExtensibleGroup> extensibleGroups = scheduleYear.extensibleGroups(); if (extensibleGroups.empty()){ startDate = jan1; }else{ // day after last end date boost::optional<int> startMonth = extensibleGroups.back().getInt(3,true); OS_ASSERT(startMonth); boost::optional<int> startDay = extensibleGroups.back().getInt(4,true); OS_ASSERT(startDay); startDate = yd.makeDate(*startMonth, *startDay) + Time(1); } OS_ASSERT(startDate <= lastDate); // Name the schedule week lastWeekSchedule->setName(scheduleYearName, startDate, lastDate); // add the values std::vector<std::string> values; values.push_back(lastWeekSchedule->name); values.push_back(boost::lexical_cast<std::string>(startDate.monthOfYear().value())); values.push_back(boost::lexical_cast<std::string>(startDate.dayOfMonth())); values.push_back(boost::lexical_cast<std::string>(lastDate.monthOfYear().value())); values.push_back(boost::lexical_cast<std::string>(lastDate.dayOfMonth())); IdfExtensibleGroup test = scheduleYear.pushExtensibleGroup(values); OS_ASSERT(!test.empty()); // Write the schedule m_idfObjects.push_back(lastWeekSchedule->toIdfObject()); } // write out the last week schedule // get last extensible group, if any, to find start date otherwise use jan1 openstudio::Date startDate; std::vector<IdfExtensibleGroup> extensibleGroups = scheduleYear.extensibleGroups(); if (extensibleGroups.empty()){ startDate = jan1; }else{ // day after last end date boost::optional<int> startMonth = extensibleGroups.back().getInt(3,true); OS_ASSERT(startMonth); boost::optional<int> startDay = extensibleGroups.back().getInt(4,true); OS_ASSERT(startDay); startDate = yd.makeDate(*startMonth, *startDay) + Time(1); } OS_ASSERT(startDate <= date); // Name the schedule week weekSchedule->setName(scheduleYearName, startDate, date); // add the values std::vector<std::string> values; values.push_back(weekSchedule->name); values.push_back(boost::lexical_cast<std::string>(startDate.monthOfYear().value())); values.push_back(boost::lexical_cast<std::string>(startDate.dayOfMonth())); values.push_back(boost::lexical_cast<std::string>(date.monthOfYear().value())); values.push_back(boost::lexical_cast<std::string>(date.dayOfMonth())); IdfExtensibleGroup test = scheduleYear.pushExtensibleGroup(values); OS_ASSERT(!test.empty()); // Write the schedule m_idfObjects.push_back(weekSchedule->toIdfObject()); } // increment date date += Time(1); } } catch (std::exception& e) { LOG(Error,"Unable to translate " << modelObject.briefDescription() << " to EnergyPlus IDF, because " << e.what() << "."); return boost::none; } m_idfObjects.push_back(scheduleYear); m_map.insert(std::make_pair(modelObject.handle(), scheduleYear)); // translate day schedules ScheduleDay defaultDaySchedule = modelObject.defaultDaySchedule(); ScheduleDay summerDesignDaySchedule = modelObject.summerDesignDaySchedule(); ScheduleDay winterDesignDaySchedule = modelObject.winterDesignDaySchedule(); translateAndMapModelObject(defaultDaySchedule); translateAndMapModelObject(summerDesignDaySchedule); translateAndMapModelObject(winterDesignDaySchedule); // translate schedule rules, these are returned in order for (ScheduleRule scheduleRule : modelObject.scheduleRules()){ ScheduleDay daySchedule = scheduleRule.daySchedule(); translateAndMapModelObject(daySchedule); } return scheduleYear; }