Skip to content

Fix/propagation solar index display#865

Merged
accius merged 5 commits intoaccius:Stagingfrom
ceotjoe:fix/propagation-solar-index-display
Apr 3, 2026
Merged

Fix/propagation solar index display#865
accius merged 5 commits intoaccius:Stagingfrom
ceotjoe:fix/propagation-solar-index-display

Conversation

@ceotjoe
Copy link
Copy Markdown
Collaborator

@ceotjoe ceotjoe commented Apr 2, 2026

What does this PR do?

Summary

Fixes several issues (reported in #859) with solar index display across the header banner and propagation/band-conditions panel, all triggered by two upstream NOAA API changes that went unnoticed.

  • K always showed -- or 0 — NOAA changed noaa-planetary-k-index.json and the forecast endpoint from an array-of-arrays format to an array-of-objects format. The old parsers read d[0]/d[1] on each row; with objects those return undefinedNaN0 (or 2 in the propagation route's hardcoded fallback). Fixed in all three independent places that fetched this endpoint: space-weather.js, propagation.js, and the browser-side useSpaceWeather hook.

  • SFI showed 112 in the panel footer instead of 140f107_cm_flux.json is not chronologically sorted; the last element in the array was a February reading rather than the current one. getSolarData() was blindly taking data[last]. Fixed by reducing over the array for the entry with the highest time_tag. The SFI history chart in space-weather.js was also sorting incorrectly for the same reason.

  • K showed -- when Kp = 0 — The server used || null when resolving kp.current from history, so a legitimately quiet geomagnetic day (Kp = 0) caused the value to be stored as null and rendered as --. Also fixed || '--'?? '--' on all numeric index display sites (Header, SpaceWeatherPanel, ClassicLayout) per project zero-value rules.

  • Band conditions panel could silently show indefinitely stale N0NBH data — When hamqsl.com was unreachable the error fallback returned cached data without updating the cache timestamp, so every subsequent retry failed and kept serving the same arbitrarily old data. Added a 4-hour maximum stale TTL (503 beyond that) and a ⚠ stale (Nm) badge in the BandConditions and PropagationPanel headers when fallback data is being served.

Changed files

File Change
server/routes/space-weather.js NOAA Kp object-format parser; SFI history sort; ?? null zero-value fixes; N0NBH max-stale TTL + fetchedAt/stale fields
server/routes/propagation.js NOAA Kp object-format parser; SFI latest-entry fix via max(time_tag)
src/hooks/useSpaceWeather.js NOAA Kp object-format parser (d.Kp for new format)
src/hooks/useBandConditions.js Expose fetchedAt and stale through extras
src/components/Header.jsx ||?? for SFI fallback chain
src/components/SpaceWeatherPanel.jsx ||?? for SFI and K-index display
src/components/BandConditionsPanel.jsx Accept extras prop; show stale badge
src/components/PropagationPanel.jsx Show stale badge in bands view header
src/layouts/ClassicLayout.jsx ||?? for SFI (×3) and A-index; stale badge on inline band conditions header

Test plan

  • Confirm header banner shows current K and SFI matching N0NBH / WWV
  • Confirm propagation panel footer shows the same SFI and K as the header
  • Verify K = 0 displays as 0 rather than -- during a geomagnetically quiet period
  • Simulate N0NBH unavailability: confirm stale badge appears and data older than 4 h returns 503
  • Hard-refresh after server restart and confirm all panels agree

Type of change

  • Bug fix
  • New feature
  • Performance improvement
  • Refactor / code cleanup
  • Documentation
  • Translation
  • Map layer plugin

Checklist

  • App loads without console errors
  • Tested in Dark, Light, and Retro themes
  • Responsive at different screen sizes (desktop + mobile)
  • If touching server.js: caches have TTLs and size caps (we serve 2,000+ concurrent users)
  • If adding an API route: includes caching and error handling
  • If adding a panel: wired into Modern, Classic, and Dockable layouts
  • No hardcoded colors — uses CSS variables (var(--accent-cyan), etc.)
  • No .bak, .old, console.log debug lines, or test scripts included

ceotjoe and others added 4 commits April 3, 2026 00:23
…le N0NBH data

Two bugs reported in propagation display:

1. Kp index (and SSN/SFI fallback) treated numeric zero as absent because the
   server used || null when resolving the current value from history.  A quiet
   geomagnetic day (Kp=0) caused kp.current to be set to null, which propagated
   to the header and layout displays as '--'.  Fixed by switching to ?? null /
   ?? '--' throughout (server route + Header, SpaceWeatherPanel, ClassicLayout,
   useSpaceWeather).  Also tightened the !result.sfi.current / !result.ssn.current
   guards to == null so a genuine zero is never treated as missing.

2. When hamqsl.com (N0NBH) was temporarily unreachable the server returned stale
   cached data indefinitely.  The error path never updated the cache timestamp so
   every subsequent request re-tried, failed, and served the same old data with no
   age bound.  Added N0NBH_MAX_STALE_TTL (4 h): beyond that the endpoint returns
   503 rather than misleading clients.  Normal and error-fallback responses now
   include fetchedAt and stale:true when serving fallback data.  useBandConditions
   passes these through extras; BandConditionsPanel and PropagationPanel show a
   stale badge in their headers when N0NBH data could not be refreshed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NOAA changed noaa-planetary-k-index.json and noaa-planetary-k-index-forecast.json
from array-of-arrays to array-of-objects.  The old parser read d[0]/d[1] on each
row; with objects those are undefined, so parseFloat(undefined) goes to NaN then
0 for every entry, making kp.current always 0 regardless of actual conditions.

Both the server /api/solar-indices handler and the browser-side useSpaceWeather
hook detect the format (Array.isArray check) and read the correct field (d.Kp for
history, d.kp for forecast) in object format, with fallback to old array indexing.

Guard history values with Number.isFinite() instead of bare || 0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…arser

getSolarData() in propagation.js fetched noaa-planetary-k-index.json
independently and parsed it with the old array-of-arrays accessor d[n][1].
NOAA now returns objects, so d[last][1] was undefined, parseInt gave NaN,
and the NaN || 2 fallback permanently locked kIndex at 2 — matching neither
the actual conditions nor the value shown in the header.

Apply the same format-detection fix (Array.isArray check, read d.Kp for
object format) used in the space-weather route.  Switch to parseFloat so
fractional Kp values (e.g. 4.67) are preserved rather than truncated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…test entry

NOAA's f107_cm_flux.json array does not guarantee chronological order; the
last element in the array can be months old (observed: last entry was
2026-02-20 with flux=112 while the actual current value from 2026-04-02
was flux=140 at array index 0).

getSolarData() in propagation.js was using data[last].flux and therefore
reporting stale SFI to the panel footer.  Fix: reduce over the array to
find the entry with the maximum time_tag.

space-weather.js was building the SFI history chart with data.slice(-30)
on the unsorted array, giving a chart with out-of-order and non-recent
readings.  Fix: sort a copy by time_tag before slicing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ceotjoe
Copy link
Copy Markdown
Collaborator Author

ceotjoe commented Apr 2, 2026

@accius please check if these fixes are fine. Values are displayed correctly now from my perspective. But I don't want to break something by accident. :-)

The N0NBH stale-data badge added in the previous commit had hardcoded
English strings.  Add band.conditions.stale.label and
band.conditions.stale.tooltip keys to all 16 language files and
replace the hardcoded literals in BandConditionsPanel, PropagationPanel,
and ClassicLayout with t() calls using {{mins}} interpolation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alanhargreaves
Copy link
Copy Markdown
Collaborator

We've had people in FB asking about the kIndex not displaying. Looks like they changed the data format. Jörg addresses this in this PR.

@accius accius merged commit 51ebafb into accius:Staging Apr 3, 2026
4 checks passed
@ceotjoe ceotjoe mentioned this pull request Apr 3, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants