From 5e9e0cccc35aa3cd5e2e6d7e7e5782e620744198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Z=C3=ADpek?= Date: Mon, 1 Apr 2024 17:26:30 +0200 Subject: [PATCH] Preparations for MQTT button --- basic-sensor-receiver.code-workspace | 1 + server/go.mod | 9 ++++-- server/go.sum | 12 +++++++ server/main.go | 1 + server/routes/mqtt.go | 47 ++++++++++++++++++++++++++++ server/services/mqtt_service.go | 30 ++++++++++++++++++ server/services/services.go | 2 ++ 7 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 server/routes/mqtt.go create mode 100644 server/services/mqtt_service.go diff --git a/basic-sensor-receiver.code-workspace b/basic-sensor-receiver.code-workspace index b6fe676..8ec6987 100644 --- a/basic-sensor-receiver.code-workspace +++ b/basic-sensor-receiver.code-workspace @@ -9,6 +9,7 @@ ], "settings": { "cSpell.words": [ + "MQTT", "sqlx", "tgbotapi" ] diff --git a/server/go.mod b/server/go.mod index df34dac..6858a2f 100644 --- a/server/go.mod +++ b/server/go.mod @@ -10,6 +10,7 @@ require ( ) require ( + github.com/eclipse/paho.mqtt.golang v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect @@ -17,6 +18,7 @@ require ( github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect github.com/goccy/go-json v0.9.10 // indirect github.com/golobby/cast v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect @@ -26,9 +28,10 @@ require ( github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect - golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/server/go.sum b/server/go.sum index 5dfd436..a40d981 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,6 +1,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eclipse/paho.mqtt.golang v1.4.3 h1:2kwcUGn8seMUfWndX0hGbvH8r7crgcJguQNCyp70xik= +github.com/eclipse/paho.mqtt.golang v1.4.3/go.mod h1:CSYvoAlsMkhYOXh/oKyxa8EcBci6dVkLCbo5tTC1RIE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= @@ -28,6 +30,8 @@ github.com/golobby/dotenv v1.3.1 h1:BvQyNuOQITmIXNHpQ/FUG2gZcUGmcGMyODMeUfiKkeU= github.com/golobby/dotenv v1.3.1/go.mod h1:EWUdOzuDlA1g4hdjo++WD37DhNZw33Oce8ryH3liZTQ= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= @@ -82,6 +86,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -90,12 +98,16 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraC golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/server/main.go b/server/main.go index 653a5c6..9159930 100644 --- a/server/main.go +++ b/server/main.go @@ -69,6 +69,7 @@ func main() { loginProtected.PUT("/api/contact-points/:contactPointId", routes.PutContactPoint(server)) loginProtected.DELETE("/api/contact-points/:contactPointId", routes.DeleteContactPoint(server)) loginProtected.POST("/api/contact-points/test", routes.TestContactPoint(server)) + loginProtected.POST("/api/mqtt/publish", routes.PutMQTTPublish(server)) if server.Config.AuthEnabled { loginProtected.POST("/api/logout", routes.Logout(server)) diff --git a/server/routes/mqtt.go b/server/routes/mqtt.go new file mode 100644 index 0000000..5b53214 --- /dev/null +++ b/server/routes/mqtt.go @@ -0,0 +1,47 @@ +package routes + +import ( + "basic-sensor-receiver/app" + "net/http" + + "github.com/gin-gonic/gin" +) + +type putMQTTPublishBody struct { + Server string `json:"server" binding:"required"` + ClientId string `json:"clientId" binding:"required"` + Username string `json:"username"` + Password string `json:"password"` + Retain *bool `json:"retain"` + Qos *float64 `json:"qos"` + Topic string `json:"topic" binding:"required"` + Message string `json:"message" binding:"required"` +} + +func PutMQTTPublish(s *app.Server) gin.HandlerFunc { + return func(c *gin.Context) { + body := putMQTTPublishBody{} + + if err := bindJSONBodyOrAbort(c, &body); err != nil { + return + } + + qos := byte(0) + retain := false + + if body.Retain != nil { + retain = *body.Retain + } + + if body.Qos != nil { + qos = byte(*body.Qos) + } + + if err := s.Services.MQTT.Publish(body.Server, body.Username, body.Password, body.ClientId, retain, qos, body.Topic, body.Message); err != nil { + c.AbortWithError(500, err) + return + } + + c.Writer.WriteHeader(http.StatusOK) + } +} diff --git a/server/services/mqtt_service.go b/server/services/mqtt_service.go new file mode 100644 index 0000000..b285153 --- /dev/null +++ b/server/services/mqtt_service.go @@ -0,0 +1,30 @@ +package services + +import ( + MQTT "github.com/eclipse/paho.mqtt.golang" +) + +type MQTTService struct { + // TODO: + // ctx *Context +} + +func (s *MQTTService) Publish(server string, username string, password string, clientId string, retain bool, qos byte, topic string, message string) error { + opts := MQTT.NewClientOptions() + opts.AddBroker(server) + opts.SetUsername(username) + opts.SetPassword(password) + opts.SetClientID(clientId) + + client := MQTT.NewClient(opts) + if token := client.Connect(); token.Wait() && token.Error() != nil { + return token.Error() + } + + token := client.Publish(topic, qos, retain, message) + token.Wait() + + client.Disconnect(250) + + return nil +} diff --git a/server/services/services.go b/server/services/services.go index 1b805ef..20c10aa 100644 --- a/server/services/services.go +++ b/server/services/services.go @@ -17,6 +17,7 @@ type Services struct { Alerts *AlertsService AlertsEvaluator *AlertsEvaluatorService ContactPoints *ContactPointsService + MQTT *MQTTService } type Integrations struct { @@ -44,6 +45,7 @@ func InitializeServices(ctx *Context) *Services { services.Alerts = &AlertsService{ctx: ctx} services.AlertsEvaluator = &AlertsEvaluatorService{ctx: ctx} services.ContactPoints = &ContactPointsService{ctx: ctx} + services.MQTT = &MQTTService{} ctx.Integrations = &Integrations{} ctx.Integrations.Telegram = &integrations.TelegramIntegration{}