New Logo
Updated cache system now 15/30mins but scope updates every minute
Font update
This commit is contained in:
fraxle
2026-06-04 14:07:34 +01:00
parent efc9b0eed9
commit ede875f0d0
100 changed files with 231 additions and 106 deletions
+56 -19
View File
@@ -116,11 +116,41 @@ export function checkHeatSpike(rows) {
// wet + calm → rain icon (🌧️)
// windy + wet → storm icon (🌩️), and the wind/rain icons are suppressed
// for that hour so a single hour never shows two icons.
const GUST_BLUSTERY = 25 / 2.237; // m/s (= 25 mph) - matches the table's gust highlight
const GUST_STORM = 20; // m/s ≈ 45 mph - storm-force
const GUST_BLUSTERY = 25 / 2.237; // m/s (= 25 mph) - Beaufort Force 6 threshold
const GUST_STORM = 20; // m/s ≈ 45 mph - Beaufort Force 8+ threshold
const PRECIP_WET = 5; // mm/h - meaningful rain
const PRECIP_HEAVY = 10; // mm/h - heavy rain
// Beaufort scale lookup - force number and name from gust speed in m/s
function beaufortForce(ms) {
const mph = ms * 2.237;
if (mph >= 73) return { force: 12, name: 'Hurricane Force' };
if (mph >= 64) return { force: 11, name: 'Violent Storm' };
if (mph >= 55) return { force: 10, name: 'Storm Force' };
if (mph >= 47) return { force: 9, name: 'Strong Gale' };
if (mph >= 39) return { force: 8, name: 'Gale' };
if (mph >= 32) return { force: 7, name: 'Near Gale' };
return { force: 6, name: 'Strong Breeze' };
}
const BEAUFORT_DESC = {
6: 'Large branches in motion; umbrellas used with difficulty.',
7: 'Whole trees in motion; inconvenience felt when walking against the wind.',
8: 'Twigs break off trees and generally impedes progress.',
9: 'Slight structural damage possible — chimney pots and slates at risk.',
10: 'Trees uprooted; considerable structural damage expected.',
11: 'Very rarely experienced inland; widespread damage expected.',
12: 'Devastating conditions — avoid all outdoor activity.',
};
// Banner colour scales with severity
function windBannerColors(force) {
if (force >= 11) return { color: '#0c1020', textColor: '#c0d8ff' };
if (force >= 9) return { color: '#101828', textColor: '#c0d4f0' };
if (force >= 7) return { color: '#141e2e', textColor: '#c0d0e8' };
return { color: '#1a2030', textColor: '#c0d8f0' };
}
const gustOf = r => r.gust ?? r.va ?? 0;
const precipOf = r => r.precip ?? 0;
const isWindyHour = r => { const g = gustOf(r); return isFinite(g) && g >= GUST_BLUSTERY; };
@@ -135,20 +165,24 @@ export function checkWind(rows) {
const maxGust = Math.max(...affected.map(gustOf).filter(isFinite));
const mph = Math.round(maxGust * 2.237);
const isStorm = maxGust >= GUST_STORM;
const { force, name } = beaufortForce(maxGust);
const desc = BEAUFORT_DESC[force] || '';
const { color, textColor } = windBannerColors(force);
const title = force >= 10 ? `${name} Winds`
: force >= 8 ? `${name} Warning`
: name;
return {
id: 'wind',
emoji: '💨',
title: isStorm ? 'Storm-Force Winds' : 'Blustery Conditions',
message: isStorm
? `Storm-force gusts to ${mph} mph expected — secure loose objects and take care outdoors.`
: `Windy spell — gusts to ${mph} mph at peak. Hold onto hats and secure loose items outdoors.`,
color: '#1a2030',
textColor: '#c0d8f0',
emoji: force >= 10 ? '🌪️' : '💨',
title,
message: `Gusts to ${mph} mph (Beaufort Force ${force}). ${desc}`,
color,
textColor,
type: 'weather',
nightOnly: false,
isoRange, // only show cell icon during the windy hours
isoRange,
};
}
@@ -185,20 +219,23 @@ export function checkStorm(rows) {
const maxGust = Math.max(...affected.map(gustOf).filter(isFinite));
const maxPrecip = Math.max(...affected.map(precipOf).filter(isFinite));
const mph = Math.round(maxGust * 2.237);
const isSevere = maxGust >= GUST_STORM || maxPrecip >= PRECIP_HEAVY;
const { force, name } = beaufortForce(maxGust);
const { color, textColor } = windBannerColors(force);
const title = force >= 10 ? `${name} — Severe Storm`
: force >= 8 ? `${name} with Rain`
: 'Storm Conditions';
return {
id: 'storm',
emoji: '🌩️',
title: isSevere ? 'Severe Storm' : 'Storm Conditions',
message: isSevere
? `Severe storm — driving rain to ${maxPrecip.toFixed(1)} mm/h and gusts to ${mph} mph. Avoid travel if you can.`
: `Stormy spell — wind and rain together, gusts to ${mph} mph with ${maxPrecip.toFixed(1)} mm/h rain. Take care outdoors.`,
color: '#141a26',
textColor: '#c0d0e8',
title,
message: `Gusts to ${mph} mph (Beaufort Force ${force}) with ${maxPrecip.toFixed(1)} mm/h rain. ${BEAUFORT_DESC[force] || ''} Take care outdoors.`,
color,
textColor,
type: 'weather',
nightOnly: false,
isoRange, // only show cell icon during the stormy hours
isoRange,
};
}