meteoswiss-mcp 2.3.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/data/meteoswiss-content-data.js +75 -37
- package/dist/data/meteoswiss-content-data.js.map +1 -1
- package/dist/data/meteoswiss-search-data.js +66 -55
- package/dist/data/meteoswiss-search-data.js.map +1 -1
- package/dist/data/meteoswiss-web-components.js +5 -0
- package/dist/data/meteoswiss-web-components.js.map +1 -1
- package/dist/data/ogd-climate-data.js +28 -8
- package/dist/data/ogd-climate-data.js.map +1 -1
- package/dist/data/ogd-current-weather.js +71 -16
- package/dist/data/ogd-current-weather.js.map +1 -1
- package/dist/data/ogd-data-store.js +102 -2
- package/dist/data/ogd-data-store.js.map +1 -1
- package/dist/data/ogd-local-forecast.js +230 -60
- package/dist/data/ogd-local-forecast.js.map +1 -1
- package/dist/data/ogd-nbcn-stations.js +18 -2
- package/dist/data/ogd-nbcn-stations.js.map +1 -1
- package/dist/data/ogd-pollen-data.js +39 -3
- package/dist/data/ogd-pollen-data.js.map +1 -1
- package/dist/data/ogd-smn-stations.js +25 -22
- package/dist/data/ogd-smn-stations.js.map +1 -1
- package/dist/data/ogd-stac-client.js +12 -7
- package/dist/data/ogd-stac-client.js.map +1 -1
- package/dist/data/ogd-station-resolver.js +2 -23
- package/dist/data/ogd-station-resolver.js.map +1 -1
- package/dist/schemas/meteoswiss-fetch.js +22 -0
- package/dist/schemas/meteoswiss-fetch.js.map +1 -1
- package/dist/schemas/meteoswiss-search.js +24 -9
- package/dist/schemas/meteoswiss-search.js.map +1 -1
- package/dist/schemas/ogd-climate-data.js +56 -1
- package/dist/schemas/ogd-climate-data.js.map +1 -1
- package/dist/schemas/ogd-current-weather.js +59 -1
- package/dist/schemas/ogd-current-weather.js.map +1 -1
- package/dist/schemas/ogd-local-forecast.js +73 -1
- package/dist/schemas/ogd-local-forecast.js.map +1 -1
- package/dist/schemas/ogd-pollen-data.js +39 -0
- package/dist/schemas/ogd-pollen-data.js.map +1 -1
- package/dist/schemas/ogd-station-list.js +21 -1
- package/dist/schemas/ogd-station-list.js.map +1 -1
- package/dist/server.js +112 -29
- package/dist/server.js.map +1 -1
- package/dist/support/environment-validation.js +18 -0
- package/dist/support/environment-validation.js.map +1 -1
- package/dist/support/geocode.js +23 -5
- package/dist/support/geocode.js.map +1 -1
- package/dist/support/http-cache.js +24 -36
- package/dist/support/http-cache.js.map +1 -1
- package/dist/support/http-communication.js +137 -33
- package/dist/support/http-communication.js.map +1 -1
- package/dist/support/name-matcher.js +28 -0
- package/dist/support/name-matcher.js.map +1 -1
- package/dist/support/ogd-csv-parser.js +7 -2
- package/dist/support/ogd-csv-parser.js.map +1 -1
- package/dist/support/ogd-timestamp.js +37 -0
- package/dist/support/ogd-timestamp.js.map +1 -0
- package/dist/support/round-measurements.js +86 -0
- package/dist/support/round-measurements.js.map +1 -0
- package/dist/support/weather-icons.js +12 -3
- package/dist/support/weather-icons.js.map +1 -1
- package/dist/tools/meteoswiss-fetch.js.map +1 -1
- package/dist/transports/streamable-http.js +47 -19
- package/dist/transports/streamable-http.js.map +1 -1
- package/package.json +11 -7
- package/src/views/homepage/overview.md +5 -1
- package/src/views/homepage/tools.md +20 -3
- package/dist/support/validation-errors.js +0 -38
- package/dist/support/validation-errors.js.map +0 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { getLatin1CsvData } from './ogd-data-store.js';
|
|
6
6
|
import { resolveNbcnStation, findNearestNbcnStation } from './ogd-nbcn-stations.js';
|
|
7
7
|
import { parseNumeric } from '../support/ogd-csv-parser.js';
|
|
8
|
+
import { roundOptional } from '../support/round-measurements.js';
|
|
8
9
|
import { debugData } from '../support/logging.js';
|
|
9
10
|
import { SOURCE_ATTRIBUTION } from '../schemas/ogd-shared.js';
|
|
10
11
|
/**
|
|
@@ -43,19 +44,19 @@ function mapMeasurement(row) {
|
|
|
43
44
|
return {
|
|
44
45
|
date: parseTimestamp(row.reference_timestamp ?? ''),
|
|
45
46
|
// Temperature (available at all resolutions)
|
|
46
|
-
temperature_mean: parseNumeric(row.ths200d0 ?? row.ths200m0 ?? row.ths200y0 ?? null) ?? undefined,
|
|
47
|
-
temperature_max: parseNumeric(row.ths200dx ?? row.ths2dymx ?? row.ths2dyyx ?? null) ?? undefined,
|
|
48
|
-
temperature_min: parseNumeric(row.ths200dn ?? row.ths2dymn ?? row.ths2dyyn ?? null) ?? undefined,
|
|
47
|
+
temperature_mean: roundOptional(parseNumeric(row.ths200d0 ?? row.ths200m0 ?? row.ths200y0 ?? null) ?? undefined, '°C'),
|
|
48
|
+
temperature_max: roundOptional(parseNumeric(row.ths200dx ?? row.ths2dymx ?? row.ths2dyyx ?? null) ?? undefined, '°C'),
|
|
49
|
+
temperature_min: roundOptional(parseNumeric(row.ths200dn ?? row.ths2dymn ?? row.ths2dyyn ?? null) ?? undefined, '°C'),
|
|
49
50
|
// Precipitation (monthly/yearly)
|
|
50
|
-
precipitation: parseNumeric(row.rhs150m0 ?? row.rhs150y0 ?? null) ?? undefined,
|
|
51
|
+
precipitation: roundOptional(parseNumeric(row.rhs150m0 ?? row.rhs150y0 ?? null) ?? undefined, 'mm'),
|
|
51
52
|
// Sunshine (monthly/yearly)
|
|
52
|
-
sunshine_duration_min: parseNumeric(row.shs000m0 ?? row.shs000y0 ?? null) ?? undefined,
|
|
53
|
+
sunshine_duration_min: roundOptional(parseNumeric(row.shs000m0 ?? row.shs000y0 ?? null) ?? undefined, 'min'),
|
|
53
54
|
// Radiation (monthly/yearly)
|
|
54
|
-
radiation_w_m2: parseNumeric(row.ghs000m0 ?? row.ghs000y0 ?? null) ?? undefined,
|
|
55
|
+
radiation_w_m2: roundOptional(parseNumeric(row.ghs000m0 ?? row.ghs000y0 ?? null) ?? undefined, 'W/m²'),
|
|
55
56
|
// Wind (monthly/yearly)
|
|
56
|
-
wind_speed_m_s: parseNumeric(row.fhs010m0 ?? row.fhs010y0 ?? null) ?? undefined,
|
|
57
|
+
wind_speed_m_s: roundOptional(parseNumeric(row.fhs010m0 ?? row.fhs010y0 ?? null) ?? undefined, 'm/s'),
|
|
57
58
|
// Pressure (monthly/yearly)
|
|
58
|
-
pressure_hpa: parseNumeric(row.phsstam0 ?? row.phsstay0 ?? null) ?? undefined,
|
|
59
|
+
pressure_hpa: roundOptional(parseNumeric(row.phsstam0 ?? row.phsstay0 ?? null) ?? undefined, 'hPa'),
|
|
59
60
|
// Day counts (monthly/yearly)
|
|
60
61
|
frost_days: parseNumeric(row.ths00nm0 ?? row.ths00ny0 ?? null) ?? undefined,
|
|
61
62
|
summer_days: parseNumeric(row.ths25xm0 ?? row.ths25xy0 ?? null) ?? undefined,
|
|
@@ -122,6 +123,24 @@ export async function getClimateData(params) {
|
|
|
122
123
|
const limit = params.limit ?? 30;
|
|
123
124
|
const sliced = filtered.slice(-limit);
|
|
124
125
|
const data = sliced.map((row) => stripUndefined(mapMeasurement(row)));
|
|
126
|
+
// If a date filter zeroed out the results, tell the caller why instead of
|
|
127
|
+
// returning a bare empty array (issue #110, BUG-5). The most common cause
|
|
128
|
+
// is a daily request predating the `_recent` (~2-year) window; derive the
|
|
129
|
+
// actually-available range from the unfiltered rows so the hint is honest
|
|
130
|
+
// even when the series is empty for other reasons.
|
|
131
|
+
let note;
|
|
132
|
+
if (data.length === 0 && (params.start_date || params.end_date) && rows.length > 0) {
|
|
133
|
+
const firstRow = rows[0];
|
|
134
|
+
const lastRow = rows[rows.length - 1];
|
|
135
|
+
const availableFrom = parseTimestamp(firstRow?.reference_timestamp ?? '');
|
|
136
|
+
const availableTo = parseTimestamp(lastRow?.reference_timestamp ?? '');
|
|
137
|
+
note =
|
|
138
|
+
`No ${resolution} data for the requested date range. ` +
|
|
139
|
+
`This series covers ${availableFrom} to ${availableTo}.` +
|
|
140
|
+
(resolution === 'daily'
|
|
141
|
+
? ' Daily data only covers roughly the last 2 years; use resolution="monthly" or "yearly" for older dates.'
|
|
142
|
+
: '');
|
|
143
|
+
}
|
|
125
144
|
return {
|
|
126
145
|
station: {
|
|
127
146
|
name: station.name,
|
|
@@ -134,6 +153,7 @@ export async function getClimateData(params) {
|
|
|
134
153
|
},
|
|
135
154
|
resolution,
|
|
136
155
|
data,
|
|
156
|
+
...(note ? { note } : {}),
|
|
137
157
|
source: SOURCE_ATTRIBUTION,
|
|
138
158
|
};
|
|
139
159
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ogd-climate-data.js","sourceRoot":"","sources":["../../src/data/ogd-climate-data.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAU9D;;;;GAIG;AACH,MAAM,iBAAiB,GAAsC;IAC3D,KAAK,EAAE,UAAU;IACjB,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF;;GAEG;AACH,SAAS,YAAY,CAAC,OAAoB,EAAE,UAA6B;IACvE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC;IACtF,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,6CAA6C,UAAU,IAAI,SAAS,IAAI,UAAU,IAAI,SAAS,IAAI,MAAM,MAAM,CAAC;AACzH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,EAAU;IAChC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,GAAW;IACjC,OAAO;QACL,IAAI,EAAE,cAAc,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC;QACnD,6CAA6C;QAC7C,gBAAgB,
|
|
1
|
+
{"version":3,"file":"ogd-climate-data.js","sourceRoot":"","sources":["../../src/data/ogd-climate-data.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAU9D;;;;GAIG;AACH,MAAM,iBAAiB,GAAsC;IAC3D,KAAK,EAAE,UAAU;IACjB,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF;;GAEG;AACH,SAAS,YAAY,CAAC,OAAoB,EAAE,UAA6B;IACvE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC;IACtF,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,6CAA6C,UAAU,IAAI,SAAS,IAAI,UAAU,IAAI,SAAS,IAAI,MAAM,MAAM,CAAC;AACzH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,EAAU;IAChC,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,GAAW;IACjC,OAAO;QACL,IAAI,EAAE,cAAc,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC;QACnD,6CAA6C;QAC7C,gBAAgB,EAAE,aAAa,CAC7B,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/E,IAAI,CACL;QACD,eAAe,EAAE,aAAa,CAC5B,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/E,IAAI,CACL;QACD,eAAe,EAAE,aAAa,CAC5B,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/E,IAAI,CACL;QACD,iCAAiC;QACjC,aAAa,EAAE,aAAa,CAC1B,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/D,IAAI,CACL;QACD,4BAA4B;QAC5B,qBAAqB,EAAE,aAAa,CAClC,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/D,KAAK,CACN;QACD,6BAA6B;QAC7B,cAAc,EAAE,aAAa,CAC3B,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/D,MAAM,CACP;QACD,wBAAwB;QACxB,cAAc,EAAE,aAAa,CAC3B,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/D,KAAK,CACN;QACD,4BAA4B;QAC5B,YAAY,EAAE,aAAa,CACzB,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS,EAC/D,KAAK,CACN;QACD,8BAA8B;QAC9B,UAAU,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS;QAC3E,WAAW,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS;QAC5E,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS;QAC1E,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS;QACzE,eAAe,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS;QAChF,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,SAAS;KAC3E,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,CAAqB;IAC3C,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAA4B,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAA4B;IAC/D,IAAI,OAAoB,CAAC;IACzB,IAAI,WAA+B,CAAC;IAEpC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC5F,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACzB,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACjC,SAAS,CAAC,yDAAyD,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAClG,CAAC;SAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnD,SAAS,CAAC,sCAAsC,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC;IAClD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,WAAW,OAAO,CAAC,OAAO,IAAI,SAAS,IAAI,iBAAiB,CAAC,UAAU,CAAC,MAAM,CAAC;IAEhG,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC9D,SAAS,CAAC,wCAAwC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAE3F,uBAAuB;IACvB,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;QAChC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;YAC3D,OAAO,IAAI,IAAI,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC5B,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;YAC3D,OAAO,IAAI,IAAI,GAAG,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,oEAAoE;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;IAEtC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAEtE,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,mDAAmD;IACnD,IAAI,IAAwB,CAAC;IAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnF,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,EAAE,mBAAmB,IAAI,EAAE,CAAC,CAAC;QACvE,IAAI;YACF,MAAM,UAAU,sCAAsC;gBACtD,sBAAsB,aAAa,OAAO,WAAW,GAAG;gBACxD,CAAC,UAAU,KAAK,OAAO;oBACrB,CAAC,CAAC,yGAAyG;oBAC3G,CAAC,CAAC,EAAE,CAAC,CAAC;IACZ,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,YAAY,EAAE,OAAO,CAAC,IAAI;YAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YACnD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW;YACX,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB;QACD,UAAU;QACV,IAAI;QACJ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,EAAE,kBAAkB;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
* Fetches real-time measurements from the consolidated VQHA80.csv.
|
|
4
4
|
*/
|
|
5
5
|
import { getCsvData, getLatin1CsvData } from './ogd-data-store.js';
|
|
6
|
-
import { resolveSmnStation,
|
|
6
|
+
import { resolveSmnStation, loadSmnStations } from './ogd-smn-stations.js';
|
|
7
7
|
import { parseNumeric } from '../support/ogd-csv-parser.js';
|
|
8
|
+
import { roundByUnit } from '../support/round-measurements.js';
|
|
8
9
|
import { reverseGeocodeSwiss } from '../support/reverse-geocode.js';
|
|
9
10
|
import { debugData } from '../support/logging.js';
|
|
10
11
|
import { SOURCE_ATTRIBUTION } from '../schemas/ogd-shared.js';
|
|
12
|
+
import { findNearest } from '../support/haversine.js';
|
|
13
|
+
import { normalizeOgdTimestamp } from '../support/ogd-timestamp.js';
|
|
11
14
|
const REALTIME_CSV_URL = 'https://data.geo.admin.ch/ch.meteoschweiz.messwerte-aktuell/VQHA80.csv';
|
|
12
15
|
/** The 8 stations that have visual observations (OBS) data */
|
|
13
16
|
const OBS_STATIONS = new Set(['ALT', 'BAS', 'CHU', 'GSB', 'JUN', 'SAE', 'SIO', 'SMA']);
|
|
@@ -17,9 +20,19 @@ async function getCachedReverseGeocode(lat, lon, stationAbbr) {
|
|
|
17
20
|
if (reverseGeoCache.has(stationAbbr)) {
|
|
18
21
|
return reverseGeoCache.get(stationAbbr) ?? null;
|
|
19
22
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
try {
|
|
24
|
+
// Cache only resolved outcomes (a hit, or a genuine "no result" null).
|
|
25
|
+
const result = await reverseGeocodeSwiss(lat, lon);
|
|
26
|
+
reverseGeoCache.set(stationAbbr, result);
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// A transient network error is NOT cached, so a later request can retry —
|
|
31
|
+
// otherwise one blip would suppress this station's municipality until restart
|
|
32
|
+
// (FUN-10). municipality is enrichment; canton falls back to metadata.
|
|
33
|
+
debugData('[ogd-weather] Reverse geocode failed for %s (not cached): %O', stationAbbr, error);
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
23
36
|
}
|
|
24
37
|
/**
|
|
25
38
|
* Create a measurement value if the raw data is present.
|
|
@@ -28,7 +41,42 @@ function measurement(row, key, unit) {
|
|
|
28
41
|
const val = parseNumeric(row[key] ?? null);
|
|
29
42
|
if (val === null)
|
|
30
43
|
return undefined;
|
|
31
|
-
return { value: val, unit };
|
|
44
|
+
return { value: roundByUnit(val, unit), unit };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Find the nearest station to a coordinate that actually reports a core
|
|
48
|
+
* measurement (temperature). Some stations are geometrically close to a
|
|
49
|
+
* point but report only sunshine/radiation or precipitation (e.g. Uetliberg
|
|
50
|
+
* near Zürich Kreis 3) — this skips past them to the nearest station with
|
|
51
|
+
* temperature data, rather than returning a mostly-empty response for the
|
|
52
|
+
* strictly-nearest point (issue #110, DECISION-4). Only used on the
|
|
53
|
+
* coordinate-lookup path; name-based resolution is unaffected. Falls back to
|
|
54
|
+
* the plain geometric nearest station if no station in VQHA80 reports
|
|
55
|
+
* temperature (should not happen in practice).
|
|
56
|
+
*
|
|
57
|
+
* Returns the selected station's own VQHA80 row alongside the station so the
|
|
58
|
+
* caller can read its measurements directly instead of re-fetching and
|
|
59
|
+
* re-parsing the same CSV (PR #116 Copilot review). Only the one matching
|
|
60
|
+
* row is retained — not the full parsed table — to avoid holding the large
|
|
61
|
+
* VQHA80 row set alive for the rest of the request.
|
|
62
|
+
*/
|
|
63
|
+
async function findNearestStationWithTemperature(lat, lon) {
|
|
64
|
+
const [stations, rows] = await Promise.all([
|
|
65
|
+
loadSmnStations(),
|
|
66
|
+
getCsvData(REALTIME_CSV_URL, 'measurements/VQHA80.csv', 'realtime'),
|
|
67
|
+
]);
|
|
68
|
+
const abbrsWithTemperature = new Set(rows
|
|
69
|
+
.filter((row) => parseNumeric(row.tre200s0 ?? null) !== null)
|
|
70
|
+
.map((row) => row['Station/Location']));
|
|
71
|
+
const capableStations = stations.filter((s) => abbrsWithTemperature.has(s.abbr));
|
|
72
|
+
const candidates = capableStations.length > 0 ? capableStations : stations;
|
|
73
|
+
const result = findNearest(candidates, (s) => s.lat, (s) => s.lon, lat, lon);
|
|
74
|
+
if (!result) {
|
|
75
|
+
throw new Error('No stations available');
|
|
76
|
+
}
|
|
77
|
+
const station = result.item;
|
|
78
|
+
const row = rows.find((r) => r['Station/Location'] === station.abbr);
|
|
79
|
+
return { station, distance_km: result.distance_km, row };
|
|
32
80
|
}
|
|
33
81
|
/**
|
|
34
82
|
* Fetch current weather measurements for a station.
|
|
@@ -40,26 +88,33 @@ function measurement(row, key, unit) {
|
|
|
40
88
|
export async function getCurrentWeather(params) {
|
|
41
89
|
let station;
|
|
42
90
|
let distance_km;
|
|
91
|
+
let row;
|
|
92
|
+
let geo;
|
|
43
93
|
if (params.coordinates) {
|
|
44
|
-
const result = await
|
|
94
|
+
const result = await findNearestStationWithTemperature(params.coordinates.lat, params.coordinates.lon);
|
|
45
95
|
station = result.station;
|
|
46
96
|
distance_km = result.distance_km;
|
|
47
|
-
debugData('[ogd-weather] Nearest station to coordinates: %s (%.1f km)', station.abbr, distance_km);
|
|
97
|
+
debugData('[ogd-weather] Nearest station with temperature to coordinates: %s (%.1f km)', station.abbr, distance_km);
|
|
98
|
+
// Reuse the row already fetched/parsed by findNearestStationWithTemperature
|
|
99
|
+
// instead of re-fetching and re-parsing the same CSV (PR #116 Copilot review).
|
|
100
|
+
row = result.row;
|
|
101
|
+
geo = await getCachedReverseGeocode(station.lat, station.lon, station.abbr);
|
|
48
102
|
}
|
|
49
103
|
else if (params.station) {
|
|
50
104
|
station = await resolveSmnStation(params.station);
|
|
51
105
|
debugData('[ogd-weather] Resolved station: %s (%s)', station.abbr, station.name);
|
|
106
|
+
const filter = (r) => r['Station/Location'] === station.abbr;
|
|
107
|
+
// Fetch weather data and reverse geocode concurrently (independent operations)
|
|
108
|
+
const [rows, geoResult] = await Promise.all([
|
|
109
|
+
getCsvData(REALTIME_CSV_URL, 'measurements/VQHA80.csv', 'realtime', filter),
|
|
110
|
+
getCachedReverseGeocode(station.lat, station.lon, station.abbr),
|
|
111
|
+
]);
|
|
112
|
+
row = rows[0];
|
|
113
|
+
geo = geoResult;
|
|
52
114
|
}
|
|
53
115
|
else {
|
|
54
116
|
throw new Error('Either "station" or "coordinates" must be provided');
|
|
55
117
|
}
|
|
56
|
-
const filter = (row) => row['Station/Location'] === station.abbr;
|
|
57
|
-
// Fetch weather data and reverse geocode concurrently (independent operations)
|
|
58
|
-
const [rows, geo] = await Promise.all([
|
|
59
|
-
getCsvData(REALTIME_CSV_URL, 'measurements/VQHA80.csv', 'realtime', filter),
|
|
60
|
-
getCachedReverseGeocode(station.lat, station.lon, station.abbr),
|
|
61
|
-
]);
|
|
62
|
-
let row = rows[0];
|
|
63
118
|
// Fallback for precipitation-only stations: VQHA80 does not include them
|
|
64
119
|
if (!row && station.network === 'smn-precip') {
|
|
65
120
|
debugData('[ogd-weather] Station %s is precip-only, fetching per-station CSV', station.abbr);
|
|
@@ -88,7 +143,7 @@ export async function getCurrentWeather(params) {
|
|
|
88
143
|
distance_km,
|
|
89
144
|
network: station.network,
|
|
90
145
|
},
|
|
91
|
-
timestamp: row.Date ?? row.reference_timestamp ?? '',
|
|
146
|
+
timestamp: normalizeOgdTimestamp(row.Date ?? row.reference_timestamp ?? ''),
|
|
92
147
|
measurements: {
|
|
93
148
|
temperature: measurement(row, 'tre200s0', '\u00B0C'),
|
|
94
149
|
humidity: measurement(row, 'ure200s0', '%'),
|
|
@@ -134,7 +189,7 @@ async function fetchVisualObservations(abbr) {
|
|
|
134
189
|
const date = match ? `${match[3]}-${match[2]}-${match[1]}` : ts;
|
|
135
190
|
return {
|
|
136
191
|
date,
|
|
137
|
-
cloud_cover_percent: cloudCover
|
|
192
|
+
cloud_cover_percent: cloudCover === null ? undefined : roundByUnit(cloudCover, '%'),
|
|
138
193
|
is_clear_day: parseFlag(latestRow.nto002d0 ?? null),
|
|
139
194
|
is_overcast_day: parseFlag(latestRow.nto008d0 ?? null),
|
|
140
195
|
has_rain: parseFlag(latestRow.w1p012d0 ?? null),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ogd-current-weather.js","sourceRoot":"","sources":["../../src/data/ogd-current-weather.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"ogd-current-weather.js","sourceRoot":"","sources":["../../src/data/ogd-current-weather.ts"],"names":[],"mappings":"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"}
|
|
@@ -64,6 +64,9 @@ function resolveFixturePath(url) {
|
|
|
64
64
|
'tre200h0',
|
|
65
65
|
'rre150h0',
|
|
66
66
|
'jww003i0',
|
|
67
|
+
'sre000h0',
|
|
68
|
+
'fu3010h0',
|
|
69
|
+
'fu3010h1',
|
|
67
70
|
]) {
|
|
68
71
|
if (url.includes(`.${param}.csv`))
|
|
69
72
|
return path.join(OGD_FIXTURES_ROOT, 'forecasts', `${param}.csv`);
|
|
@@ -89,6 +92,25 @@ export const CACHE_TTL = {
|
|
|
89
92
|
climate: envNumber('OGD_CACHE_TTL_CLIMATE', 604_800_000),
|
|
90
93
|
};
|
|
91
94
|
const CACHE_DIR = process.env.OGD_CACHE_DIR || path.join(os.tmpdir(), 'meteoswiss-ogd');
|
|
95
|
+
/** Total-bytes ceiling for the on-disk cache before LRU eviction kicks in. */
|
|
96
|
+
const CACHE_MAX_BYTES = envNumber('OGD_CACHE_MAX_BYTES', 268_435_456); // 256 MiB
|
|
97
|
+
/**
|
|
98
|
+
* Resolve a cache key to an absolute path and assert it stays under CACHE_DIR.
|
|
99
|
+
*
|
|
100
|
+
* Cache keys are currently built from server-controlled STAC metadata and
|
|
101
|
+
* validated enums (not raw user input), so this is defense-in-depth: it makes a
|
|
102
|
+
* future `..`/absolute-path key a hard failure instead of a path traversal.
|
|
103
|
+
*
|
|
104
|
+
* @throws {Error} If the resolved path escapes CACHE_DIR
|
|
105
|
+
*/
|
|
106
|
+
export function resolveCachePath(cacheKey) {
|
|
107
|
+
const resolved = path.resolve(CACHE_DIR, cacheKey);
|
|
108
|
+
const root = path.resolve(CACHE_DIR);
|
|
109
|
+
if (resolved !== root && !resolved.startsWith(root + path.sep)) {
|
|
110
|
+
throw new Error(`Unsafe cache key escapes cache directory: ${cacheKey}`);
|
|
111
|
+
}
|
|
112
|
+
return resolved;
|
|
113
|
+
}
|
|
92
114
|
/**
|
|
93
115
|
* Write data to disk cache atomically (write to .tmp then rename).
|
|
94
116
|
*/
|
|
@@ -99,6 +121,82 @@ async function writeToDiskCache(cachePath, data) {
|
|
|
99
121
|
await fs.writeFile(tmpPath, data);
|
|
100
122
|
await fs.rename(tmpPath, cachePath);
|
|
101
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Recursively collect regular files under `dir` with their size and mtime.
|
|
126
|
+
* Missing directory → empty list.
|
|
127
|
+
*/
|
|
128
|
+
async function listCacheFiles(dir) {
|
|
129
|
+
const out = [];
|
|
130
|
+
const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => null);
|
|
131
|
+
if (entries === null) {
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
for (const entry of entries) {
|
|
135
|
+
const full = path.join(dir, entry.name);
|
|
136
|
+
if (entry.isDirectory()) {
|
|
137
|
+
out.push(...(await listCacheFiles(full)));
|
|
138
|
+
}
|
|
139
|
+
else if (entry.isFile()) {
|
|
140
|
+
try {
|
|
141
|
+
const stat = await fs.stat(full);
|
|
142
|
+
out.push({
|
|
143
|
+
path: full,
|
|
144
|
+
size: stat.size,
|
|
145
|
+
mtimeMs: stat.mtimeMs,
|
|
146
|
+
isTmp: entry.name.endsWith('.tmp'),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// file vanished between readdir and stat — ignore
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
/** Serializes prune passes so concurrent fetches don't double-evict. */
|
|
157
|
+
let prunePromise = null;
|
|
158
|
+
/**
|
|
159
|
+
* Bound the on-disk cache: delete orphaned `.tmp` files, then evict oldest
|
|
160
|
+
* entries (LRU by mtime) until total size is under CACHE_MAX_BYTES. Best-effort
|
|
161
|
+
* and never throws — a cache-maintenance failure must not fail a data request.
|
|
162
|
+
*/
|
|
163
|
+
async function pruneDiskCache() {
|
|
164
|
+
if (prunePromise)
|
|
165
|
+
return prunePromise;
|
|
166
|
+
prunePromise = (async () => {
|
|
167
|
+
try {
|
|
168
|
+
const files = await listCacheFiles(CACHE_DIR);
|
|
169
|
+
let totalBytes = 0;
|
|
170
|
+
const live = [];
|
|
171
|
+
for (const file of files) {
|
|
172
|
+
if (file.isTmp) {
|
|
173
|
+
await fs.rm(file.path, { force: true });
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
totalBytes += file.size;
|
|
177
|
+
live.push(file);
|
|
178
|
+
}
|
|
179
|
+
if (totalBytes <= CACHE_MAX_BYTES)
|
|
180
|
+
return;
|
|
181
|
+
// Evict oldest-first until under the ceiling.
|
|
182
|
+
live.sort((a, b) => a.mtimeMs - b.mtimeMs);
|
|
183
|
+
for (const file of live) {
|
|
184
|
+
if (totalBytes <= CACHE_MAX_BYTES)
|
|
185
|
+
break;
|
|
186
|
+
await fs.rm(file.path, { force: true });
|
|
187
|
+
totalBytes -= file.size;
|
|
188
|
+
debugData('[ogd-store] Evicted cache file %s (%d bytes)', file.path, file.size);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
debugData('[ogd-store] Cache prune failed (non-fatal): %O', error);
|
|
193
|
+
}
|
|
194
|
+
finally {
|
|
195
|
+
prunePromise = null;
|
|
196
|
+
}
|
|
197
|
+
})();
|
|
198
|
+
return prunePromise;
|
|
199
|
+
}
|
|
102
200
|
/**
|
|
103
201
|
* Read a cached file, decoding it as UTF-8 text.
|
|
104
202
|
* Returns null if the cache entry is missing or stale.
|
|
@@ -135,7 +233,7 @@ export async function getCsvData(url, cacheKey, tier, filter) {
|
|
|
135
233
|
if (USE_TEST_FIXTURES) {
|
|
136
234
|
throw new Error(`No test fixture for URL: ${url}. Add a mapping in resolveFixturePath.`);
|
|
137
235
|
}
|
|
138
|
-
const cachePath =
|
|
236
|
+
const cachePath = resolveCachePath(cacheKey);
|
|
139
237
|
const ttl = CACHE_TTL[tier];
|
|
140
238
|
const cached = await readCacheUtf8(cachePath, ttl);
|
|
141
239
|
if (cached !== null) {
|
|
@@ -146,6 +244,7 @@ export async function getCsvData(url, cacheKey, tier, filter) {
|
|
|
146
244
|
const text = await fetchWithRetry(url, { useCache: false, timeout: 60_000 });
|
|
147
245
|
await writeToDiskCache(cachePath, text);
|
|
148
246
|
debugData('[ogd-store] Cached %d bytes to %s', text.length, cacheKey);
|
|
247
|
+
void pruneDiskCache();
|
|
149
248
|
return parseCsv(text, filter);
|
|
150
249
|
}
|
|
151
250
|
/**
|
|
@@ -168,7 +267,7 @@ export async function getLatin1CsvData(url, cacheKey, tier, filter) {
|
|
|
168
267
|
if (USE_TEST_FIXTURES) {
|
|
169
268
|
throw new Error(`No test fixture for URL: ${url}. Add a mapping in resolveFixturePath.`);
|
|
170
269
|
}
|
|
171
|
-
const cachePath =
|
|
270
|
+
const cachePath = resolveCachePath(cacheKey);
|
|
172
271
|
const ttl = CACHE_TTL[tier];
|
|
173
272
|
// Cache stores the decoded UTF-8 text
|
|
174
273
|
const cached = await readCacheUtf8(cachePath, ttl);
|
|
@@ -181,6 +280,7 @@ export async function getLatin1CsvData(url, cacheKey, tier, filter) {
|
|
|
181
280
|
const text = LATIN1_DECODER.decode(buffer);
|
|
182
281
|
await writeToDiskCache(cachePath, text);
|
|
183
282
|
debugData('[ogd-store] Cached %d bytes (decoded) to %s', text.length, cacheKey);
|
|
283
|
+
void pruneDiskCache();
|
|
184
284
|
return parseCsv(text, filter);
|
|
185
285
|
}
|
|
186
286
|
//# sourceMappingURL=ogd-data-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ogd-data-store.js","sourceRoot":"","sources":["../../src/data/ogd-data-store.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ogd-data-store.js","sourceRoot":"","sources":["../../src/data/ogd-data-store.ts"],"names":[],"mappings":"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"}
|