Source Valmiera's Faktiskā temperature from Priekuļi as a temporary substitute
CI / backend (push) Successful in 1m7s
CI / frontend (push) Successful in 42s

LVĢMC's open-data station list has no station in or near Valmiera at all
(confirmed live 2026-08-23 in OpenDataStationService.scala), so that fixed
position has been silently blank. Priekuļi is the closest currently-
reporting station -- measured against the app's own calibrated map
coordinates (~56px away vs. the next-closest candidate, Rūjiena, at ~81px),
not a guess. Same pattern already used for Stende/Talsi and Zīlāni/Jēkabpils.

Implemented client-side in Faktiskā's fetch only: query Priekuļi's reading,
remap it back onto the "Valmiera" key before it reaches the rest of the
component. Valmiera's marker position and on-map label are untouched (both
are tied to Valmiera's real map location, not Priekuļi's) -- only the data
source for that one slot changes. This also fixes a second, previously
unexplained symptom for free: the weather-symbol picker only lists cities
with a value, so Valmiera never appeared there either; it now does.

Provisional pending direct confirmation from LVĢMC -- documented as such in
PRODUCT_WORKFLOWS.md, matching how Stende/Zīlāni are already flagged.

Verified: typecheck clean, production build succeeds, headless-browser
checks confirm Valmiera's field shows Priekuļi's real live value (14.8°C,
fresh timestamp, not flagged manual/stale) and now appears in the
weather-symbol exceptions list (13 cities, was 12).
This commit is contained in:
b0txec
2026-08-25 11:16:12 +03:00
parent e1ce1533bd
commit 07b16accb2
2 changed files with 26 additions and 6 deletions
+3 -4
View File
@@ -62,7 +62,7 @@ Fixed positions:
| 4 | Rīga |
| 5 | Jelgava |
| 6 | Ainaži |
| 7 | Valmiera |
| 7 | Valmiera, sourced from Priekuļi (temporary substitute, see below) |
| 8 | Madona |
| 9 | Alūksne |
| 10 | Zīlāni (temporary substitute for Jēkabpils) |
@@ -83,7 +83,7 @@ Completed Faktiskā checkpoint:
- automatic badge-relative image placement using consistent 256×256 asset geometry;
- guarded 3840×1440 export using the fixed wind production artwork.
Confirmed Monda Regular/Bold files are now bundled and used. The export dimensions are locked, but final pixel-level placement must still be compared against the production masters after the font change. As of 2026-08-23 the 12 other fixed positions load real station data; Valmiera has no matching real open-data station yet, so it currently still shows the last synthetic row generated before synthetic data generation was stopped (increasingly stale, since nothing refreshes it). Once the old synthetic rows are wiped from `weather` (a still-pending step — see `docs/UPDATE_ROADMAP.md` Phase 7), Valmiera will show no data until a real source is found.
Confirmed Monda Regular/Bold files are now bundled and used. The export dimensions are locked, but final pixel-level placement must still be compared against the production masters after the font change. All 13 fixed positions now load real station data. Valmiera itself has no matching LVĢMC open-data station (confirmed live 2026-08-23); as of 2026-08-25 that position queries Priekuļi's reading instead, chosen as the closest currently-reporting station by measuring against the app's own calibrated map coordinates (~56px away vs. the next-closest candidate's ~81px). Valmiera's marker position and on-map label are unaffected — only the underlying data source for that slot changed. This is a provisional stand-in pending direct confirmation from LVĢMC.
## Ūdens
@@ -151,7 +151,6 @@ Development limitation: representative forecast CSV fixtures are not currently i
## Decisions still required
- Whether weather conditions can eventually be populated automatically and which provider field is authoritative.
- Whether Stende and Zīlāni remain the production feeds after users test real provider data.
- Confirm how Valmiera is named and sourced when authorized provider data is available.
- Whether Stende, Zīlāni, and now Priekuļi (for Valmiera) remain the production feeds after users test real provider data — Priekuļi is a provisional pick pending direct confirmation from LVĢMC.
- Apply the same native-resolution production comparison to additional broadcast products as they are finalized.
- Required authentication and role separation for analytical, production, and administrative workspaces.
+23 -2
View File
@@ -7,10 +7,26 @@ import type { FaktiskaTemplate } from "./faktiskaTemplates";
import "./mapGraphics.css";
type LatestTemperature = { city: FaktiskaStation; observedAt: string; value: number | null };
type RawLatestTemperature = { city: string; observedAt: string; value: number | null };
const emptyValues = (): Record<FaktiskaStation, string> =>
Object.fromEntries(faktiskaStations.map(city => [city, ""])) as Record<FaktiskaStation, string>;
// LVĢMC's open-data station list has no station in or near Valmiera at all
// (confirmed live 2026-08-23, see OpenDataStationService.scala). Priekuļi is
// the closest currently-reporting station (verified against the app's own
// calibrated map coordinates: ~56px away vs. the next-closest candidate's
// ~81px). Valmiera's marker position and on-map label stay exactly where
// they are -- only the queried data source for that one slot changes.
// Temporary, same pattern as Stende/Zīlāni substituting for Talsi/Jēkabpils
// (see PRODUCT_WORKFLOWS.md); pending confirmation directly from LVĢMC.
const stationSubstitutes: Partial<Record<FaktiskaStation, string>> = {
"Valmiera": "Priekuļi",
};
const substituteToStation = new Map(
Object.entries(stationSubstitutes).map(([station, substitute]) => [substitute, station as FaktiskaStation])
);
export function Faktiska() {
const [values, setValues] = createSignal(emptyValues());
const [overrides, setOverrides] = createSignal<Set<FaktiskaStation>>(new Set());
@@ -21,9 +37,14 @@ export function Faktiska() {
: { width: 3840, height: 1440 };
const fetchLatest = async (): Promise<LatestTemperature[]> => {
const response = await fetch(`${apiHost}/api/query/latest-temperatures/${faktiskaStations.join(",")}`);
const queryCities = faktiskaStations.map(city => stationSubstitutes[city] ?? city);
const response = await fetch(`${apiHost}/api/query/latest-temperatures/${queryCities.join(",")}`);
if (!response.ok) throw new Error(`Latest observations failed (${response.status})`);
return response.json();
const observations: RawLatestTemperature[] = await response.json();
return observations.map(observation => ({
...observation,
city: substituteToStation.get(observation.city) ?? observation.city as FaktiskaStation,
}));
};
const [latest, { refetch }] = createResource(fetchLatest);