Skip to content

Instantly share code, notes, and snippets.

@jmarrec
Last active June 7, 2024 07:33
Show Gist options
  • Save jmarrec/f7c03511f70bbe1d1f62c8b929496078 to your computer and use it in GitHub Desktop.
Save jmarrec/f7c03511f70bbe1d1f62c8b929496078 to your computer and use it in GitHub Desktop.
ScheduleRuleset Demonstration
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "15768243",
"metadata": {},
"source": [
"# ScheduleRuleset\n",
"\n",
"`ScheduleRuleset` is an OpenStudio specific object provided for convenience. \n",
"\n",
"It has:\n",
"\n",
"* A default `ScheduleDay`\n",
"* Potential special days `ScheduleDay`s (Summer / Winter Design Day, Holiday, CustomDay1 & 2)\n",
"* 0 to many `ScheduleRule`s\n",
"\n",
"A `ScheduleRule` has a `ScheduleDay`, and fields means to express when the rule applies:\n",
"* Apply Sunday, Monday...Saturday\n",
"* A start date & end date\n",
"\n",
"`ScheduleRuleset` has the logic needed to translate to EnergyPlus IDF objects, because it knows when rules are meant to apply (and if no rules apply, the defaultDay is used). It will translate to an E+ `Schedule:Year` object (alongside as many `Schedule:Week:Daily` objects needed to represent it and `Schedule:Day:Interval`).\n",
"\n",
"## DefaultScheduleSet\n",
"The `DefaultScheduleSet` is an abstraction provided for convenience, and with a concept that is dear to OpenStudio which is **Inheritance** (same as for SpaceType and co, cf https://nrel.github.io/OpenStudio-user-documentation/reference/model_objects/). Basically you can use a DefaultScheduleSet and apply to your Building, BuildingStory, SpaceType or Space. And that would allow you to not specifically assign a schedule to some of your loads, such as Lights, as it would use the one from the DefaultScheduleSet.\n",
"\n",
"**Note:** Tthe \"Hours Of Operation\" one is not being used anywhere though.\n",
"\n",
"\n",
"## More information/demo\n",
"\n",
"You can find lots of example of usage for pretty much all OpenStudio ModelObjects in the OpenStudio-resources repository (that's our integration tests which serve as an API demonstration as well). While it has historically been ruby only, I recently ported all examples to python as well. Go check out https://github.com/NREL/OpenStudio-resources/tree/develop/model/simulationtests, and for eg [schedule_ruleset_2012_LeapYear.py](https://github.com/NREL/OpenStudio-resources/blob/bd4f450564f6f0d7dcc052dcaba002bf23abb8d5/model/simulationtests/schedule_ruleset_2012_LeapYear.py#L32-L74)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "dca8d63a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OS:Schedule:Ruleset,\n",
" {d71791cf-65ed-4310-9e78-b506c3789ada}, !- Handle\n",
" Lighting ScheduleRuleset, !- Name\n",
" , !- Schedule Type Limits Name\n",
" {1c4524c3-e0b9-4418-b240-4c6517ff709d}, !- Default Day Schedule Name\n",
" {585902bd-4468-486b-99f4-dd7908ddd4a3}, !- Summer Design Day Schedule Name\n",
" {d3a05b83-01a6-4f79-a53b-ab2fd5a91924}; !- Winter Design Day Schedule Name\n",
"\n",
"\n",
"OS:Schedule:Day,\n",
" {1c4524c3-e0b9-4418-b240-4c6517ff709d}, !- Handle\n",
" Lighting DefaultDay, !- Name\n",
" , !- Schedule Type Limits Name\n",
" , !- Interpolate to Timestep\n",
" 8, !- Hour 1\n",
" 0, !- Minute 1\n",
" 0.1, !- Value Until Time 1\n",
" 20, !- Hour 2\n",
" 0, !- Minute 2\n",
" 0.75, !- Value Until Time 2\n",
" 24, !- Hour 3\n",
" 0, !- Minute 3\n",
" 0.1; !- Value Until Time 3\n",
"\n",
"\n",
"OS:Schedule:Day,\n",
" {585902bd-4468-486b-99f4-dd7908ddd4a3}, !- Handle\n",
" Lighting Summer DesignDay, !- Name\n",
" , !- Schedule Type Limits Name\n",
" , !- Interpolate to Timestep\n",
" 24, !- Hour 1\n",
" 0, !- Minute 1\n",
" 1; !- Value Until Time 1\n",
"\n",
"\n",
"OS:Schedule:Day,\n",
" {d3a05b83-01a6-4f79-a53b-ab2fd5a91924}, !- Handle\n",
" Lighting Winter DesignDay, !- Name\n",
" , !- Schedule Type Limits Name\n",
" , !- Interpolate to Timestep\n",
" 24, !- Hour 1\n",
" 0, !- Minute 1\n",
" 0; !- Value Until Time 1\n",
"\n",
"\n",
"OS:Schedule:Rule,\n",
" {5e1e489c-7098-4297-b9f3-772241b543ab}, !- Handle\n",
" Lighting Weekend Rule, !- Name\n",
" {d71791cf-65ed-4310-9e78-b506c3789ada}, !- Schedule Ruleset Name\n",
" 0, !- Rule Order\n",
" {91cae5f3-546a-4c22-a758-8b705d11e8ba}, !- Day Schedule Name\n",
" Yes, !- Apply Sunday\n",
" No, !- Apply Monday\n",
" No, !- Apply Tuesday\n",
" No, !- Apply Wednesday\n",
" No, !- Apply Thursday\n",
" No, !- Apply Friday\n",
" Yes, !- Apply Saturday\n",
" DateRange, !- Date Specification Type\n",
" 1, !- Start Month\n",
" 1, !- Start Day\n",
" 12, !- End Month\n",
" 31; !- End Day\n",
"\n",
"\n"
]
}
],
"source": [
"import openstudio\n",
"\n",
"model = openstudio.model.Model()\n",
"\n",
"# Create Lighting ScheduleRuleset\n",
"lightingSchedule = openstudio.model.ScheduleRuleset(model)\n",
"lightingSchedule.setName(\"Lighting ScheduleRuleset\")\n",
"lightingSchedule.defaultDaySchedule().setName(\"Lighting DefaultDay\")\n",
"lightingSchedule.defaultDaySchedule().addValue(openstudio.Time(0, 8, 0, 0), 0.1)\n",
"lightingSchedule.defaultDaySchedule().addValue(openstudio.Time(0, 20, 0, 0), 0.75)\n",
"lightingSchedule.defaultDaySchedule().addValue(openstudio.Time(0, 24, 0, 0), 0.1)\n",
"\n",
"# Design days\n",
"temp_ = openstudio.model.ScheduleDay(model)\n",
"lightingSchedule.setSummerDesignDaySchedule(temp_) # This clones it\n",
"summer_design_day = lightingSchedule.summerDesignDaySchedule()\n",
"summer_design_day.setName(\"Lighting Summer DesignDay\")\n",
"summer_design_day.addValue(openstudio.Time(0, 24, 0, 0), 1.0)\n",
"\n",
"lightingSchedule.setWinterDesignDaySchedule(temp_) # This clones it\n",
"winter_design_day = lightingSchedule.winterDesignDaySchedule()\n",
"winter_design_day.setName(\"Lighting Winter DesignDay\")\n",
"winter_design_day.addValue(openstudio.Time(0, 24, 0, 0), 0.0)\n",
"\n",
"temp_.remove()\n",
"\n",
"# Add a weekend rule\n",
"weekendRule = openstudio.model.ScheduleRule(lightingSchedule)\n",
"weekendRule.setName(\"Lighting Weekend Rule\")\n",
"weekendRule.daySchedule().setName(\"Lighting Weekend Day\")\n",
"weekendRule.setApplySunday(True)\n",
"weekendRule.setApplyMonday(False)\n",
"weekendRule.setApplyTuesday(False)\n",
"weekendRule.setApplyWednesday(False)\n",
"weekendRule.setApplyThursday(False)\n",
"weekendRule.setApplyFriday(False)\n",
"weekendRule.setApplySaturday(True)\n",
"weekendRule.setStartDate(openstudio.Date(openstudio.MonthOfYear(\"Jan\"), 1))\n",
"weekendRule.setEndDate(openstudio.Date(openstudio.MonthOfYear(\"Dec\"), 31))\n",
"weekendRule.daySchedule().addValue(openstudio.Time(0, 24, 0, 0), 0)\n",
"\n",
"print(lightingSchedule)\n",
"print(lightingSchedule.defaultDaySchedule())\n",
"print(lightingSchedule.summerDesignDaySchedule())\n",
"print(lightingSchedule.winterDesignDaySchedule())\n",
"print(weekendRule)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "59dea335",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OS:Lights,\n",
" {458c8bf0-4142-46e9-8096-53450661de8f}, !- Handle\n",
" Lights 1, !- Name\n",
" {94cdf04f-ba35-40e3-8553-19e0d13daf09}, !- Lights Definition Name\n",
" {313017c3-8b39-409e-86fc-520d32d01688}, !- Space or SpaceType Name\n",
" , !- Schedule Name\n",
" 1, !- Fraction Replaceable\n",
" , !- Multiplier\n",
" General; !- End-Use Subcategory\n",
"\n",
"\n"
]
}
],
"source": [
"# Create a Lights object and place it inside a Space\n",
"# it has to be part of a Space or spaceType for inheritance to look upward for the schedule\n",
"# But if not part of a Space or SpaceType, it would not be translated to E+ anyways\n",
"ld = openstudio.model.LightsDefinition(model)\n",
"lights = openstudio.model.Lights(ld)\n",
"\n",
"space = openstudio.model.Space(model) # This space should have geometry in reality, but this is a demo\n",
"zone = openstudio.model.ThermalZone(model)\n",
"space.setThermalZone(zone)\n",
"lights.setSpace(space)\n",
"\n",
"# All of these are equivalent, and we can check there's no schedule\n",
"assert lights.schedule().empty()\n",
"assert not lights.schedule().is_initialized()\n",
"assert not bool(lights.schedule())\n",
"\n",
"print(lights)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "41349dc4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OS:Lights,\n",
" {458c8bf0-4142-46e9-8096-53450661de8f}, !- Handle\n",
" Lights 1, !- Name\n",
" {94cdf04f-ba35-40e3-8553-19e0d13daf09}, !- Lights Definition Name\n",
" {313017c3-8b39-409e-86fc-520d32d01688}, !- Space or SpaceType Name\n",
" , !- Schedule Name\n",
" 1, !- Fraction Replaceable\n",
" , !- Multiplier\n",
" General; !- End-Use Subcategory\n",
"\n",
"\n",
"lights.schedule().get().nameString()='Lighting ScheduleRuleset'\n"
]
}
],
"source": [
"# Assign a DefaultScheduleSet to the building\n",
"building = model.getBuilding()\n",
"default_sch_set = openstudio.model.DefaultScheduleSet(model)\n",
"building.setDefaultScheduleSet(default_sch_set)\n",
"# Set a Lighting Schedule\n",
"default_sch_set.setLightingSchedule(lightingSchedule)\n",
"\n",
"# And TADAAAAAAAAA! We can grab the schedule, even though there's none directly assigned\n",
"assert lights.schedule().is_initialized()\n",
"print(lights)\n",
"print(f\"lights.schedule().get().nameString()='{lights.schedule().get().nameString()}'\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "cd6582ce",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[openstudio.model.YearDescription] <1> 'UseWeatherFile' is selected in YearDescription, but there are no weather file set for the model.\n",
"[openstudio.model.YearDescription] <1> 'UseWeatherFile' is selected in YearDescription, but there are no weather file set for the model.\n",
"[openstudio.model.YearDescription] <1> 'UseWeatherFile' is selected in YearDescription, but there are no weather file set for the model.\n",
"[openstudio.model.YearDescription] <1> 'UseWeatherFile' is selected in YearDescription, but there are no weather file set for the model.\n",
"[openstudio.model.YearDescription] <1> 'UseWeatherFile' is selected in YearDescription, but there are no weather file set for the model.\n",
"[openstudio.model.YearDescription] <1> 'UseWeatherFile' is selected in YearDescription, but there are no weather file set for the model.\n",
"[openstudio.model.YearDescription] <1> 'UseWeatherFile' is selected in YearDescription, but there are no weather file set for the model.\n"
]
}
],
"source": [
"ft = openstudio.energyplus.ForwardTranslator()\n",
"ft.setExcludeLCCObjects(True)\n",
"w = ft.translateModel(model)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "0f5164dc",
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Schedule:Constant,\n",
" Always On Continuous, !- Name\n",
" Fractional 1, !- Schedule Type Limits Name\n",
" 1; !- Hourly Value\n",
"\n",
"\n",
"Schedule:Constant,\n",
" Always Off Discrete, !- Name\n",
" OnOff 1, !- Schedule Type Limits Name\n",
" 0; !- Hourly Value\n",
"\n",
"\n",
"Schedule:Constant,\n",
" Always On Discrete, !- Name\n",
" OnOff, !- Schedule Type Limits Name\n",
" 1; !- Hourly Value\n",
"\n",
"\n",
"Schedule:Day:Interval,\n",
" Lighting Winter DesignDay, !- Name\n",
" Fractional, !- Schedule Type Limits Name\n",
" No, !- Interpolate to Timestep\n",
" 24:00, !- Time 1 {hh:mm}\n",
" 0; !- Value Until Time 1\n",
"\n",
"\n",
"Schedule:Day:Interval,\n",
" Lighting Summer DesignDay, !- Name\n",
" Fractional, !- Schedule Type Limits Name\n",
" No, !- Interpolate to Timestep\n",
" 24:00, !- Time 1 {hh:mm}\n",
" 1; !- Value Until Time 1\n",
"\n",
"\n",
"Schedule:Year,\n",
" Lighting ScheduleRuleset, !- Name\n",
" Fractional, !- Schedule Type Limits Name\n",
" Lighting ScheduleRuleset Week Rule - Jan1-Jan3, !- Schedule:Week Name 1\n",
" 1, !- Start Month 1\n",
" 1, !- Start Day 1\n",
" 1, !- End Month 1\n",
" 3, !- End Day 1\n",
" Lighting ScheduleRuleset Week Rule - Jan4-Dec31, !- Schedule:Week Name 2\n",
" 1, !- Start Month 2\n",
" 4, !- Start Day 2\n",
" 12, !- End Month 2\n",
" 31; !- End Day 2\n",
"\n",
"\n",
"Schedule:Week:Daily,\n",
" Lighting ScheduleRuleset Week Rule - Jan4-Dec31, !- Name\n",
" Lighting Weekend Day, !- Sunday Schedule:Day Name\n",
" Lighting DefaultDay, !- Monday Schedule:Day Name\n",
" Lighting DefaultDay, !- Tuesday Schedule:Day Name\n",
" Lighting DefaultDay, !- Wednesday Schedule:Day Name\n",
" Lighting DefaultDay, !- Thursday Schedule:Day Name\n",
" Lighting DefaultDay, !- Friday Schedule:Day Name\n",
" Lighting Weekend Day, !- Saturday Schedule:Day Name\n",
" Lighting DefaultDay, !- Holiday Schedule:Day Name\n",
" Lighting Summer DesignDay, !- SummerDesignDay Schedule:Day Name\n",
" Lighting Winter DesignDay, !- WinterDesignDay Schedule:Day Name\n",
" Lighting DefaultDay, !- CustomDay1 Schedule:Day Name\n",
" Lighting DefaultDay; !- CustomDay2 Schedule:Day Name\n",
"\n",
"\n",
"Schedule:Week:Daily,\n",
" Lighting ScheduleRuleset Week Rule - Jan1-Jan3, !- Name\n",
" Lighting DefaultDay, !- Sunday Schedule:Day Name\n",
" Lighting DefaultDay, !- Monday Schedule:Day Name\n",
" Lighting DefaultDay, !- Tuesday Schedule:Day Name\n",
" Lighting DefaultDay, !- Wednesday Schedule:Day Name\n",
" Lighting DefaultDay, !- Thursday Schedule:Day Name\n",
" Lighting DefaultDay, !- Friday Schedule:Day Name\n",
" Lighting Weekend Day, !- Saturday Schedule:Day Name\n",
" Lighting DefaultDay, !- Holiday Schedule:Day Name\n",
" Lighting Summer DesignDay, !- SummerDesignDay Schedule:Day Name\n",
" Lighting Winter DesignDay, !- WinterDesignDay Schedule:Day Name\n",
" Lighting DefaultDay, !- CustomDay1 Schedule:Day Name\n",
" Lighting DefaultDay; !- CustomDay2 Schedule:Day Name\n",
"\n",
"\n",
"Schedule:Day:Interval,\n",
" Lighting Weekend Day, !- Name\n",
" Fractional, !- Schedule Type Limits Name\n",
" No, !- Interpolate to Timestep\n",
" 24:00, !- Time 1 {hh:mm}\n",
" 0; !- Value Until Time 1\n",
"\n",
"\n",
"Schedule:Day:Interval,\n",
" Lighting DefaultDay, !- Name\n",
" Fractional, !- Schedule Type Limits Name\n",
" No, !- Interpolate to Timestep\n",
" 08:00, !- Time 1 {hh:mm}\n",
" 0.1, !- Value Until Time 1\n",
" 20:00, !- Time 2 {hh:mm}\n",
" 0.75, !- Value Until Time 2\n",
" 24:00, !- Time 3 {hh:mm}\n",
" 0.1; !- Value Until Time 3\n",
"\n",
"\n"
]
},
{
"data": {
"text/plain": [
"[None, None, None, None, None, None, None, None, None, None]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[print(x) for x in w.objects() if x.iddObject().name().startswith('Schedule:')]"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment