Replies: 3 comments
Update: the plan has changed, and it is now four PRsTwo things drove the revision. @frahlg's review of #718 pointed out — correctly — Everything below is implemented, tested and open as draft PRs. What the investigation changedSTRÅNG's parameter set, measured rather than assumedSMHI's apidocs pages currently 404, so the RFC's parameter list was a best
Two independent checks pin the identification: 121 + 122 = 723.0 + 87.5 = Cloud cover does not exist in STRÅNG — but it is derivableWorth stating plainly since it came up: STRÅNG is a radiation model and The trap this walked into, and the fixThe first working version reported 100% cloud cover at midnight, confidently, So The domain is measured, and the bounds are honestly advisorySTRÅNG's extent was probed rather than assumed: data at lat 53.5 and 72.5 but not But the grid is rotated relative to lat/lon, so a box can only ever be a The four PRs
#718 — plane-of-array wiringNarrowed to exactly what @frahlg suggested: the half that is user-visible today. #734 — STRÅNG source + coverage metadataThe STRÅNG client, the performance scoring that consumes it, and the calibration This makes an existing silence explicit — STRÅNG is Nordic-only and every price Also here: #735 — roof geometryAnswers open question 1 — yes to a third module, structured exactly like the SPAN's method (RANSAC per surface, then DBSCAN to split faces sharing a plane but Two choices worth surfacing for review:
#736 — optional vostok shadingEach face is run twice, once against real occlusion geometry and once with The GPL boundary is exactly as the RFC proposed: separate process, files and a A maintainer should sanity-check that licensing reading before it ships. It is Answers to the RFC's open questions
What is not builtTerra Draw "draw your array" (RFC phase 5-manual). The MapLibre swap in #734 is Still needed from youThe live Lantmäteriet fetch is the one path not exercised end-to-end — it needs Attribution: SMHI STRÅNG and Lantmäteriet data are CC BY 4.0. |
Update: you now pick your building, and the roof is read from that footprintSince this morning's update This closes the gap the RFC left widest: derive a roof is meaningless until you Why a picker — the measurement that forced itBefore this, a derive segmented a radius: your roof, the neighbour's, the garage, RANSAC fits infinite planes. A roof at azimuth 180° is A synthetic tile: a 12 × 12 m house and an 8 × 8 m garage, both at 35°, ridges Both buildings' south faces are consumed as one surface. Only the DBSCAN pass The sharpest evidence that this is a global effect rather than a proximity one:
A neighbourhood method would fade with distance. This does not fade, because the Clipping to the picked footprint restores the isolated result exactly. The Two honest caveats about those numbers, since they cut against the headlineIn this particular scene the unclipped area is coincidentally closer to truth. The −12% is a separate systematic, and it is mine. Area is derived as What it looks like in use
Geotorget credentials now have somewhere to goThe RFC promised these would be "stored redacted, exactly like today's There is a short A correction to this morning's commentI wrote that "auto-applying derived arrays to config is deliberately not wired… A successful derive fills the arrays into the editor — you see real numbers in The roofmodel tests were not actually running in CIWorth flagging separately, since it is a repository issue rather than a feature. It found two real bugs immediately, both invisible on WindowsThe Go tests stub the Python module with a fake executable. The stub returned Both are gone: the tests now re-exec the test binary itself as the stub Still not builtTerra Draw free-hand polygon drawing (RFC phase 5-manual). Picking a published Still needed from youUnchanged, and now the only thing standing between this and a real roof: the live Same caveat as before on vostok: written to the documented interface, exercised Attribution: SMHI STRÅNG and Lantmäteriet data are CC BY 4.0. |
Update: the ingest layer now matches what Lantmäteriet actually publishesPushed to #735 (ee93827), This settles a question I left open in the last Both products are STAC APIs behind one account, differing only in what their The correctionI wrote that "inline geometry and GeoJSON assets are handled today". Only the GeoPackage without GDALA GeoPackage is a SQLite database holding geometry as a short header followed by The fixtures are built from the spec, not from the decoderA decoder tested against blobs its own encoder produced agrees with itself and Picking a building now makes it cheap as well as correctCOPC orders its points into an octree with the index at a known offset, so a Best-effort, in this order: plain Also corrected: the coplanar measurementThe 93% / two-fragment figures I quoted for the garage do not reproduce, and are Still needed from you, unchanged: Geotorget credentials for the live fetch. Attribution: SMHI STRÅNG and Lantmäteriet data are CC BY 4.0. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Summary
This RFC proposes using two Swedish open-data sources to sharpen FTW's PV modeling:
Everything is additive and optional; nothing changes the control tick, dispatch, or the optimizer contract.
What FTW already has (so we build on it, not around it)
forecast.Providerinterface withmet_no,openweather,open_meteo(shortwave),forecast_solar(multi-plane PVGIS); results persist to aforecaststable that already has asolar_wm2column.sunpos.POA(t,lat,lon,tilt,az)— plane-of-array physics already in-tree, but currently driven by its own clear-sky model and not wired into the twin.pv_wper slot plus a robustpv_low_w/pv_high_wband.config.Weather.PVArrays[]={name, kWp, tilt_deg, azimuth_deg}, edited today in the Weather settings tab with a Leaflet point-picker + a Three.js 3D preview.history_*tables +DailyEnergy()giving measured PV Wh/day.Key finding: STRÅNG is historical, not a forecast
STRÅNG is an analysis/reanalysis product (hourly, ~2.5 km, 1999→present, ~1-day lag, CC BY 4.0, no API key). It has no forward horizon. So its value is not "STRÅNG predicts tomorrow" — it is:
Forward forecasting stays on
open_meteo/forecast_solar/ SMHI metfcst.STRÅNG API specifics & the SMHI forecast-API migration
Point time-series REST:
https://opendata-download-metanalys.smhi.se/api/category/strang1g/version/1/geotype/point/lon/{lon}/lat/{lat}/parameter/{p}/data.jsonwith
from/to/interval. Parameters: 117 = Global irradiance (GHI), 122 = Diffuse (verify the others against the live apidocs). Diffuse / direct-horizontal exist only from 2017-04-18.For the forward horizon, note SMHI's forecast API migrated
pmp3g→snow1gv1(old endpoint retired 2026-03-31); confirm whether it exposes shortwave radiation or only cloud cover before relying on it.Proposal & phasing (crawl → walk → run)
sunposphysics)GET /api/pv/performance, dashed "expected" history overlaypv_low_w/pv_high_w(no contract change)pv_arrays<date>" from the STAC datetimeRoof geometry: method, tooling, data & licensing
Proposed shape: an on-host, opt-in, automatic optional module
The roof module is a separate optional module (sibling to the optimizer) with a versioned
roof_model.jsoncontract, independent failure/update semantics, and a safe unavailable state — it only ever pre-fills the user-editablepv_arrays, never touching control.POST /api/roofmodel/derive(the existing subprocess pattern), opt-in and default-off, onboarding-time only, off the control tick, in its own time-boxed process.pv_arraysand stamps provenance — no manual JSON-shuffling. Derived values remain user-editable afterward.geotorget_username/geotorget_token) are stored redacted, exactly like today'sweather.api_key.Is on-host invocation possible under the GPL? (yes — arm's-length subprocess, no bundling)
The FTW-authored
roofmodel/module uses permissive libraries only (laspy BSD, scikit-learn BSD for RANSAC/DBSCAN, pystac-client, pyproj), and reimplements the SPAN method (an algorithm, not copyrightable code) — so the module itself ships with FTW without GPL obligations.vostok is GPL-3.0, so it stays an optional, user-installed external tool invoked at arm's length (a separate process, over the CLI + files) only if present on the host and opted in. Under the FSF's mere-aggregation / arm's-length rule, invoking a separate GPL program by subprocess does not make FTW a derivative work — so FTW's own permissive license is unaffected, even when vostok runs on the same host. The single obligation is distribution: FTW must not bundle or redistribute the vostok binary — the user installs it themselves; with vostok absent, shading is simply skipped (safe unavailable). Nothing (vostok, PDAL, laspy) is ever auto-installed on the host.
This is the standard interpretation of the GPL for arm's-length subprocess use, not formal legal advice — worth a maintainer confirmation of the distribution boundary before shipping.
Why on-host is acceptable despite LiDAR weight: derivation is a one-shot onboarding step, not a runtime tick — it runs in a separate, time-boxed, cancellable process and never blocks dispatch or the control loop.
Provenance ("show when the data is from")
Reuse FTW's existing
fetched_at_msepoch-ms convention. The roof model carriescaptured_at_ms(from the STAC itemproperties.datetime, or the laser stripdatumfield) plusderived_at_ms, surfaced viaGET /api/roofmodeland rendered as a "Lantmäteriet data from<date>" badge on the map. Lantmäteriet is backfilling STACproperties.datetimethrough autumn 2026, so the UI degrades gracefully to "capture date unknown" until then.Open questions for maintainers
roofmodel/, on-host, opt-in) alongside the optimizer — vs. keeping roof derivation entirely out-of-repo (import JSON only)?GET /api/pv/performanceendpoint + a dashed "expected (STRÅNG)" history overlay the right first slice to land (Phases 1–2, no keys, high value)?irradiance_historytable (keepingforecastsforward-only)?Risks
properties.datetimebackfill runs through autumn 2026 → provenance dates may be missing; the UI degrades to "date unknown".pv_low_w/pv_high_ware site-signed ≤ 0 (generation negative) — the low/high↔pessimistic/optimistic mapping needs a direct unit test.Attribution: SMHI STRÅNG and Lantmäteriet data are licensed CC BY 4.0. This text is preserved as originally posted; the implementation and its departures from it are in the comments.
All reactions