From dde59e3865d2c2a7128a24276df15d5770129fb5 Mon Sep 17 00:00:00 2001 From: Nate Emmert Date: Thu, 15 Oct 2026 15:16:33 -0400 Subject: [PATCH] Station tab: explain what the station is - 'What is this station?' card: a personal weather station measuring real conditions on site (not a forecast), how it differs from the Now tab, update cadence, what Live/Offline mean - Lists the instruments this station actually reports (temp/humidity, wind, rain, pressure, sun, indoor), using the station's real name - Open for new visitors, remembers once closed; empty state and Now-tab badge/tab hover explain it too Co-Authored-By: Claude Sonnet 5.5 --- app/public/index.html | 4 ++-- app/public/station-live.css | 15 +++++++++++++ app/public/station-live.js | 42 ++++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/app/public/index.html b/app/public/index.html index 37cc1d2..554fac3 100644 --- a/app/public/index.html +++ b/app/public/index.html @@ -35,7 +35,7 @@ ☁︎NeCloud @@ -86,7 +86,7 @@
- +
--°F
diff --git a/app/public/station-live.css b/app/public/station-live.css index 5367aa9..c370cbc 100644 --- a/app/public/station-live.css +++ b/app/public/station-live.css @@ -75,3 +75,18 @@ .sl-empty button { margin-top: 1rem; font: inherit; font-weight: 600; padding: .6rem 1.2rem; min-height: 44px; border-radius: 10px; border: 1px solid var(--sl-accent); background: transparent; color: var(--sl-accent); cursor: pointer; } .sl-link { display: inline-flex; align-items: center; gap: .3rem; font-size: .78rem; font-weight: 600; color: var(--sl-muted); text-decoration: none; padding: .32rem .75rem; border: 1px solid var(--sl-border); border-radius: 8px; } .sl-link:hover { color: var(--sl-accent); border-color: var(--sl-accent); } + +/* What is this station? */ +.sl-about { background: var(--sl-surface); border: 1px solid var(--sl-border); border-radius: 14px; margin-bottom: 0.9rem; overflow: hidden; } +.sl-about summary { display: flex; align-items: center; gap: 0.6rem; min-height: 48px; padding: 0 1rem; cursor: pointer; list-style: none; font-size: 0.9rem; font-weight: 600; color: var(--sl-text); } +.sl-about summary::-webkit-details-marker { display: none; } +.sl-about-ico { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: color-mix(in srgb, var(--sl-accent) 18%, transparent); color: var(--sl-accent); font-size: 0.95rem; } +.sl-about-chev { margin-left: auto; color: var(--sl-muted); font-size: 1.2rem; transition: transform .2s; } +.sl-about[open] .sl-about-chev { transform: rotate(90deg); } +.sl-about-body { padding: 0 1rem 1rem; font-size: 0.88rem; line-height: 1.55; color: var(--sl-text); } +.sl-about-body p { margin: 0 0 0.6rem; } +.sl-about-h { font-size: 0.62rem; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; color: var(--sl-muted); margin: 0.9rem 0 0.35rem !important; } +.sl-sensors { margin: 0 0 0.3rem; padding: 0; list-style: none; display: grid; gap: 0.4rem; } +.sl-sensors li { padding-left: 0; color: var(--sl-text); } +.sl-about-foot { margin-top: 0.8rem !important; padding-top: 0.7rem; border-top: 1px solid var(--sl-border); font-size: 0.8rem; color: var(--sl-muted); } +.sl-about-foot a { color: var(--sl-accent); font-weight: 600; } diff --git a/app/public/station-live.js b/app/public/station-live.js index c63789b..114bbb8 100644 --- a/app/public/station-live.js +++ b/app/public/station-live.js @@ -52,6 +52,22 @@ const SHELL = ` Live
+
+ ⓘWhat is this station?› +
+

This station is a personal weather station: real instruments on the owner's property that measure the weather right here, right now. These numbers are measurements, not a forecast or a computer model.

+

What it measures

+
  • Waiting for the first reading…
+

How it fits with the rest of the app

+
    +
  • Now shows a forecast model for the city you picked. Station shows what one spot is actually measuring.
  • +
  • When you see 📡 Your station on the Now tab, its temperature, wind and rain come from this station.
  • +
  • It reports about every minute or two. Live means the last reading is under 15 minutes old; Offline means older.
  • +
  • Because it's one spot, it can differ a little from the airport or the forecast, and that's normal.
  • +
+

History, records and charts, plus a side-by-side with the official National Weather Service station, are on the Station Dashboard (sign-in required).

+
+
@@ -109,10 +125,21 @@ const setAll = (sel, v) => root.querySelectorAll(sel).forEach((el) => { el.textC let shellReady = false; let lastDir = null; + +// "What is this station?" starts open for new visitors and stays closed once dismissed +function initAbout() { + const d = $('sl-about'); + if (!d) return; + let closed = false; try { closed = localStorage.getItem('stationAboutClosed') === '1'; } catch {} + d.open = !closed; + d.addEventListener('toggle', () => { try { localStorage.setItem('stationAboutClosed', d.open ? '0' : '1'); } catch {} }); +} + function ensureShell() { if (shellReady) return; root.innerHTML = SHELL; shellReady = true; + initAbout(); drawCompass(null, null); } @@ -178,6 +205,19 @@ window.renderStationTab = function renderStationTab(device) { const name = (typeof state !== 'undefined' && state.stationName) || device.info?.name || 'My Station'; set('sl-name', name); + + // Describe the instruments this particular station really has + set('sl-about-name', name); + const has = (...k) => k.some((f) => d[f] != null); + const sensors = [ + has('tempf', 'humidity') && '🌡 Temperature & humidity: a shaded outdoor sensor', + has('windspeedmph', 'winddir', 'windgustmph') && '💨 Wind: speed, gusts and direction (anemometer and wind vane)', + has('dailyrainin', 'rainratein') && '🌧 Rain: a rain gauge that tips with each bit of rain', + has('baromrelin') && '🧭 Pressure: a barometer (falling pressure often means weather is coming)', + has('uv', 'solarradiation') && '☀️ Sun: UV and solar-radiation sensors', + has('tempinf', 'humidityin') && '🏠 Indoor: a sensor inside the house', + ].filter(Boolean); + if (sensors.length) $('sl-sensors').innerHTML = sensors.map((x) => `
  • ${x}
  • `).join(''); const fresh = d.dateutc && Date.now() - d.dateutc < 15 * 60 * 1000; const live = $('sl-live'); live.classList.toggle('stale', !fresh); @@ -230,7 +270,7 @@ window.stationTabMessage = function (kind, detail) { return; } if (kind === 'unconfigured') { - showMessage('No station connected', 'Add your Ambient Weather API keys in Settings to see live readings from your own station here.'); + showMessage('No station connected', 'This tab shows live readings from a personal weather station (a real device on someone\'s property that measures conditions on the spot, not a forecast). Add your Ambient Weather API keys in Settings to connect yours.'); } else { showMessage('Station unavailable', detail || 'Could not reach your station right now. It will keep retrying.'); }