Add Ambient Weather personal station integration
* Add Ambient Weather personal station integration Fetches live data from the user's Ambient Weather station via their REST API and displays it as a "My Station" card in the conditions tab. - server.js: add /api/ambient endpoint with 60s cache using AMBIENT_API_KEY and AMBIENT_APP_KEY env vars - docker-compose.yml: expose AMBIENT_API_KEY/AMBIENT_APP_KEY env vars - index.html: add collapsible "My Station" drawer to conditions tab showing temp, humidity, wind, gusts, daily rain, pressure, UV, solar radiation, and indoor readings - app.js: add fetchAmbientStation() and renderAmbientStation(), auto-refresh every 60s, peek text summary in drawer header - style.css: station drawer styles - .gitignore: add .env so API keys stay off git Co-Authored-By: Claude <noreply@anthropic.com> * Move Ambient Weather keys to Settings panel Users can now enter their API Key and Application Key directly in the Settings tab under "Ambient Weather Station". Keys are saved to localStorage and sent per-request to the server proxy. - index.html: add API Key + Application Key inputs with Save button - app.js: persist keys in localStorage, populate inputs on load, wire Save button (validates by testing the connection), pass keys as query params in fetchAmbientStation and its auto-refresh loop - server.js: accept apiKey/appKey from query params with env var fallback; cache keyed per-user so multiple callers don't collide --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
b9e6cad190
commit
b9e2b463f5
6 files changed
+303
No files matched your search
@@ -440,6 +440,30 @@ app.get('/api/spc/reports', async (_req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// ── Ambient Weather personal station ─────────────────────────────────────────
|
||||
const ambientCaches = new Map(); // keyed by apiKey so each user's cache is independent
|
||||
app.get('/api/ambient', async (req, res) => {
|
||||
const apiKey = req.query.apiKey || process.env.AMBIENT_API_KEY;
|
||||
const appKey = req.query.appKey || process.env.AMBIENT_APP_KEY;
|
||||
if (!apiKey || !appKey) return res.status(503).json({ error: 'Ambient Weather keys not configured' });
|
||||
|
||||
const cacheKey = apiKey;
|
||||
const cached = ambientCaches.get(cacheKey);
|
||||
if (cached && Date.now() - cached.at < 60 * 1000) return res.json(cached.data);
|
||||
|
||||
try {
|
||||
const url = `https://rt.ambientweather.net/v1/devices?apiKey=${encodeURIComponent(apiKey)}&applicationKey=${encodeURIComponent(appKey)}`;
|
||||
const r = await fetchWithRetry(url, { attempts: 2, timeoutMs: 10000, retryDelayMs: 500 });
|
||||
const devices = await r.json();
|
||||
ambientCaches.set(cacheKey, { data: devices, at: Date.now() });
|
||||
res.json(devices);
|
||||
} catch (e) {
|
||||
console.error('Ambient Weather fetch error:', e.message);
|
||||
if (cached) return res.json(cached.data);
|
||||
res.status(502).json({ error: 'Ambient Weather fetch failed' });
|
||||
}
|
||||
});
|
||||
|
||||
// ── Personal weather station proxy ────────────────────────────────────────────
|
||||
app.get('/api/pws', async (req, res) => {
|
||||
const { url } = req.query;
|
||||
|
||||
Reference in new issue
Block a user