|
| 1 | +--- |
| 2 | +name: comcheck-api |
| 3 | +description: Use this skill when the user is writing Python code that uses |
| 4 | + the comcheck_api package to build COMcheck project JSON, run compliance |
| 5 | + simulations against the PNNL COMcheck Web API, or work with envelope, |
| 6 | + lighting, mechanical, or building-area operations. Triggers on imports |
| 7 | + of `comcheck_api`, mentions of COMcheck/ASHRAE 90.1/IECC compliance, |
| 8 | + or requests to validate building energy code compliance. |
| 9 | +--- |
| 10 | + |
| 11 | +# COMcheck API Python Client Skill |
| 12 | + |
| 13 | +## When to use this skill |
| 14 | + |
| 15 | +Triggers: |
| 16 | +- The user imports `comcheck_api` or asks for help with it. |
| 17 | +- The user mentions COMcheck, ASHRAE 90.1, IECC, or commercial building |
| 18 | + energy code compliance. |
| 19 | +- The user wants to build, update, or run a simulation on a COMcheck |
| 20 | + project from Python. |
| 21 | + |
| 22 | +## Core concepts |
| 23 | + |
| 24 | +- **Single entry point**: `COMcheckClient` is the only client class |
| 25 | + users instantiate. Construct with `api_key=...` or rely on the |
| 26 | + `COM_API_KEY` env var. |
| 27 | +- **Project shape**: a project is a `ComBuilding` Pydantic model. It |
| 28 | + contains: `Project` (metadata), `Location`, `Envelope`, `WholeBldgUse[]` |
| 29 | + (building areas), `HVAC`, `Lighting`, `Renewable`, and `Control`. |
| 30 | +- **Operation classes (functional)**: building areas and envelope |
| 31 | + components are added/updated/removed via free functions in |
| 32 | + `project_building_area_operations` and `project_envelope_operations`. |
| 33 | + Each function takes a `ComBuilding` and returns a new `ComBuilding`. |
| 34 | +- **Defaults**: `comcheck_api.defaults` has `get_default_*_template()` |
| 35 | + functions that return Pydantic models filled with sensible defaults. |
| 36 | + Always start from these. |
| 37 | +- **Simulation flow is async**: `start_run_simulation` returns a |
| 38 | + session ID. Poll `get_simulation_status` until status is `complete`, |
| 39 | + then call `get_simulation_result`. |
| 40 | + |
| 41 | +## Quick start |
| 42 | + |
| 43 | +```python |
| 44 | +from comcheck_api import COMcheckClient |
| 45 | +from comcheck_api.defaults import get_default_project_template |
| 46 | + |
| 47 | +client = COMcheckClient(api_key="your-key") |
| 48 | + |
| 49 | +# Build a project from a default template |
| 50 | +project = get_default_project_template() |
| 51 | +project.Project.title = "5,000 sqft office in Seattle" |
| 52 | + |
| 53 | +# Save it (creates server-side project, returns ID via list) |
| 54 | +# Update if you have an existing ID: |
| 55 | +# updated = client.update_project(project_id="123", project_data=project) |
| 56 | + |
| 57 | +# Run a simulation |
| 58 | +session_id = client.start_run_simulation(project) |
| 59 | + |
| 60 | +# Poll until complete |
| 61 | +import time |
| 62 | +while True: |
| 63 | + status = client.get_simulation_status(session_id) |
| 64 | + if status["status"] == "complete": |
| 65 | + break |
| 66 | + time.sleep(5) |
| 67 | + |
| 68 | +result = client.get_simulation_result(session_id) |
| 69 | +print(result["performanceRating"]) |
| 70 | +``` |
| 71 | + |
| 72 | +## Conventions (do) |
| 73 | + |
| 74 | +- Use `get_default_*_template()` to start any new component, then |
| 75 | + customize. Don't construct `ComBuilding` from scratch. |
| 76 | +- Use the operation classes (e.g., |
| 77 | + `project_envelope_operations.add_ag_wall_to_project(project, wall)`) |
| 78 | + to mutate project structure. Don't manipulate nested dicts directly. |
| 79 | +- Read the API key from `COM_API_KEY` env var by default; let users |
| 80 | + pass `api_key=...` to override. |
| 81 | +- Wrap network calls in try/except and catch `COMCheckHTTPError`, |
| 82 | + `COMCheckConnectionError`, `COMCheckValidationError`, |
| 83 | + `COMCheckSimulationError`, `COMCheckProjectNotFoundError`. |
| 84 | +- The package uses `httpx`, not `requests`. |
| 85 | + |
| 86 | +## Conventions (don't) |
| 87 | + |
| 88 | +- Don't construct project JSON by hand — use templates + operation |
| 89 | + functions. |
| 90 | +- Don't suggest `requests` — the SDK is `httpx`-based. |
| 91 | +- Don't import private modules (anything starting with `_`). |
| 92 | +- Don't poll `get_simulation_status` faster than every 5 seconds. |
| 93 | +- Don't put the API key in source code; use env var or argument. |
| 94 | + |
| 95 | +## Common patterns |
| 96 | + |
| 97 | +### Adding an above-grade wall |
| 98 | + |
| 99 | +```python |
| 100 | +from comcheck_api import project_envelope_operations as envelope_ops |
| 101 | +from comcheck_api.defaults import get_default_ag_wall_template |
| 102 | + |
| 103 | +wall = get_default_ag_wall_template() |
| 104 | +wall.name = "South wall" |
| 105 | +wall.area = 4800.0 |
| 106 | +project = envelope_ops.add_ag_wall_to_project(project, wall) |
| 107 | +``` |
| 108 | + |
| 109 | +### Listing the user's projects and updating one |
| 110 | + |
| 111 | +```python |
| 112 | +projects = client.list_projects() |
| 113 | +target = next(p for p in projects if p["title"] == "My office") |
| 114 | +project_obj = client.get_project(target["id"]) |
| 115 | +project_obj.Project.title = "My office (revised)" |
| 116 | +client.update_project(project_id=target["id"], project_data=project_obj) |
| 117 | +``` |
| 118 | + |
| 119 | +### Polling a simulation with a timeout |
| 120 | + |
| 121 | +```python |
| 122 | +import time |
| 123 | +session_id = client.start_run_simulation(project) |
| 124 | +deadline = time.time() + 300 # 5 min |
| 125 | +while time.time() < deadline: |
| 126 | + status = client.get_simulation_status(session_id) |
| 127 | + if status["status"] == "complete": |
| 128 | + result = client.get_simulation_result(session_id) |
| 129 | + break |
| 130 | + time.sleep(5) |
| 131 | +else: |
| 132 | + raise TimeoutError(f"Simulation {session_id} did not complete in 5 min") |
| 133 | +``` |
| 134 | + |
| 135 | +## When you need more detail |
| 136 | + |
| 137 | +- For envelope assemblies (roof, walls, floor, windows, doors, |
| 138 | + skylights, thermal bridges) → read `reference/operations.md`. |
| 139 | +- For Pydantic model field-level details → read `reference/types.md`. |
| 140 | +- For the simulation start/poll/fetch flow → read |
| 141 | + `reference/simulation.md`. |
| 142 | +- To validate generated code against a mocked client → run |
| 143 | + `scripts/validate_code.py`. |
0 commit comments