Show an explicit error when no forecast is available

The Weather Compensation hint text only ever showed the forecast peak
when the fetch succeeded — a failure (bad location, wrong Met Office
subscription, etc.) just silently showed nothing, which is exactly what
happened debugging this live. Now shows a clear red hint pointing at the
two things most likely wrong (Integrations config, backend logs) once
the initial status fetch has resolved and come back empty.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-08-25 11:28:39 +00:00
parent 0321f0fc80
commit e7a8153990

View file

@ -35,6 +35,7 @@ export default function Settings() {
const [weatherPeakC, setWeatherPeakC] = useState<number | null>(null) const [weatherPeakC, setWeatherPeakC] = useState<number | null>(null)
const [weatherTier, setWeatherTier] = useState<string | null>(null) const [weatherTier, setWeatherTier] = useState<string | null>(null)
const [weatherLoaded, setWeatherLoaded] = useState(false)
const [publicAreaName, setPublicAreaName] = useState('') const [publicAreaName, setPublicAreaName] = useState('')
const [creatingZone, setCreatingZone] = useState(false) const [creatingZone, setCreatingZone] = useState(false)
@ -61,7 +62,10 @@ export default function Settings() {
setDefaults({ ...DEFAULT_HVAC_TEMPLATE, ...cfg.hvac_defaults, ac_occupied_tiers: cfg.hvac_defaults?.ac_occupied_tiers ?? DEFAULT_HVAC_TEMPLATE.ac_occupied_tiers }) setDefaults({ ...DEFAULT_HVAC_TEMPLATE, ...cfg.hvac_defaults, ac_occupied_tiers: cfg.hvac_defaults?.ac_occupied_tiers ?? DEFAULT_HVAC_TEMPLATE.ac_occupied_tiers })
}).catch(() => {}) }).catch(() => {})
fetchMqttStatus().then(s => { setMqttConnected(s.connected); setMqttNote(s.note) }).catch(() => {}) fetchMqttStatus().then(s => { setMqttConnected(s.connected); setMqttNote(s.note) }).catch(() => {})
fetchStatus().then(s => { setWeatherPeakC(s.weather_peak_c); setWeatherTier(s.weather_tier) }).catch(() => {}) fetchStatus()
.then(s => { setWeatherPeakC(s.weather_peak_c); setWeatherTier(s.weather_tier) })
.catch(() => {})
.finally(() => setWeatherLoaded(true))
}, []) }, [])
function toggleExcluded(siteId: string) { function toggleExcluded(siteId: string) {
@ -348,6 +352,13 @@ export default function Settings() {
<> Today's forecast peak: <strong>{weatherPeakC}°C</strong>{weatherTier ? <> — currently in the <strong>{weatherTier}</strong> tier</> : ' — below every tier'}.</> <> Today's forecast peak: <strong>{weatherPeakC}°C</strong>{weatherTier ? <> — currently in the <strong>{weatherTier}</strong> tier</> : ' — below every tier'}.</>
)} )}
</p> </p>
{weatherLoaded && weatherPeakC == null && (
<p className="field-hint" style={{ marginBottom: 10, color: 'var(--danger)' }}>
No forecast available right now — check Hotel Location and Met Office DataHub under Settings →
Integrations are saved correctly (both need a Test to pass), or check hvac-backend's logs for
a "[weather]" line explaining why.
</p>
)}
<div className="table-wrap" style={{ marginBottom: 24 }}> <div className="table-wrap" style={{ marginBottom: 24 }}>
<table className="data"> <table className="data">
<thead><tr><th>Tier</th><th>If peak above (°C)</th><th>On/Off</th><th>Mode</th><th>Setpoint (°C)</th><th>Fan speed</th></tr></thead> <thead><tr><th>Tier</th><th>If peak above (°C)</th><th>On/Off</th><th>Mode</th><th>Setpoint (°C)</th><th>Fan speed</th></tr></thead>