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')}
+