Know when a window's direct sun will actually reach a desk, plant shelf, or tabletop. Offline, reproducible, and dependency-free.
Most sun calculators stop at azimuth and elevation. Room planners stop at a picture. Professional daylight suites are powerful but heavy. WindowRay takes a narrow measured scenario—location, fixed UTC offset, rectangular room, wall openings, and horizontal target surfaces—and emits auditable hit samples plus a report you can open locally.
WindowRay predicts idealized direct geometric visibility. It does not predict lux, perceived brightness, weather, plant health, glare safety, or code compliance.
No installation or network access is required after cloning:
git clone https://github.com/KanadeK/windowray.git
cd windowray
python -m windowray validate examples/home-office.json
python -m windowray plan examples/home-office.json --out build/demoOpen build/demo/report.html. The command also writes plan.json, samples.csv, and floorplan.svg.
Prefer one file? Download windowray-0.1.0.pyz from the latest release:
python windowray-0.1.0.pyz validate home-office.json
python windowray-0.1.0.pyz plan home-office.json --out reportThe committed Los Angeles home-office scenario covers seven winter days at 15-minute resolution:
| Target | Result |
|---|---|
desk |
88 hit samples, about 1,320 sampled minutes, 33.3% peak surface coverage |
plant-shelf |
0 hit samples—the intentional no-hit control farther from the opening |
| Work performed | 6,720 point-to-boundary rays |
This is generated by the same pipeline shipped to users. The Pages site rebuilds its fully static demo from this JSON on every deployment.
- NOAA's published fractional-year equations produce geometric solar elevation and azimuth for each local timestamp.
- The sun vector is rotated into the room's local axes.
- A ray leaves every target grid point toward the sun.
- A point counts as lit only when the nearest room boundary is a wall and the intersection lies inside a declared window opening.
- Consecutive positive samples become local-time hit intervals; coverage remains available per sample in JSON and CSV.
The algorithm, tolerances, coordinates, and limitations are documented in the model guide. The complete input/output contract is in the specification.
x: local west → east.y: towardroom.y_axis_azimuth_deg;0is geographic north,90east.z: floor → ceiling.south,north,west,east: local room walls, not implied geographic directions.- Window offset: from local west on north/south walls; from local south on east/west walls.
- Target
x_m,y_m: southwest corner of a horizontal rectangle. - Longitude and
utc_offset: standard east-positive signs.
The fixed offset is deliberate. Split a date range at a daylight-saving transition and use the correct offset in each scenario.
| Artifact | Purpose |
|---|---|
plan.json |
Complete deterministic result, model IDs, limitations, summaries, intervals, and samples |
samples.csv |
Spreadsheet/data-tool friendly row per timestamp and target |
report.html |
Self-contained human report; no remote scripts, fonts, or assets |
floorplan.svg |
Top-down room/window/target geometry colored by sampled hit rate |
WindowRay refuses to overwrite these artifacts unless --force is explicit. --force overwrites only the four known names and never deletes unrelated files.
Run the release-candidate gate from the repository root:
python scripts/verify.pyIt runs every test, validates and plans the real example from source, builds the .pyz, reruns the example through the package, compares all four outputs byte-for-byte, and checks the hit/no-hit controls. A successful run ends with:
tests: pass (26 cases)
valid: Los Angeles south-window home office
1 window(s), 2 target(s), 6,720 rays
package: windowray 0.1.0
artifacts: source/package byte parity pass
example: desk 88 hit samples; plant-shelf 0-hit control
VERIFY PASS
Focused commands:
python -m unittest discover -s tests -v
python scripts/build_zipapp.py
python dist/windowray-0.1.0.pyz --versionWindowRay uses exit code 2 for expected input/output errors and preserves a traceback for unexpected code failures.
| Symptom | Cause | Repair |
|---|---|---|
No module named windowray |
Source command was run outside the repository root | cd to the cloned repository, or use the release .pyz |
invalid JSON / unexpected field |
Syntax error or a misspelled schema key | Run validate, fix the exact path named in the one-line error, then rerun plan |
already exists |
One of the four report files is present | Choose a new output directory, or review it and pass --force intentionally |
| Plausible room produces zero hits | Local wall/bearing, sill/height, target coordinates, or fixed UTC offset is wrong | Check floorplan.svg; verify y_axis_azimuth_deg, wall name, opening bounds, and offset sign; then inspect samples.csv solar angles |
| Dates cross a DST change | One fixed offset cannot describe both sides | Split the input into two date ranges with the applicable UTC offsets |
source/package parity failed |
Packaged code and source output diverged | Run python scripts/build_zipapp.py, then rerun python scripts/verify.py; if it persists, treat it as a code defect and do not release |
| CI fails on one Python/OS cell | A cross-platform behavior regressed | Run that cell's Python version locally if available, reproduce with the printed command, fix the first failing test, then rerun the full gate |
More detail: Troubleshooting.
No diffuse light, illuminance, material reflectance, atmospheric refraction, weather, exterior obstruction, curtain, furniture occlusion, complex room geometry, vertical targets, or professional certification. For those jobs, use a validated daylight-simulation workflow such as Radiance/Honeybee and a qualified practitioner.
The novelty brief records the closest GitHub project classes and why WindowRay is not a repackaged clone.
- Python 3.11+, standard library only at runtime.
- No network, subprocess, plugin, telemetry, dynamic import, or user-code execution in the application.
- CI covers Python 3.11–3.14 on Ubuntu and Windows.
- Untrusted JSON is size/type/range/workload checked; report strings are escaped.
- Architecture decision: ADR 0001.
See CONTRIBUTING.md and SECURITY.md. Licensed under MIT.
WindowRay 是一个离线直射日光命中规划器:输入地点、固定 UTC 偏移、矩形房间、墙面窗洞和水平目标面,它会回答“哪些日期和本地时刻,太阳直射线能穿过这扇窗到达这个目标?”
它不是只有界面的房间摆放器,也不是专业采光软件的简化皮肤。它提供真实计算、逐采样 CSV/JSON、自包含 HTML、SVG 平面图和可独立运行的 .pyz。
python -m windowray validate examples/home-office.json
python -m windowray plan examples/home-office.json --out build/demo
python scripts/verify.py验收通过应以 VERIFY PASS 结束。示例实际执行 6,720 条射线:书桌有 88 个命中采样,较远的植物架为 0,能直接用于比较布局。
请特别注意:结果只代表理想直线几何可见性,不代表照度、体感亮度、天气、植物适宜度、眩光安全或建筑合规。跨夏令时必须拆成两个场景并分别填写正确 UTC 偏移。输入结构、坐标和上限见 完整规格,失败修复见上表和 故障排查。