Small tweaks

This commit is contained in:
fraxle
2026-06-11 23:31:24 +01:00
parent 2608f93483
commit 5a95b875c2
7 changed files with 49 additions and 106 deletions
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File
File diff suppressed because one or more lines are too long
+33 -5
View File
@@ -12,20 +12,48 @@
// ------------------------------------------------------------------------
export function checkStargazing(rows) {
// Great stargazing: mostly clear night hours with low cloud
// Great stargazing: mostly clear night hours with low cloud.
// Split night into contiguous runs (pre-dawn vs post-dusk) and evaluate
// each independently so a cloudy evening doesn't suppress a clear morning
// (or vice versa), and so the icon is pinned to only the clear hours.
const nightRows = rows.filter(r => r.elev < -5);
if (nightRows.length < 3) return null;
const avgCloud = nightRows.reduce((s, r) => s + r.cc, 0) / nightRows.length;
if (avgCloud > 30) return null;
// Build contiguous runs — a gap > 2 h means we've crossed daytime.
const runs = [];
let cur = [nightRows[0]];
for (let i = 1; i < nightRows.length; i++) {
const dtDiff = (new Date(nightRows[i].iso) - new Date(nightRows[i - 1].iso)) / 3600000;
if (dtDiff <= 2) { cur.push(nightRows[i]); }
else { runs.push(cur); cur = [nightRows[i]]; }
}
runs.push(cur);
// Evaluate each run; among those passing ≤30% avg cloud prefer the evening
// run (actionable for tonight) then fall back to whichever is clearest.
let bestRun = null, bestAvg = Infinity;
for (const run of runs) {
if (run.length < 2) continue;
const avg = run.reduce((s, r) => s + r.cc, 0) / run.length;
if (avg > 30) continue;
const isEvening = parseInt(run[0].iso.slice(11, 13), 10) >= 12;
if (!bestRun || (isEvening && parseInt(bestRun[0].iso.slice(11, 13), 10) < 12) || avg < bestAvg) {
bestRun = run; bestAvg = avg;
}
}
if (!bestRun) return null;
const isPreDawn = parseInt(bestRun[0].iso.slice(11, 13), 10) < 12;
return {
id: 'stargazing',
emoji: '⭐',
title: 'Great Stargazing Tonight',
message: `Clear skies expected overnight at ${nightRows.length} hours with average ${Math.round(avgCloud)}% cloud — ideal conditions for stargazing.`,
title: isPreDawn ? 'Great Stargazing Overnight' : 'Great Stargazing Tonight',
message: `Clear skies expected for ${bestRun.length} hours overnight with average ${Math.round(bestAvg)}% cloud — ideal conditions for stargazing.`,
color: '#080e1a',
textColor: '#c8dcff',
type: 'weather',
nightOnly: true,
isoRange: [bestRun[0].iso, bestRun[bestRun.length - 1].iso],
};
}