Skip to content

Commit 24bb06d

Browse files
authored
Merge pull request #38 from NatLabRockies/develop
v0.8.2
2 parents b22c6e6 + 9260b7a commit 24bb06d

58 files changed

Lines changed: 55067 additions & 1490 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/measure-authoring/SKILL.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ create_measure(
3434
```
3535
test_measure(measure_dir="/runs/custom_measures/set_lights_8w")
3636
```
37+
Tests run against the currently loaded model (or SystemD_baseline.osm fallback),
38+
so measures that depend on HVAC, plant loops, or zones will work correctly.
39+
Use `model_path` to test against a specific model.
3740

3841
### 3. Apply to Model
3942
```
@@ -103,6 +106,40 @@ extract_summary_metrics(run_id=<retrofit_id>) # compare to baseline
103106

104107
WARNING: Beams are AIR TERMINALS (connect via `air_loop.addBranchForZone`), NOT zone equipment (`addToThermalZone`).
105108

109+
## ReportingMeasures
110+
111+
ReportingMeasures run **after simulation** and access SQL results. Use when the user wants to
112+
generate custom reports, extract specific metrics, or post-process simulation output.
113+
114+
### Create a ReportingMeasure
115+
```
116+
create_measure(
117+
name="custom_eui_report",
118+
description="Extract and report custom EUI breakdown",
119+
language="Ruby",
120+
measure_type="ReportingMeasure",
121+
run_body=' query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName=\'AnnualBuildingUtilityPerformanceSummary\' AND TableName=\'Site and Source Energy\' AND RowName=\'Total Site Energy\' AND ColumnName=\'Total Energy\' AND Units=\'GJ\'"\n val = sql.execAndReturnFirstDouble(query)\n if val.is_initialized\n runner.registerValue("total_site_energy_gj", val.get)\n runner.registerInfo("Total Site Energy: #{val.get} GJ")\n end\n runner.registerFinalCondition("Report complete")'
122+
)
123+
```
124+
125+
### Test with Simulation Results
126+
```
127+
# ReportingMeasures need SQL — provide run_id from a completed sim
128+
test_measure(measure_dir="/runs/custom_measures/custom_eui_report", run_id="<completed_run_id>")
129+
```
130+
Without `run_id`, only argument validation tests run (no `run()` execution).
131+
132+
### Apply to Completed Simulation
133+
```
134+
apply_measure(measure_dir="/runs/custom_measures/custom_eui_report", run_id="<completed_run_id>")
135+
```
136+
137+
### Key Differences from ModelMeasure
138+
- `run()` signature: `(runner, user_arguments)` — no `model` param
139+
- Model & SQL boilerplate is auto-generated: `model` and `sql` variables are available in run_body
140+
- `arguments()` takes no params (not `model`)
141+
- Includes empty `energyPlusOutputRequests()` stub (edit via `edit_measure` if needed)
142+
106143
## Notes
107144

108145
- `run_body` indentation matters: Ruby = 4 spaces, Python = 8 spaces

.claude/skills/tool-workflows/SKILL.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,26 @@ extract_summary_metrics(run_id=<retrofit_id>)
120120

121121
See the `measure-authoring` skill for run_body patterns and language guidance.
122122

123+
## Write and Apply a Custom ReportingMeasure
124+
125+
ReportingMeasures run after simulation to analyze SQL results.
126+
127+
```
128+
# 1. Run simulation first
129+
run_simulation(osm_path="/runs/model.osm", epw_path="<epw>")
130+
131+
# 2. Create reporting measure
132+
create_measure(name="custom_report", description="...",
133+
language="Ruby", measure_type="ReportingMeasure",
134+
run_body=" val = sql.execAndReturnFirstDouble('SELECT ...')\n runner.registerValue('metric', val.get) if val.is_initialized")
135+
136+
# 3. Test against completed simulation
137+
test_measure(measure_dir="/runs/custom_measures/custom_report", run_id="<run_id>")
138+
139+
# 4. Apply to completed simulation
140+
apply_measure(measure_dir="/runs/custom_measures/custom_report", run_id="<run_id>")
141+
```
142+
123143
## Object Cleanup
124144

125145
```

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
;;
7373
3)
7474
# controls, object mgmt, loads, building, doas, hvac, measures, measure_authoring, skill_qaqc, hvac_supply_wiring
75-
FILES="tests/test_component_controls.py tests/test_object_management.py tests/test_generic_access.py tests/test_create_loads.py tests/test_building.py tests/test_doas_system.py tests/test_hvac.py tests/test_measures.py tests/test_measure_authoring.py tests/test_skill_qaqc.py tests/test_hvac_supply_wiring.py"
75+
FILES="tests/test_component_controls.py tests/test_object_management.py tests/test_generic_access.py tests/test_create_loads.py tests/test_building.py tests/test_doas_system.py tests/test_hvac.py tests/test_measures.py tests/test_measure_authoring.py tests/test_skill_qaqc.py tests/test_hvac_supply_wiring.py tests/test_validate_model.py"
7676
EXTRA_ENV=""
7777
;;
7878
4)

AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# AGENTS.md — Codex CLI Instructions
22

33
## Project
4-
OpenStudio MCP server — 22 skills, 126 tools, ~14K prod lines.
4+
OpenStudio MCP server — 24 skills, 138 tools, ~18K prod lines.
55

66
## Architecture
77
- `mcp_server/skills/<name>/tools.py` — MCP tool defs, calls operations
@@ -16,6 +16,7 @@ OpenStudio MCP server — 22 skills, 126 tools, ~14K prod lines.
1616
- No `getattr()` for OpenStudio API calls — every method must be explicit
1717
- No `shell=True` in subprocess calls
1818
- Tool functions use `_tool` suffix internally, MCP name strips it
19+
- `list[str]` params use `list[str] | str` type + `parse_str_list()` from `osm_helpers.py` (MCP clients may send JSON strings)
1920

2021
## Review Focus
2122
When reviewing code, check for:

0 commit comments

Comments
 (0)