feat(gateway): small adaption for softweng project

Signed-off-by: Klagarge <remi@heredero.ch>
This commit is contained in:
2025-04-15 01:03:57 +02:00
parent 0b57f26688
commit f4d088decd
7 changed files with 100 additions and 116 deletions

View File

@@ -12,6 +12,8 @@ services:
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8080:8080" - "8080:8080"
networks:
- kb28_default
environment: environment:
- INFLUXDB_TOKEN=$INFLUXDB_TOKEN - INFLUXDB_TOKEN=$INFLUXDB_TOKEN
- INFLUXDB_ORG=$INFLUXDB_ORG - INFLUXDB_ORG=$INFLUXDB_ORG

View File

@@ -15,7 +15,7 @@ import (
type dataPoints = map[string]interface{} type dataPoints = map[string]interface{}
type updateEvent struct { type updateEvent struct {
State string `json:"state"` //State string `json:"state"`
DataPoints dataPoints `json:"values"` DataPoints dataPoints `json:"values"`
} }

View File

@@ -20,17 +20,22 @@ type Command struct {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Security BasicAuth // @Security BasicAuth
// @Param room query string true "Room name" example(Garage) // @Param user query string true "User name" example(remi)
// @Param device query string true "Device name" example(Door) // @Param room query string true "Room name" example(Bedroom)
// @Param device query string true "Device name" example(DoorSensor)
// @Param command body main.Command true "Command to publish" // @Param command body main.Command true "Command to publish"
// @Success 200 {object} map[string]string "status:ok" // @Success 200 {object} map[string]string "status:ok"
// @Failure 500 {object} gin.H // @Failure 500 {object} gin.H
// @Router /raclette [post] // @Router /raclette [post]
func (gh *Gateway) publishCommand(c *gin.Context) error { func (gh *Gateway) publishCommand(c *gin.Context) error {
// Get the user from the authenticated context // Get the user from the authenticated context
user := c.MustGet(gin.AuthUserKey).(string) //userid := c.MustGet(gin.AuthUserKey).(string)
// Get room and device from the query parameters // Get user, room and device from the query parameters
user, ret := c.GetQuery("user")
if !ret {
return errors.New("no user found")
}
room, ret := c.GetQuery("room") room, ret := c.GetQuery("room")
if !ret { if !ret {
return errors.New(`no room found`) return errors.New(`no room found`)

View File

@@ -11,37 +11,27 @@ import (
"os" "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 // @Summary Request Influx data
// @Description Request data from InfluxDB for a specific device in a room // @Description Request data from InfluxDB for a specific device in a room
// @Tags request // @Tags request
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Security BasicAuth // @Security BasicAuth
// @Param room query string true "Room name" example(Garage) // @Param user query string true "User name" example(remi)
// @Param device query string true "Device name" example(Door) // @Param room query string true "Room name" example(Bedroom)
// @Success 200 {object} GarageDoorExample "Returns a map of field names to their latest values." // @Param device query string true "Device name" example(DoorSensor)
// @Success 200 {object} map[string]interface{} "Returns a map of field names to their latest values."
// @Failure 500 {object} gin.H // @Failure 500 {object} gin.H
// @Router /raclette [get] // @Router /raclette [get]
func (gh *Gateway) requestInflux(c *gin.Context) error { func (gh *Gateway) requestInflux(c *gin.Context) error {
// Get the user from the authenticated context // Get the user from the authenticated context
user := c.MustGet(gin.AuthUserKey).(string) //userId := c.MustGet(gin.AuthUserKey).(string)
// Get room and device from the query parameters // Get room and device from the query parameters
user, ret := c.GetQuery("user")
if !ret {
return errors.New("no user found")
}
room, ret := c.GetQuery("room") room, ret := c.GetQuery("room")
if !ret { if !ret {
return errors.New(`no room found`) return errors.New(`no room found`)
@@ -51,24 +41,35 @@ func (gh *Gateway) requestInflux(c *gin.Context) error {
return errors.New(`no device found`) return errors.New(`no device found`)
} }
org := user // Get env variables and set default values if not set
bucket := user INFLUXDB_ORG, ok := os.LookupEnv("INFLUXDB_ORG")
if !ok {
log.Error("INFLUXDB_ORG not set, using default value: raclette")
INFLUXDB_ORG = "raclette"
}
queryAPI := gh.influx.QueryAPI(org) INFLUXDB_BUCKET, ok := os.LookupEnv("INFLUXDB_BUCKET")
if !ok {
log.Error("INFLUXDB_BUCKET not set, using default value: raclette")
INFLUXDB_BUCKET = "raclette"
}
queryAPI := gh.influx.QueryAPI(INFLUXDB_ORG)
MEASUREMENT_NAME, ok := os.LookupEnv("MEASUREMENT_NAME") MEASUREMENT_NAME, ok := os.LookupEnv("MEASUREMENT_NAME")
if !ok { if !ok {
log.Error("MEASUREMENT_NAME not set, using default value: softweng") log.Error("MEASUREMENT_NAME not set, using default value: softweng")
MEASUREMENT_NAME = "softweng" MEASUREMENT_NAME = "THC"
} }
// The Flux query uses a large range (-1000d) and aggregates the latest values. // 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. // This ensures we always get the most recent data, even if the database contains old entries.
query := fmt.Sprintf(`from(bucket: %q) query := fmt.Sprintf(`from(bucket: %q)
|> range(start: -1000d) |> range(start: -1000d)
|> filter(fn: (r) => r["_measurement"] == %q) |> filter(fn: (r) => r["_measurement"] == %q)
|> filter(fn: (r) => r["user"] == %q)
|> filter(fn: (r) => r["room"] == %q) |> filter(fn: (r) => r["room"] == %q)
|> filter(fn: (r) => r["device"] == %q) |> filter(fn: (r) => r["device"] == %q)
|> aggregateWindow(every: 1000d, fn: last, createEmpty: false) //|> aggregateWindow(every: 1000d, fn: mean, createEmpty: false)
`, bucket, MEASUREMENT_NAME, room, device) `, INFLUXDB_BUCKET, MEASUREMENT_NAME, user, room, device)
results, err := queryAPI.Query(context.Background(), query) results, err := queryAPI.Query(context.Background(), query)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View File

@@ -59,7 +59,15 @@ const docTemplate = `{
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"example": "Garage", "example": "remi",
"description": "User name",
"name": "user",
"in": "query",
"required": true
},
{
"type": "string",
"example": "Bedroom",
"description": "Room name", "description": "Room name",
"name": "room", "name": "room",
"in": "query", "in": "query",
@@ -67,7 +75,7 @@ const docTemplate = `{
}, },
{ {
"type": "string", "type": "string",
"example": "Door", "example": "DoorSensor",
"description": "Device name", "description": "Device name",
"name": "device", "name": "device",
"in": "query", "in": "query",
@@ -78,7 +86,8 @@ const docTemplate = `{
"200": { "200": {
"description": "Returns a map of field names to their latest values.", "description": "Returns a map of field names to their latest values.",
"schema": { "schema": {
"$ref": "#/definitions/main.GarageDoorExample" "type": "object",
"additionalProperties": true
} }
}, },
"500": { "500": {
@@ -109,7 +118,15 @@ const docTemplate = `{
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"example": "Garage", "example": "remi",
"description": "User name",
"name": "user",
"in": "query",
"required": true
},
{
"type": "string",
"example": "Bedroom",
"description": "Room name", "description": "Room name",
"name": "room", "name": "room",
"in": "query", "in": "query",
@@ -117,7 +134,7 @@ const docTemplate = `{
}, },
{ {
"type": "string", "type": "string",
"example": "Door", "example": "DoorSensor",
"description": "Device name", "description": "Device name",
"name": "device", "name": "device",
"in": "query", "in": "query",
@@ -170,32 +187,6 @@ const docTemplate = `{
"example": "UP" "example": "UP"
} }
} }
},
"main.GarageDoorExample": {
"description": "Example response for Garage Door status",
"type": "object",
"properties": {
"IsClosed": {
"description": "example: true",
"type": "boolean"
},
"IsDownButtonPressed": {
"description": "example: false",
"type": "boolean"
},
"IsIRSensor": {
"description": "example: false",
"type": "boolean"
},
"IsOpen": {
"description": "example: false",
"type": "boolean"
},
"IsUpButtonPressed": {
"description": "example: false",
"type": "boolean"
}
}
} }
}, },
"securityDefinitions": { "securityDefinitions": {

View File

@@ -53,7 +53,15 @@
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"example": "Garage", "example": "remi",
"description": "User name",
"name": "user",
"in": "query",
"required": true
},
{
"type": "string",
"example": "Bedroom",
"description": "Room name", "description": "Room name",
"name": "room", "name": "room",
"in": "query", "in": "query",
@@ -61,7 +69,7 @@
}, },
{ {
"type": "string", "type": "string",
"example": "Door", "example": "DoorSensor",
"description": "Device name", "description": "Device name",
"name": "device", "name": "device",
"in": "query", "in": "query",
@@ -72,7 +80,8 @@
"200": { "200": {
"description": "Returns a map of field names to their latest values.", "description": "Returns a map of field names to their latest values.",
"schema": { "schema": {
"$ref": "#/definitions/main.GarageDoorExample" "type": "object",
"additionalProperties": true
} }
}, },
"500": { "500": {
@@ -103,7 +112,15 @@
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"example": "Garage", "example": "remi",
"description": "User name",
"name": "user",
"in": "query",
"required": true
},
{
"type": "string",
"example": "Bedroom",
"description": "Room name", "description": "Room name",
"name": "room", "name": "room",
"in": "query", "in": "query",
@@ -111,7 +128,7 @@
}, },
{ {
"type": "string", "type": "string",
"example": "Door", "example": "DoorSensor",
"description": "Device name", "description": "Device name",
"name": "device", "name": "device",
"in": "query", "in": "query",
@@ -164,32 +181,6 @@
"example": "UP" "example": "UP"
} }
} }
},
"main.GarageDoorExample": {
"description": "Example response for Garage Door status",
"type": "object",
"properties": {
"IsClosed": {
"description": "example: true",
"type": "boolean"
},
"IsDownButtonPressed": {
"description": "example: false",
"type": "boolean"
},
"IsIRSensor": {
"description": "example: false",
"type": "boolean"
},
"IsOpen": {
"description": "example: false",
"type": "boolean"
},
"IsUpButtonPressed": {
"description": "example: false",
"type": "boolean"
}
}
} }
}, },
"securityDefinitions": { "securityDefinitions": {

View File

@@ -12,25 +12,6 @@ definitions:
required: required:
- command - command
type: object type: object
main.GarageDoorExample:
description: Example response for Garage Door status
properties:
IsClosed:
description: 'example: true'
type: boolean
IsDownButtonPressed:
description: 'example: false'
type: boolean
IsIRSensor:
description: 'example: false'
type: boolean
IsOpen:
description: 'example: false'
type: boolean
IsUpButtonPressed:
description: 'example: false'
type: boolean
type: object
host: rest.mse.kb28.ch host: rest.mse.kb28.ch
info: info:
contact: {} contact: {}
@@ -59,14 +40,20 @@ paths:
- application/json - application/json
description: Request data from InfluxDB for a specific device in a room description: Request data from InfluxDB for a specific device in a room
parameters: parameters:
- description: User name
example: remi
in: query
name: user
required: true
type: string
- description: Room name - description: Room name
example: Garage example: Bedroom
in: query in: query
name: room name: room
required: true required: true
type: string type: string
- description: Device name - description: Device name
example: Door example: DoorSensor
in: query in: query
name: device name: device
required: true required: true
@@ -77,7 +64,8 @@ paths:
"200": "200":
description: Returns a map of field names to their latest values. description: Returns a map of field names to their latest values.
schema: schema:
$ref: '#/definitions/main.GarageDoorExample' additionalProperties: true
type: object
"500": "500":
description: Internal Server Error description: Internal Server Error
schema: schema:
@@ -92,14 +80,20 @@ paths:
- application/json - application/json
description: Publish a command to a specific device in a room description: Publish a command to a specific device in a room
parameters: parameters:
- description: User name
example: remi
in: query
name: user
required: true
type: string
- description: Room name - description: Room name
example: Garage example: Bedroom
in: query in: query
name: room name: room
required: true required: true
type: string type: string
- description: Device name - description: Device name
example: Door example: DoorSensor
in: query in: query
name: device name: device
required: true required: true