Schedule evaluation¶
idfkit.schedules evaluates EnergyPlus schedules without running a simulation. Useful for visualisation, debugging, building parametric inputs, and any workflow where you need the value of a Schedule:* at a given timestamp.
When to use¶
- You want to see what a
Schedule:Compactresolves to at hour 14:00 on a Tuesday. - You're plotting an annual schedule to confirm it matches expectations.
- You're synthesising schedules from a
numpyarray or a pandasSeries. - You're auditing a model to find every schedule it uses.
Quick start¶
from datetime import datetime
from idfkit import load_idf
from idfkit.schedules import evaluate, values, to_series
doc = load_idf("building.idf")
sched = doc["Schedule:Compact"]["Office Occupancy"]
# Single timestamp
v = evaluate(sched, datetime(2024, 1, 8, 10, 0))
print(v) # 1.0 (fully occupied at Monday 10am)
# Full year, hourly
year = values(sched, year=2024)
print(len(year)) # 8760
# Pandas (requires idfkit[dataframes])
series = to_series(sched, year=2024)
series.plot()
Core API¶
from idfkit.schedules import (
evaluate, # single-timestamp lookup
values, # array of hourly (or sub-hourly) values
to_series, # pandas Series
plot_schedule,
plot_day,
plot_week, # quick plots
create_compact_schedule_from_values,
create_constant_schedule,
create_schedule_type_limits,
ScheduleFileCache,
get_holidays,
extract_special_days,
)
Supported schedule types¶
The evaluator covers every standard EnergyPlus schedule type:
Schedule:Compact(the most common)Schedule:Year+Schedule:Week:Daily/Week:Compact+Schedule:Day:Hourly/Day:Interval/Day:ListSchedule:ConstantSchedule:File(reads the CSV directly, with optionalFileSystemfor S3)ScheduleTypeLimitsresolution
If you hit an unsupported type, UnsupportedScheduleType is raised.
Single-timestamp evaluation¶
from datetime import datetime
from idfkit.schedules import evaluate
sched = doc["Schedule:Compact"]["Office Occupancy"]
# Default — uses the calendar day type derived from the date
v = evaluate(sched, datetime(2024, 7, 15, 14, 0))
# Override day type (useful for sizing checks)
v_summer = evaluate(sched, datetime(2024, 7, 15, 14, 0), day_type="summer")
v_winter = evaluate(sched, datetime(2024, 1, 15, 6, 0), day_type="winter")
v_holiday = evaluate(sched, datetime(2024, 12, 25, 10, 0), day_type="holiday")
day_type accepts "normal", "summer", "winter", "holiday" and an explicit DayType enum.
Annual values¶
from idfkit.schedules import values
annual = values(sched, year=2024) # 8760 hourly values
sub_hourly = values(sched, year=2024, timestep=4) # 35,040 quarter-hourly values
By default values returns a list[float]. For pandas:
from idfkit.schedules import to_series
ts = to_series(sched, year=2024) # DatetimeIndex, length 8760
Plotting¶
from idfkit.schedules import plot_schedule, plot_day, plot_week
plot_schedule(sched, year=2024) # entire year
plot_day(sched, year=2024, month=7, day=15) # one day
plot_week(sched, year=2024, week=29) # week 29 (mid-July)
These pick the default backend (matplotlib if idfkit[plot] is installed, plotly if idfkit[plotly]). Pass backend="plotly" or backend="matplotlib" to force.
Building schedules programmatically¶
from idfkit.schedules import (
create_constant_schedule,
create_compact_schedule_from_values,
create_schedule_type_limits,
)
# Type limits (required by many schedule types)
limits = create_schedule_type_limits(doc, "Fraction", lower=0.0, upper=1.0)
# Constant
always_on = create_constant_schedule(doc, "Always On", value=1.0, type_limits="Fraction")
# From an array of hourly values for the year. The array length must match
# the number of hours in the target year (8760 for non-leap, 8784 for leap).
import numpy as np
arr = np.zeros(8760)
arr[6 * 24 : 18 * 24] = 1.0 # mornings of week 1 occupied (toy example)
sched = create_compact_schedule_from_values(
doc,
"Office Occupancy",
arr.tolist(), # Sequence[float] — NumPy arrays need .tolist()
year=2023, # non-leap → 8760
type_limits="Fraction",
)
create_compact_schedule_from_values is a one-shot way to take an array and emit a Schedule:Compact object — useful when you have hourly inputs from measurement data.
Auditing schedule usage¶
# Names of every schedule referenced by anything in the model
used = doc.get_used_schedules() # set[str]
all_schedules = doc.schedules_dict # {name: IDFObject} across all Schedule:* types
# Unused schedules — can usually be deleted
for name in all_schedules.keys() - used:
print("unused:", name)
Schedule:File¶
Schedule:File reads CSV data from disk (or S3 if you provide a FileSystem):
from idfkit.simulation.fs import S3FileSystem
from idfkit.schedules import values
fs = S3FileSystem(bucket="models", prefix="data/")
hourly = values(doc["Schedule:File"]["Plug Loads"], fs=fs)
For batch workflows reuse a ScheduleFileCache to avoid re-reading the same CSV:
from idfkit.schedules import ScheduleFileCache
from idfkit.simulation.fs import LocalFileSystem
# Reuse one cache across many Schedule:File reads to avoid re-parsing the CSV.
cache = ScheduleFileCache()
file_sched = doc["Schedule:File"]["Plug Loads"]
raw = cache.get_values(file_sched, LocalFileSystem()) # parsed once, cached by file + column
Holidays and special days¶
from idfkit.schedules import get_holidays, extract_special_days
# Pull RunPeriodControl:SpecialDays from a document for a year
specials = extract_special_days(doc, 2024)
# Set[date] of dates classified as holidays for that year
holidays = get_holidays(doc, 2024)
Both functions read the document's RunPeriodControl:SpecialDays objects — idfkit does not bundle external holiday calendars. To use country-specific calendars, add the corresponding SpecialDays entries yourself (e.g. from the holidays PyPI package) before calling.
Common mistakes¶
evaluating a schedule that references missing schedules
assuming hourly when the schedule is sub-hourly
match the simulation timestep
passing a date in a non-leap year for Feb 29
Related¶
- document-and-objects.md —
doc.add(Schedule:Compact, ...)etc. - reference-tracking.md — finding what references a schedule.
- result-parsing.md — compare evaluated schedules against simulated
Schedule Valueoutputs. - API docs: py.idfkit.com/schedules/