const router = require('express').Router(); const { queryAll, query, hset } = require('../store/redis'); const { connectedSensors } = require('../ws/handler'); /** * GET /sessions — Lista tutte le sessioni dei sensori con metadata e rules versions */ router.get('/', async (req, res) => { try { const keys = await queryAll('sensors'); const sessions = {}; for (const key of keys) { const name = key.replace('sensors:', ''); const info = await query(name, 'sensors'); sessions[name] = { name, connectedAt: info.timestamp || null, session: info.session || null, sessionLabel: info.sessionLabel || info.session || null, status: info.status || 'unknown', rules: { weather: info.rules_weather || null, data: info.rules_data || null, logs: info.rules_logs || null, } }; } res.json(sessions); } catch (err) { console.error('Error fetching sessions', err); res.status(500).json({ error: 'internal server error' }); } }); /** * GET /sessions/pending — Lista token di connessione pendenti */ router.get('/pending', async (req, res) => { try { const keys = await queryAll('sensors_pending'); res.json(keys); } catch (err) { console.error('Error fetching pending tokens', err); res.status(500).json({ error: `Error fetching pending tokens, ${err}` }); } }); /** * GET /sessions/connected — Lista sensori attualmente connessi */ router.get('/connected', async (req, res) => { try { const keys = await queryAll('sensor'); const connected = []; for (const key of keys) { const name = key.replace('sensor:', ''); const info = await query(name, 'sensor'); if (info.status === 'connected') { connected.push({ name, connectedAt: info.timestamp }); } } res.json(connected); } catch (err) { console.error('Error fetching connected sensors', err); res.status(500).json({ error: `Error fetching connected sensors, ${err}` }); } }); /** * GET /sessions/connected/:id — Verifica se un sensore specifico è connesso */ router.get('/connected/:id', async (req, res) => { const { id } = req.params; try { const info = await query(id, 'sensor'); if (!info || info.status !== 'connected') { return res.status(404).json({ error: 'sensor not connected' }); } res.json({ name: id, connectedAt: info.timestamp }); } catch (err) { console.error('Error fetching sensor connection status', err); res.status(500).json({ error: `Error fetching sensor connection status, ${err}` }); } }); /** * POST /sessions/:id/label — Cambia il label della sessione per un sensore connesso. * Non interrompe il flusso dati. I nuovi punti InfluxDB avranno il nuovo tag. */ router.post('/:id/label', async (req, res) => { const { id } = req.params; const { label } = req.body; if (!label || typeof label !== 'string' || label.trim().length === 0) { return res.status(400).json({ error: 'label is required' }); } const trimmedLabel = label.trim(); // Trova il WS client connesso const ws = connectedSensors.get(id); if (!ws) { return res.status(404).json({ error: 'sensor not connected' }); } // Aggiorna in memoria (effetto immediato sui prossimi punti InfluxDB) ws.sessionLabel = trimmedLabel; // Aggiorna in Redis per persistenza try { await hset(`sensors:${id}`, 'sessionLabel', trimmedLabel); } catch (err) { console.error('Error updating session label in Redis', err); } console.log(`[${id}] Session label changed to: ${trimmedLabel}`); res.json({ status: 'ok', label: trimmedLabel }); }); module.exports = router;