TEST_F(EnergyPlusFixture,ReverseTranslator_ScheduleDayInterval) { // ScheduleDayInterval time entries contain the string 'Until: ' that must be // stripped off before constructing a Time object. We are also more lenient in // making this optional. Workspace ws(StrictnessLevel::Draft,IddFileType(IddFileType::EnergyPlus)); OptionalWorkspaceObject owo = ws.addObject(IdfObject(IddObjectType::Schedule_Day_Interval)); ASSERT_TRUE(owo); WorkspaceObject object = *owo; object.setName("Heating Setpoint Design Day"); StringVector groupValues(2u); groupValues[0] = std::string("Until: 12:00"); groupValues[1] = std::string("21.1"); object.pushExtensibleGroup(groupValues); groupValues[0] = std::string("24:00"); groupValues[1] = std::string("20.5"); object.pushExtensibleGroup(groupValues); ReverseTranslator translator; Model model = translator.translateWorkspace(ws); EXPECT_TRUE(translator.errors().empty()); // There are warnings related to ws being a partial model. EXPECT_TRUE(translator.untranslatedIdfObjects().empty()); ScheduleDayVector daySchedules = model.getModelObjects<ScheduleDay>(); ASSERT_EQ(1u,daySchedules.size()); ScheduleDay daySchedule = daySchedules[0]; DoubleVector values = daySchedule.values(); ASSERT_EQ(2u,values.size()); EXPECT_DOUBLE_EQ(21.1,values[0]); EXPECT_DOUBLE_EQ(20.5,values[1]); TimeVector times = daySchedule.times(); ASSERT_EQ(2u,times.size()); EXPECT_EQ(Time(0,12,0),times[0]); EXPECT_EQ(Time(0,24,0),times[1]); }
TEST_F(ModelFixture, ScheduleRuleset_DaySchedule) { Model model; ScheduleRuleset schedule(model); ScheduleDay daySchedule = schedule.defaultDaySchedule(); EXPECT_TRUE(daySchedule.setName("My Day Schedule")); ASSERT_TRUE(daySchedule.name()); EXPECT_EQ("My Day Schedule", daySchedule.name().get()); }
boost::optional<IdfObject> ForwardTranslator::translateScheduleDay( ScheduleDay & modelObject ) { IdfObject scheduleDay = createRegisterAndNameIdfObject(openstudio::IddObjectType::Schedule_Day_Interval, modelObject); boost::optional<ScheduleTypeLimits> scheduleTypeLimits = modelObject.scheduleTypeLimits(); if (scheduleTypeLimits){ boost::optional<IdfObject> idfScheduleTypeLimits = translateAndMapModelObject(*scheduleTypeLimits); if (idfScheduleTypeLimits){ scheduleDay.setString(Schedule_Day_IntervalFields::ScheduleTypeLimitsName, idfScheduleTypeLimits->name().get()); } } if (modelObject.interpolatetoTimestep()){ scheduleDay.setString(Schedule_Day_IntervalFields::InterpolatetoTimestep, "Yes"); }else{ scheduleDay.setString(Schedule_Day_IntervalFields::InterpolatetoTimestep, "No"); } std::vector<double> values = modelObject.values(); std::vector<openstudio::Time> times = modelObject.times(); unsigned N = values.size(); OS_ASSERT(N == times.size()); scheduleDay.clearExtensibleGroups(); for (unsigned i = 0; i < N; ++i){ IdfExtensibleGroup group = scheduleDay.pushExtensibleGroup(); std::string hourPrefix; std::string minutePrefix; int hours = times[i].hours() + 24*times[i].days(); if (hours < 10){ hourPrefix = "0"; } int minutes = times[i].minutes() + floor((times[i].seconds()/60.0) + 0.5); if (minutes < 10){ minutePrefix = "0"; } std::stringstream ss; ss << hourPrefix << hours << ":" << minutePrefix << minutes; group.setString(Schedule_Day_IntervalExtensibleFields::Time, ss.str()); group.setDouble(Schedule_Day_IntervalExtensibleFields::ValueUntilTime, values[i]); } return scheduleDay; }
TEST_F(ModelFixture, ScheduleRuleset_InsertObjects) { Model model; ScheduleTypeLimits typeLimits(model); ScheduleRuleset schedule(model); schedule.setName("Always_On"); EXPECT_EQ("Always_On", schedule.name().get()); schedule.setScheduleTypeLimits(typeLimits); ScheduleRule rule(schedule); rule.setName("Always_On Rule 1"); EXPECT_EQ("Always_On Rule 1", rule.name().get()); ScheduleDay daySchedule = rule.daySchedule(); daySchedule.setName("Always_On Rule 1 Day Schedule"); EXPECT_EQ("Always_On Rule 1 Day Schedule", daySchedule.name().get()); daySchedule.setScheduleTypeLimits(typeLimits); // clone does not preserve handles Workspace workspace1 = model.clone(); Workspace workspace2 = model.clone(); IdfObjectVector idfObjects1; for (const WorkspaceObject& object : workspace1.objects()){ // this handle should not exist in the original model EXPECT_FALSE(model.getObject(object.handle())); idfObjects1.push_back(object.idfObject()); } IdfObjectVector idfObjects2; for (const WorkspaceObject& object : workspace2.objects()){ // this handle should not exist in the original model EXPECT_FALSE(model.getObject(object.handle())); idfObjects2.push_back(object.idfObject()); } std::vector<WorkspaceObject> insertedObjects = model.insertObjects(idfObjects1); // DLM: I do not know what the correct operation is here, should the number of objects in // the model stay constant? // the insert should not fail EXPECT_FALSE(insertedObjects.empty()); std::vector<WorkspaceObject> addedObjects = model.addObjects(idfObjects2); // the add should not fail EXPECT_FALSE(addedObjects.empty()); }
TEST_F(ModelFixture,People_Schedule_Quantities) { Model model; PeopleDefinition definition(model); definition.setNumberofPeople(Quantity(100.0,createSIPeople())); People people(definition); ScheduleRuleset activityLevelSchedule(model); EXPECT_TRUE(checkOrAssignScheduleTypeLimits("People","Activity Level",activityLevelSchedule)); ScheduleDay defaultSchedule = activityLevelSchedule.defaultDaySchedule(); defaultSchedule.addValue(Time(0,24,0,0),Quantity(150.0,createSIPower()/createSIPeople())); EXPECT_TRUE(people.setActivityLevelSchedule(activityLevelSchedule)); OSQuantityVector ipValues = defaultSchedule.getValues(true); EXPECT_EQ("W/person",ipValues.units().prettyString()); EXPECT_DOUBLE_EQ(150.0,ipValues.values()[0]); }
ScheduleRule::ScheduleRule(ScheduleRuleset& scheduleRuleset, const ScheduleDay& daySchedule) : ParentObject(ScheduleRule::iddObjectType(), scheduleRuleset.model()) { OS_ASSERT(getImpl<detail::ScheduleRule_Impl>()); bool result = setPointer(OS_Schedule_RuleFields::ScheduleRulesetName, scheduleRuleset.handle()); OS_ASSERT(result); ModelObject clone = daySchedule.clone(scheduleRuleset.model()); result = setPointer(OS_Schedule_RuleFields::DayScheduleName, clone.handle()); OS_ASSERT(result); if (OptionalScheduleTypeLimits limits = scheduleRuleset.scheduleTypeLimits()) { clone.cast<ScheduleDay>().setScheduleTypeLimits(*limits); } this->setRuleIndex(std::numeric_limits<int>::max()); result = scheduleRuleset.setScheduleRuleIndex(*this, 0); OS_ASSERT(result); }
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; }
bool ScheduleWeek_Impl::setCustomDay2Schedule(const ScheduleDay& schedule) { return setPointer(OS_Schedule_WeekFields::CustomDay2Schedule_DayName, schedule.handle()); }
bool ScheduleWeek_Impl::setWinterDesignDaySchedule(const ScheduleDay& schedule) { return setPointer(OS_Schedule_WeekFields::WinterDesignDaySchedule_DayName, schedule.handle()); }