Add Ambient station primary source toggle; swap location name to station

When configured, a new "Use as primary source" toggle appears in Settings
under Ambient Weather Station (defaults on). When on, the location header
shows the station name and "Ambient Weather Station" subtitle instead of the
city; the hero badge is hidden as redundant. Toggling off restores the city
name immediately and re-shows the hero badge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Nate EmmertandClaude Sonnet 4.6 committed 2026-08-19 12:13:00 -04:00
1 parent 2d2e36d9fa
commit 9620c1b0cd
2 files changed
+59 -6

No files matched your search

+52 -6
View File
@@ -302,6 +302,7 @@ const STORAGE_KEYS = {
pwsUrl: 'weather.pwsUrl', pwsUrl: 'weather.pwsUrl',
ambientApiKey: 'weather.ambientApiKey', ambientApiKey: 'weather.ambientApiKey',
ambientAppKey: 'weather.ambientAppKey', ambientAppKey: 'weather.ambientAppKey',
ambientUseStation: 'weather.ambientUseStation',
alertIdsSeen: 'weather.alertIdsSeen', alertIdsSeen: 'weather.alertIdsSeen',
}; };
@@ -348,6 +349,7 @@ const state = {
pwsUrl: localStorage.getItem(STORAGE_KEYS.pwsUrl) || '', pwsUrl: localStorage.getItem(STORAGE_KEYS.pwsUrl) || '',
ambientApiKey: localStorage.getItem(STORAGE_KEYS.ambientApiKey) || '', ambientApiKey: localStorage.getItem(STORAGE_KEYS.ambientApiKey) || '',
ambientAppKey: localStorage.getItem(STORAGE_KEYS.ambientAppKey) || '', ambientAppKey: localStorage.getItem(STORAGE_KEYS.ambientAppKey) || '',
ambientUseStation: localStorage.getItem(STORAGE_KEYS.ambientUseStation) !== 'false',
ambientDevice: null, ambientDevice: null,
pushSub: null, pushSub: null,
hourlyExtended: false, hourlyExtended: false,
@@ -2696,6 +2698,8 @@ if (ambientSaveBtn) {
}).catch(() => {}); }).catch(() => {});
const stationName = devices?.[0]?.info?.name || devices?.[0]?.macAddress || 'station'; const stationName = devices?.[0]?.info?.name || devices?.[0]?.macAddress || 'station';
if (ambientStatusEl) { ambientStatusEl.textContent = `✓ Connected to ${stationName} — saved for all devices`; show(ambientStatusEl); } if (ambientStatusEl) { ambientStatusEl.textContent = `✓ Connected to ${stationName} — saved for all devices`; show(ambientStatusEl); }
const useRow = document.getElementById('ambient-use-row');
if (useRow) useRow.style.display = '';
fetchAmbientStation(); fetchAmbientStation();
} else { } else {
const { error } = await res.json().catch(() => ({})); const { error } = await res.json().catch(() => ({}));
@@ -2714,8 +2718,46 @@ fetch('/api/ambient-config').then(r => r.json()).then(({ configured }) => {
if (ambientStatusEl) { ambientStatusEl.textContent = '✓ Keys configured on server'; show(ambientStatusEl); } if (ambientStatusEl) { ambientStatusEl.textContent = '✓ Keys configured on server'; show(ambientStatusEl); }
fetchAmbientStation(); fetchAmbientStation();
} }
if (configured || state.ambientApiKey) {
const useRow = document.getElementById('ambient-use-row');
if (useRow) useRow.style.display = '';
}
}).catch(() => {}); }).catch(() => {});
// ── Ambient "use as primary source" toggle ────────────────────────────────────
const ambientUseToggle = document.getElementById('ambient-use-toggle');
if (ambientUseToggle) {
ambientUseToggle.checked = state.ambientUseStation;
ambientUseToggle.addEventListener('change', () => {
state.ambientUseStation = ambientUseToggle.checked;
localStorage.setItem(STORAGE_KEYS.ambientUseStation, state.ambientUseStation);
if (state.ambientUseStation) {
// Re-apply station overlay immediately
if (state.ambientDevice) applyStationOverlay(state.ambientDevice);
} else {
// Restore location name from current city
if (state.currentCity) {
const locNameEl = document.getElementById('loc-name');
const locSubEl = document.getElementById('loc-sub');
if (locNameEl) locNameEl.textContent = state.currentCity.name;
if (locSubEl) locSubEl.textContent = [state.currentCity.admin1, state.currentCity.country].filter(Boolean).join(', ');
}
// Show station badge so user knows station is still fetching but not overriding
if (state.ambientDevice) {
const badge = document.getElementById('station-badge');
const badgeName = document.getElementById('station-badge-name');
if (badge) { if (badgeName) badgeName.textContent = state.ambientDevice.info?.name || 'My Station'; show(badge); }
}
}
});
}
// Show toggle row if keys are already saved locally
if (state.ambientApiKey && state.ambientAppKey) {
const useRow = document.getElementById('ambient-use-row');
if (useRow) useRow.style.display = '';
}
const pwsUrlInput = document.getElementById('pws-url-input'); const pwsUrlInput = document.getElementById('pws-url-input');
const pwsSaveBtn = document.getElementById('pws-save-btn'); const pwsSaveBtn = document.getElementById('pws-save-btn');
const pwsStatusEl = document.getElementById('pws-status'); const pwsStatusEl = document.getElementById('pws-status');
@@ -2879,6 +2921,7 @@ async function fetchAmbientStation() {
function applyStationOverlay(device) { function applyStationOverlay(device) {
if (!device) return; if (!device) return;
if (!state.ambientUseStation) return;
const data = device.lastData || {}; const data = device.lastData || {};
if (!data.dateutc || Date.now() - data.dateutc > 15 * 60 * 1000) return; // stale > 15 min if (!data.dateutc || Date.now() - data.dateutc > 15 * 60 * 1000) return; // stale > 15 min
@@ -2948,13 +2991,16 @@ function applyStationOverlay(device) {
peekEl.textContent = `· ${fS(data.windspeedmph)} ${speedUnit()} ${compassDir(data.winddir || 0)} · ${data.humidity ?? '--'}% humidity`; peekEl.textContent = `· ${fS(data.windspeedmph)} ${speedUnit()} ${compassDir(data.winddir || 0)} · ${data.humidity ?? '--'}% humidity`;
} }
// Station badge // Replace location name with station name
const stationName = device.info?.name || device.macAddress || 'My Station';
const locNameEl = document.getElementById('loc-name');
const locSubEl = document.getElementById('loc-sub');
if (locNameEl) locNameEl.textContent = stationName;
if (locSubEl) locSubEl.textContent = 'Ambient Weather Station';
// Hide the hero badge (redundant — location header now identifies the station)
const badge = document.getElementById('station-badge'); const badge = document.getElementById('station-badge');
const badgeName = document.getElementById('station-badge-name'); if (badge) hide(badge);
if (badge) {
if (badgeName) badgeName.textContent = device.info?.name || 'My Station';
show(badge);
}
} }
function renderAmbientStation(device) { function renderAmbientStation(device) {
+7
View File
@@ -601,6 +601,13 @@
<p class="settings-help">From ambientweather.net → Account → API Keys. Keys are stored locally in your browser.</p> <p class="settings-help">From ambientweather.net → Account → API Keys. Keys are stored locally in your browser.</p>
<p id="ambient-status" class="settings-help hidden"></p> <p id="ambient-status" class="settings-help hidden"></p>
</div> </div>
<div class="settings-row" id="ambient-use-row" style="display:none">
<span class="settings-label">Use as primary source</span>
<label class="switch-toggle">
<input id="ambient-use-toggle" type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
<div class="settings-section-title">Personal Weather Station</div> <div class="settings-section-title">Personal Weather Station</div>
<div class="settings-row settings-row--block"> <div class="settings-row settings-row--block">