Show interactive schedule heatmap from the loaded model.
Renders EnergyPlus schedules as a visual heatmap showing hourly values
across days of the week (week view) or across the full year (year view).
Supports Schedule:Compact, Schedule:Constant, Schedule:Year, and
Schedule:File types.
Source code in src/idfkit_mcp/tools/schedule.py
| @tool(
annotations=_READ_ONLY,
meta={
"ui": app_config_to_meta_dict(
AppConfig(
resourceUri="ui://idfkit/schedule-viewer.html",
prefersBorder=False,
)
)
},
)
def view_schedules(
name: Annotated[
str | None,
Field(description="Schedule name to visualize. If omitted, shows all top-level schedules."),
] = None,
year: Annotated[
int,
Field(description="Year for schedule evaluation (affects day-of-week alignment).", ge=2000, le=2100),
] = 2024,
) -> ToolResult:
"""Show interactive schedule heatmap from the loaded model.
Renders EnergyPlus schedules as a visual heatmap showing hourly values
across days of the week (week view) or across the full year (year view).
Supports Schedule:Compact, Schedule:Constant, Schedule:Year, and
Schedule:File types.
"""
data = _extract_schedules(name, year)
schedule_list: list[dict[str, object]] = data["schedules"] # type: ignore[assignment]
skipped_list: list[str] = data["skipped"] # type: ignore[assignment]
count = len(schedule_list)
logger.info("Extracted %d schedules for viewer (skipped %d)", count, len(skipped_list))
# Text summary for non-Apps clients.
names = [str(s["name"]) for s in schedule_list]
summary_parts = [f"Schedule heatmap: {count} schedule(s) evaluated for year {year}."]
if names:
summary_parts.append("Schedules: " + ", ".join(names[:10]))
if len(names) > 10:
summary_parts.append(f"... and {len(names) - 10} more.")
if skipped_list:
summary_parts.append(f"Skipped {len(skipped_list)}: " + "; ".join(skipped_list))
return ToolResult(
content=[
TextContent(type="text", text=json.dumps(data)),
TextContent(type="text", text=" ".join(summary_parts)),
]
)
|