From 5198784c373115492c35b1a4ca84729ab51c9f85 Mon Sep 17 00:00:00 2001 From: Klagarge Date: Sat, 30 May 2026 00:23:25 +0200 Subject: [PATCH] refactor(db): adapt SQL query for 5 min average Signed-off-by: Klagarge --- db/src/rest/rest.go | 68 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/db/src/rest/rest.go b/db/src/rest/rest.go index 4d7e803..ff69d59 100644 --- a/db/src/rest/rest.go +++ b/db/src/rest/rest.go @@ -88,11 +88,11 @@ func (g *RestGateway) setupRoutes() { // buildNodeFilter builds a SQL WHERE clause fragment matching any of the given node IDs. func buildNodeFilter(nodes []string) string { - parts := make([]string, len(nodes)) + quotedNodes := make([]string, len(nodes)) for i, n := range nodes { - parts[i] = fmt.Sprintf(`"node" = '%s'`, n) + quotedNodes[i] = fmt.Sprintf("'%s'", n) } - return "(" + strings.Join(parts, " OR ") + ")" + return fmt.Sprintf(`"node" IN (%s)`, strings.Join(quotedNodes, ", ")) } // GET /api/v1/battery @@ -113,9 +113,15 @@ func (g *RestGateway) getBattery(c *gin.Context) { } nodeFilter := buildNodeFilter(allNodes) - query := fmt.Sprintf( - `SELECT "node", "battery" FROM "%s" WHERE %s AND time > now() - INTERVAL '30 minutes' ORDER BY time DESC`, - g.measurementName, nodeFilter, + query := fmt.Sprintf(` + SELECT + "node", + "battery" + FROM "%s" + WHERE %s + AND time > now() - INTERVAL '30 minutes' + ORDER BY time DESC + `, g.measurementName, nodeFilter, ) it, err := g.influxGateway.Query(context.Background(), query) @@ -200,9 +206,20 @@ func (g *RestGateway) getExportCSV(c *gin.Context) { return } - query := fmt.Sprintf( - `SELECT time, co2_ppm, temp, battery, humidity, window_open FROM "%s" WHERE time >= '%s' AND time <= '%s' AND "node" = '%s' ORDER BY time ASC`, - g.measurementName, from, to, node, + query := fmt.Sprintf(` + SELECT + time, + co2_ppm, + temp, + battery, + humidity, + window_open + FROM "%s" + WHERE time >= '%s' + AND time <= '%s' + AND "node" = '%s' + ORDER BY time ASC + `, g.measurementName, from, to, node, ) it, err := g.influxGateway.Query(context.Background(), query) @@ -323,8 +340,22 @@ func (g *RestGateway) getRoomCurrent(c *gin.Context) { } nodeFilter := buildNodeFilter(nodes) - // Get the last record for the specific room by matching node IDs - query := fmt.Sprintf(`SELECT * FROM "%s" WHERE %s AND time > now() - INTERVAL '1 days' ORDER BY time DESC LIMIT 1`, g.measurementName, nodeFilter) + // Get the last record for the specific room by matching node IDs, aggregated by 5m intervals + query := fmt.Sprintf(` + SELECT + date_bin(INTERVAL '5 minutes', time) AS time, + AVG(co2_ppm) AS co2_ppm, + AVG(temp) AS temp, + AVG(humidity) AS humidity, + MAX(window_open) AS window_open + FROM "%s" + WHERE time > now() - INTERVAL '1 day' + AND %s + GROUP BY date_bin(INTERVAL '5 minutes', time) + ORDER BY time DESC + LIMIT 1 + `, g.measurementName, nodeFilter, + ) // Using context.Background() as seen in working snippet it, err := g.influxGateway.Query(context.Background(), query) @@ -369,7 +400,20 @@ func (g *RestGateway) getRoomHistory(c *gin.Context) { } nodeFilter := buildNodeFilter(nodes) - query := fmt.Sprintf(`SELECT * FROM "%s" WHERE %s AND time > now() - INTERVAL '%s' ORDER BY time ASC`, g.measurementName, nodeFilter, window) + query := fmt.Sprintf(` + SELECT + date_bin(INTERVAL '5 minutes', time) AS time, + AVG(co2_ppm) AS co2_ppm, + AVG(temp) AS temp, + AVG(humidity) AS humidity, + MAX(window_open) AS window_open + FROM "%s" + WHERE time > now() - INTERVAL '%s' + AND %s + GROUP BY date_bin(INTERVAL '5 minutes', time) + ORDER BY time ASC + `, g.measurementName, window, nodeFilter, + ) // Using context.Background() as seen in working snippet it, err := g.influxGateway.Query(context.Background(), query)