{"id":"v001","input":{"lat":39.7392,"lon":-104.9903,"date":"2026-06-21","offset":"-06:00"},"expect":{"result.max_elevation.value":73.70293597864959,"ok":true},"source":"NOAA solar calculator equations transcribed in Python (tools/vectors/gen_sun.py)","sourceVersion":"NOAA GML 2023","tolerance":{"result.max_elevation.value":{"rel":0,"abs":0.01}}}
{"id":"v002","input":{"lat":40.4406,"lon":-79.9959,"date":"2026-09-18","offset":"-04:00"},"expect":{"result.max_elevation.value":51.23821351216183,"ok":true},"source":"NOAA solar calculator equations transcribed in Python (tools/vectors/gen_sun.py)","sourceVersion":"NOAA GML 2023","tolerance":{"result.max_elevation.value":{"rel":0,"abs":0.01}}}
{"id":"v003","input":{"lat":51.5074,"lon":-0.1278,"date":"2026-01-15","offset":"+00:00"},"expect":{"result.max_elevation.value":17.47689893175902,"ok":true},"source":"NOAA solar calculator equations transcribed in Python (tools/vectors/gen_sun.py)","sourceVersion":"NOAA GML 2023","tolerance":{"result.max_elevation.value":{"rel":0,"abs":0.01}}}
{"id":"v004","input":{"lat":51.5074,"lon":-0.1278,"date":"2026-01-15","offset":"+00:00","threshold":30},"expect":{"result.window":"at no time that day","ok":true},"source":"NOAA solar calculator equations transcribed in Python (tools/vectors/gen_sun.py)","sourceVersion":"NOAA GML 2023","tolerance":{}}
{"id":"v005","input":{"lat":69.65,"lon":18.96,"date":"2026-06-21","offset":"+02:00","threshold":2},"expect":{"result.window":"all day","ok":true},"source":"NOAA solar calculator equations transcribed in Python (tools/vectors/gen_sun.py)","sourceVersion":"NOAA GML 2023","tolerance":{}}
{"id": "v006", "input": {"lat": 39.7392, "lon": -104.9903, "date": "2026-03-21", "offset": "-06:00"}, "expect": {"ok": true, "result.max_elevation.value": 50.7400670416549, "result.window_start": "2026-03-21 09:48 local (2026-03-21 1548Z)", "result.window_end": "2026-03-21 16:27 local (2026-03-21 2227Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v007", "input": {"lat": 39.7392, "lon": -104.9903, "date": "2026-12-21", "offset": "-07:00"}, "expect": {"ok": true, "result.max_elevation.value": 26.85419255372457}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}}}
{"id": "v008", "input": {"lat": 39.7392, "lon": -104.9903, "date": "2026-06-21", "offset": "-06:00", "threshold": "60 deg"}, "expect": {"ok": true, "result.max_elevation.value": 73.70231595494649, "result.window_start": "2026-06-21 11:02 local (2026-06-21 1702Z)", "result.window_end": "2026-06-21 15:01 local (2026-06-21 2101Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v009", "input": {"lat": 51.5074, "lon": -0.1278, "date": "2026-06-21", "offset": "+01:00"}, "expect": {"ok": true, "result.max_elevation.value": 61.93832922322509, "result.window_start": "2026-06-21 08:19 local (2026-06-21 0719Z)", "result.window_end": "2026-06-21 17:45 local (2026-06-21 1645Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v010", "input": {"lat": 51.5074, "lon": -0.1278, "date": "2026-09-18", "offset": "+01:00", "threshold": "20 deg"}, "expect": {"ok": true, "result.max_elevation.value": 40.26088003425433, "result.window_start": "2026-09-18 08:57 local (2026-09-18 0757Z)", "result.window_end": "2026-09-18 16:51 local (2026-09-18 1551Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v011", "input": {"lat": -33.8688, "lon": 151.2093, "date": "2026-01-15", "offset": "+11:00"}, "expect": {"ok": true, "result.max_elevation.value": 77.27923292751645, "result.window_start": "2026-01-15 08:35 local (2026-01-14 2135Z)", "result.window_end": "2026-01-15 17:34 local (2026-01-15 0634Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v012", "input": {"lat": -33.8688, "lon": 151.2093, "date": "2026-06-21", "offset": "+10:00", "threshold": "20 deg"}, "expect": {"ok": true, "result.max_elevation.value": 32.717574590958684, "result.window_start": "2026-06-21 09:08 local (2026-06-20 2308Z)", "result.window_end": "2026-06-21 14:46 local (2026-06-21 0446Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v013", "input": {"lat": 1.3521, "lon": 103.8198, "date": "2026-03-21", "offset": "+08:00"}, "expect": {"ok": true, "result.max_elevation.value": 88.88602671941187, "result.window_start": "2026-03-21 09:12 local (2026-03-21 0112Z)", "result.window_end": "2026-03-21 17:12 local (2026-03-21 0912Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v014", "input": {"lat": 1.3521, "lon": 103.8198, "date": "2026-03-21", "offset": "+08:00", "threshold": "70 deg"}, "expect": {"ok": true, "result.max_elevation.value": 88.88602671941187, "result.window_start": "2026-03-21 11:52 local (2026-03-21 0352Z)", "result.window_end": "2026-03-21 14:32 local (2026-03-21 0632Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v015", "input": {"lat": 25.2048, "lon": 55.2708, "date": "2026-11-11", "offset": "+04:00"}, "expect": {"ok": true, "result.max_elevation.value": 47.355711449136344, "result.window_start": "2026-11-11 09:09 local (2026-11-11 0509Z)", "result.window_end": "2026-11-11 14:56 local (2026-11-11 1056Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v016", "input": {"lat": 35.6762, "lon": 139.6503, "date": "2026-04-10", "offset": "+09:00"}, "expect": {"ok": true, "result.max_elevation.value": 62.243479540656956, "result.window_start": "2026-04-10 07:49 local (2026-04-09 2249Z)", "result.window_end": "2026-04-10 15:37 local (2026-04-10 0637Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v017", "input": {"lat": 47.6062, "lon": -122.3321, "date": "2026-08-05", "offset": "-07:00"}, "expect": {"ok": true, "result.max_elevation.value": 59.19383524021153, "result.window_start": "2026-08-05 09:01 local (2026-08-05 1601Z)", "result.window_end": "2026-08-05 17:30 local (2026-08-06 0030Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v018", "input": {"lat": -22.9068, "lon": -43.1729, "date": "2026-09-18", "offset": "-03:00"}, "expect": {"ok": true, "result.max_elevation.value": 65.39597629411001, "result.window_start": "2026-09-18 08:02 local (2026-09-18 1102Z)", "result.window_end": "2026-09-18 15:32 local (2026-09-18 1832Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v019", "input": {"lat": 19.4326, "lon": -99.1332, "date": "2026-05-05", "offset": "-05:00", "threshold": "45 deg"}, "expect": {"ok": true, "result.max_elevation.value": 86.98288295015388, "result.window_start": "2026-05-05 10:24 local (2026-05-05 1524Z)", "result.window_end": "2026-05-05 16:43 local (2026-05-05 2143Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v020", "input": {"lat": -1.2921, "lon": 36.8219, "date": "2026-07-01", "offset": "+03:00"}, "expect": {"ok": true, "result.max_elevation.value": 65.62295841686596, "result.window_start": "2026-07-01 08:51 local (2026-07-01 0551Z)", "result.window_end": "2026-07-01 16:22 local (2026-07-01 1322Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
{"id": "v021", "input": {"lat": 30.0444, "lon": 31.2357, "date": "2026-02-14", "offset": "+02:00"}, "expect": {"ok": true, "result.max_elevation.value": 47.0233340747007, "result.window_start": "2026-02-14 09:15 local (2026-02-14 0715Z)", "result.window_end": "2026-02-14 15:03 local (2026-02-14 1303Z)"}, "source": "Sun position from pvlib's NREL SPA (sea level, 101325 Pa, 12 C); threshold crossings by bisection (tools/vectors/gen_sun_pvlib.py)", "sourceVersion": "pvlib 0.13.0", "tolerance": {"result.max_elevation.value": {"abs": 0.001}, "result.window_start": {"abs": 0}, "result.window_end": {"abs": 0}}}
