mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 03:14:00 +00:00
fix(weather): keep absent observations unknown instead of reporting clear skies
This commit is contained in:
1 parent
6dd4d0156f
commit
c86c1a4cce
4 files changed
+48
-2
No files matched your search
@@ -15,6 +15,8 @@
|
|||||||
the five borough cores load and `CCTV_NYC_MAX_SOURCES` changes the cap. The catalog-wide ceiling is
|
the five borough cores load and `CCTV_NYC_MAX_SOURCES` changes the cap. The catalog-wide ceiling is
|
||||||
unchanged; extra cameras share it round-robin with the other packs.
|
unchanged; extra cameras share it round-robin with the other packs.
|
||||||
|
|
||||||
|
- Weather records keep missing conditions unknown and refuse summaries without a measured temperature.
|
||||||
|
|
||||||
- Treat explicitly current, complete empty vessel coverage as a successful update,
|
- Treat explicitly current, complete empty vessel coverage as a successful update,
|
||||||
clearing obsolete contacts while retaining stale or incomplete snapshots.
|
clearing obsolete contacts while retaining stale or incomplete snapshots.
|
||||||
|
|
||||||
|
|||||||
@@ -5310,3 +5310,8 @@ datacenters, dams and the Nepal locator retain that shared credit while displaye
|
|||||||
|
|
||||||
Military fragments stitch by source identity. Different mapped parcels merge only
|
Military fragments stitch by source identity. Different mapped parcels merge only
|
||||||
when their footprints touch or contain one another, never across a seam tolerance gap.
|
when their footprints touch or contain one another, never across a seam tolerance gap.
|
||||||
|
|
||||||
|
|
||||||
|
### fix(weather): keep absent observations unknown instead of reporting clear skies
|
||||||
|
|
||||||
|
Refuse absent or boolean primary temperatures and keep absent/boolean weather codes explicitly CONDITIONS UNKNOWN while retaining valid numeric strings and real zero observations.
|
||||||
@@ -90,9 +90,22 @@ export function normalizeRegionalArticles(payload, limit = MAX_ARTICLES) {
|
|||||||
/** Normalize Open-Meteo current conditions into a small source-stamped record. */
|
/** Normalize Open-Meteo current conditions into a small source-stamped record. */
|
||||||
export function normalizeRegionalWeather(payload) {
|
export function normalizeRegionalWeather(payload) {
|
||||||
const current = payload?.current;
|
const current = payload?.current;
|
||||||
if (!current || !Number.isFinite(Number(current.temperature_2m))) return null;
|
if (
|
||||||
|
!current ||
|
||||||
|
current.temperature_2m == null ||
|
||||||
|
typeof current.temperature_2m === 'boolean' ||
|
||||||
|
(typeof current.temperature_2m === 'string' &&
|
||||||
|
!current.temperature_2m.trim()) ||
|
||||||
|
!Number.isFinite(Number(current.temperature_2m))
|
||||||
|
)
|
||||||
|
return null;
|
||||||
const numberOrNull = (value) => {
|
const numberOrNull = (value) => {
|
||||||
if (value === null || value === undefined || value === '') return null;
|
if (
|
||||||
|
value == null ||
|
||||||
|
typeof value === 'boolean' ||
|
||||||
|
(typeof value === 'string' && !value.trim())
|
||||||
|
)
|
||||||
|
return null;
|
||||||
return Number.isFinite(Number(value)) ? Number(value) : null;
|
return Number.isFinite(Number(value)) ? Number(value) : null;
|
||||||
};
|
};
|
||||||
// Open-Meteo reports zone-naive timestamps ("2026-08-17T00:15") that are UTC,
|
// Open-Meteo reports zone-naive timestamps ("2026-08-17T00:15") that are UTC,
|
||||||
@@ -119,6 +132,12 @@ export function normalizeRegionalWeather(payload) {
|
|||||||
|
|
||||||
/** Translate the WMO weather code used by Open-Meteo into concise cockpit copy. */
|
/** Translate the WMO weather code used by Open-Meteo into concise cockpit copy. */
|
||||||
export function weatherCodeLabel(code) {
|
export function weatherCodeLabel(code) {
|
||||||
|
if (
|
||||||
|
code == null ||
|
||||||
|
typeof code === 'boolean' ||
|
||||||
|
(typeof code === 'string' && !code.trim())
|
||||||
|
)
|
||||||
|
return 'CONDITIONS UNKNOWN';
|
||||||
const value = Number(code);
|
const value = Number(code);
|
||||||
if (!Number.isFinite(value)) return 'CONDITIONS UNKNOWN';
|
if (!Number.isFinite(value)) return 'CONDITIONS UNKNOWN';
|
||||||
if (value === 0) return 'CLEAR';
|
if (value === 0) return 'CLEAR';
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { normalizeRegionalWeather, weatherCodeLabel } from './regionalModel.js';
|
||||||
|
test('missing weather observations never assert clear conditions', () => {
|
||||||
|
for (const value of [null, undefined, '', ' ', false, true]) {
|
||||||
|
assert.equal(weatherCodeLabel(value), 'CONDITIONS UNKNOWN');
|
||||||
|
assert.equal(
|
||||||
|
normalizeRegionalWeather({ current: { temperature_2m: value } }),
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assert.equal(weatherCodeLabel(0), 'CLEAR');
|
||||||
|
assert.equal(weatherCodeLabel('0'), 'CLEAR');
|
||||||
|
const record = normalizeRegionalWeather({
|
||||||
|
current: { temperature_2m: 0, weather_code: null, wind_speed_10m: false },
|
||||||
|
});
|
||||||
|
assert.equal(record.temperatureC, 0);
|
||||||
|
assert.equal(record.weatherCode, null);
|
||||||
|
assert.equal(record.windKph, null);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user