feat(gateway): added first implement of the Gateway (MQTT, Influx, REST)

Signed-off-by: Klagarge <remi@heredero.ch>
This commit is contained in:
2025-04-14 22:39:47 +02:00
parent d33a6a1d02
commit e6ef490314
14 changed files with 928 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
package main
import (
"errors"
"fmt"
_ "github.com/eclipse/paho.mqtt.golang"
"github.com/gin-gonic/gin"
"github.com/labstack/gommon/log"
"golang.org/x/net/context"
"net/http"
"os"
)
// swagger:model
// @Description Example response for Garage Door status
type GarageDoorExample struct {
// example: true
IsClosed bool `json:"IsClosed"`
// example: false
IsDownButtonPressed bool `json:"IsDownButtonPressed"`
// example: false
IsIRSensor bool `json:"IsIRSensor"`
// example: false
IsOpen bool `json:"IsOpen"`
// example: false
IsUpButtonPressed bool `json:"IsUpButtonPressed"`
}
// @Summary Request Influx data
// @Description Request data from InfluxDB for a specific device in a room
// @Tags request
// @Accept json
// @Produce json
// @Security BasicAuth
// @Param room query string true "Room name" example(Garage)
// @Param device query string true "Device name" example(Door)
// @Success 200 {object} GarageDoorExample "Returns a map of field names to their latest values."
// @Failure 500 {object} gin.H
// @Router /raclette [get]
func (gh *Gateway) requestInflux(c *gin.Context) error {
// Get the user from the authenticated context
user := c.MustGet(gin.AuthUserKey).(string)
// Get room and device from the query parameters
room, ret := c.GetQuery("room")
if !ret {
return errors.New(`no room found`)
}
device, ret := c.GetQuery("device")
if !ret {
return errors.New(`no device found`)
}
org := user
bucket := user
queryAPI := gh.influx.QueryAPI(org)
MEASUREMENT_NAME, ok := os.LookupEnv("MEASUREMENT_NAME")
if !ok {
log.Error("MEASUREMENT_NAME not set, using default value: softweng")
MEASUREMENT_NAME = "softweng"
}
// The Flux query uses a large range (-1000d) and aggregates the latest values.
// This ensures we always get the most recent data, even if the database contains old entries.
query := fmt.Sprintf(`from(bucket: %q)
|> range(start: -1000d)
|> filter(fn: (r) => r["_measurement"] == %q)
|> filter(fn: (r) => r["room"] == %q)
|> filter(fn: (r) => r["device"] == %q)
|> aggregateWindow(every: 1000d, fn: last, createEmpty: false)
`, bucket, MEASUREMENT_NAME, room, device)
results, err := queryAPI.Query(context.Background(), query)
if err != nil {
log.Fatal(err)
}
values := make(map[string]interface{})
for results.Next() {
record := results.Record()
field := record.Field()
value := record.Value()
values[field] = value
fmt.Println(results.Record())
}
if err := results.Err(); err != nil {
log.Fatal(err)
}
c.JSON(http.StatusOK, values)
return nil
}