diff --git a/server.js b/server.js index 5901c5b..21cb89d 100644 --- a/server.js +++ b/server.js @@ -1218,30 +1218,43 @@ app.get('/api/history', (req, res) => { break; } - // Calculate time modifiers using offset in seconds - let durationSec; - if (range === 'week') durationSec = 7 * 24 * 3600; - else if (range === 'month') durationSec = 30 * 24 * 3600; - else durationSec = 24 * 3600; // day + // Calculate absolute start/end times (in seconds) + const nowMs = Date.now(); + let startTsSec, endTsSec; - const endOffsetSec = off * durationSec; - const startOffsetSec = (off + 1) * durationSec; + if (range === 'today') { + // align to midnight local time + const d = new Date(nowMs); + d.setHours(0, 0, 0, 0); + const midnightMs = d.getTime(); - const endMod = `-${endOffsetSec} seconds`; - const startMod = `-${startOffsetSec} seconds`; + // "1 Tag" = 24h aligned to midnight + startTsSec = (midnightMs / 1000) - (off * 24 * 3600); + endTsSec = startTsSec + (24 * 3600); + } else { + // Rolling window + let durationSec; + if (range === 'week') durationSec = 7 * 24 * 3600; + else if (range === 'month') durationSec = 30 * 24 * 3600; + else durationSec = 24 * 3600; // day + + const endMs = nowMs - (off * durationSec * 1000); + const startMs = endMs - (durationSec * 1000); + + startTsSec = Math.floor(startMs / 1000); + endTsSec = Math.floor(endMs / 1000); + } - // Select raw data - // Select raw data const stmt = db.prepare(` SELECT strftime('%s', timestamp) as ts, temp_c, humidity, fan_speed FROM readings WHERE dev_name = ? AND port = ? - AND timestamp >= datetime('now', ?) - AND timestamp < datetime('now', ?) + AND timestamp >= datetime(?, 'unixepoch') + AND timestamp < datetime(?, 'unixepoch') ORDER BY timestamp ASC `); - const rows = stmt.all(devName, parseInt(port, 10), startMod, endMod); + const rows = stmt.all(devName, parseInt(port, 10), startTsSec, endTsSec); if (rows.length === 0) return res.json({ start: 0, step: bucketSize, temps: [], hums: [], levels: [] }); @@ -1320,27 +1333,38 @@ app.get('/api/outputs/history', (req, res) => { const { range, offset = 0 } = req.query; const off = parseInt(offset, 10) || 0; - // Calculate duration in seconds - let durationSec; - if (range === 'week') durationSec = 7 * 24 * 3600; - else if (range === 'month') durationSec = 30 * 24 * 3600; - else durationSec = 24 * 3600; // day + // Calculate absolute start/end times (in seconds) + const nowMs = Date.now(); + let startTsSec, endTsSec; - const endOffsetSec = off * durationSec; - const startOffsetSec = (off + 1) * durationSec; + if (range === 'today') { + const d = new Date(nowMs); + d.setHours(0, 0, 0, 0); + const midnightMs = d.getTime(); + startTsSec = (midnightMs / 1000) - (off * 24 * 3600); + endTsSec = startTsSec + (24 * 3600); + } else { + let durationSec; + if (range === 'week') durationSec = 7 * 24 * 3600; + else if (range === 'month') durationSec = 30 * 24 * 3600; + else durationSec = 24 * 3600; // day - const endMod = `-${endOffsetSec} seconds`; - const startMod = `-${startOffsetSec} seconds`; + const endMs = nowMs - (off * durationSec * 1000); + const startMs = endMs - (durationSec * 1000); + + startTsSec = Math.floor(startMs / 1000); + endTsSec = Math.floor(endMs / 1000); + } const stmt = db.prepare(` SELECT timestamp, dev_name, port, state, level FROM output_log - WHERE timestamp >= datetime('now', ?) - AND timestamp < datetime('now', ?) + WHERE timestamp >= datetime(?, 'unixepoch') + AND timestamp < datetime(?, 'unixepoch') ORDER BY timestamp ASC `); - const rows = stmt.all(startMod, endMod); + const rows = stmt.all(startTsSec, endTsSec); // Compress: Group by "Dev:Port" -> [[ts, state, level], ...] const compressed = {}; diff --git a/src/client/Dashboard.js b/src/client/Dashboard.js index a6c6ca1..0dd8d88 100644 --- a/src/client/Dashboard.js +++ b/src/client/Dashboard.js @@ -28,9 +28,19 @@ class Dashboard extends Component { const { range, offset } = this.state; const nowMs = Date.now(); - const durationSec = (range === 'week' ? 7 * 24 * 3600 : (range === 'month' ? 30 * 24 * 3600 : 24 * 3600)); - const endMs = nowMs - (offset * durationSec * 1000); - const startMs = endMs - (durationSec * 1000); + let startMs, endMs; + + if (range === 'today') { + const d = new Date(nowMs); + d.setHours(0, 0, 0, 0); + const midnightMs = d.getTime(); + startMs = midnightMs - (offset * 24 * 3600 * 1000); + endMs = startMs + (24 * 3600 * 1000); + } else { + const durationSec = (range === 'week' ? 7 * 24 * 3600 : (range === 'month' ? 30 * 24 * 3600 : 24 * 3600)); + endMs = nowMs - (offset * durationSec * 1000); + startMs = endMs - (durationSec * 1000); + } const dateOpts = { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }; const dateRangeLabel = `${new Date(startMs).toLocaleString([], dateOpts)} - ${new Date(endMs).toLocaleString([], dateOpts)}`; @@ -71,6 +81,12 @@ class Dashboard extends Component { > {t('dashboard.hours24')} +