From 516f6d49f04cb09a141e692cb7a738154a7e9148 Mon Sep 17 00:00:00 2001
From: Jonas Leder <jonas@jonasled.de>
Date: Tue, 25 Mar 2025 22:49:26 +0100
Subject: [PATCH] implement new plugin interface

---
 alarm/alarm.go                    |  4 ++--
 alarm/init.go                     |  7 +++++--
 alarm/pluginConfig.go             | 33 +++++++++++++++++++++++++++++++
 database/gorm.go                  |  3 ++-
 go.mod                            |  2 +-
 go.sum                            |  4 ++--
 webserver/plugins/deleteConfig.go |  4 +++-
 webserver/plugins/getConfig.go    | 22 ++++++++++++---------
 webserver/plugins/list.go         |  4 ++--
 webserver/plugins/setConfig.go    | 29 ++++++++++++++++++++-------
 10 files changed, 85 insertions(+), 27 deletions(-)
 create mode 100644 alarm/pluginConfig.go

diff --git a/alarm/alarm.go b/alarm/alarm.go
index 6646f97..627a201 100644
--- a/alarm/alarm.go
+++ b/alarm/alarm.go
@@ -5,7 +5,7 @@ import (
 
 	"jonasled.dev/firehouse-smokedetection/backend/database/tables"
 	"jonasled.dev/firehouse-smokedetection/backend/types"
-	plugininterface "jonasled.dev/firehouse-smokedetection/plugin-interface"
+	plugintypes "jonasled.dev/firehouse-smokedetection/plugin-interface/types"
 	"jonasled.dev/jonasled/go-libs/log"
 )
 
@@ -18,7 +18,7 @@ func Alarm(mqttMessage types.Z2MSmoke, smokeDetector tables.SmokeDetector) {
 		log.Log.Errorf("Plugin %s for smoke sensor %s not found, can't forward alarm", smokeDetector.AlarmPlugin, smokeDetector.Name)
 		return
 	}
-	err := Plugins[smokeDetector.AlarmPlugin].Alarm(plugininterface.AlarmSmokeSensor{
+	err := Plugins[smokeDetector.AlarmPlugin].Alarm(plugintypes.AlarmSmokeSensor{
 		Smoke:      mqttMessage.Smoke,
 		Test:       mqttMessage.Test,
 		Name:       smokeDetector.Name,
diff --git a/alarm/init.go b/alarm/init.go
index a209597..a4db94c 100644
--- a/alarm/init.go
+++ b/alarm/init.go
@@ -6,7 +6,6 @@ import (
 	"plugin"
 	"strings"
 
-	"jonasled.dev/firehouse-smokedetection/backend/database"
 	plugininterface "jonasled.dev/firehouse-smokedetection/plugin-interface"
 	"jonasled.dev/jonasled/go-libs/config"
 	"jonasled.dev/jonasled/go-libs/log"
@@ -36,7 +35,11 @@ func Init() {
 				log.Log.Fatalf("Failed parsing plugin %s as Plugin Interface", path)
 			}
 
-			plugin.Setup(database.Db)
+			pluginConfig := PluginConfig{
+				PluginName: plugin.GetMetadata().Name,
+			}
+
+			plugin.Setup(&pluginConfig)
 
 			log.Log.Infof("Initialized Plugin %s (v%s)", plugin.GetMetadata().Name, plugin.GetMetadata().Version)
 
diff --git a/alarm/pluginConfig.go b/alarm/pluginConfig.go
new file mode 100644
index 0000000..76ff2c5
--- /dev/null
+++ b/alarm/pluginConfig.go
@@ -0,0 +1,33 @@
+package alarm
+
+import (
+	"jonasled.dev/firehouse-smokedetection/backend/database"
+	"jonasled.dev/firehouse-smokedetection/plugin-interface/types"
+)
+
+type PluginConfig struct {
+	PluginName string
+}
+
+func (p *PluginConfig) GetConfig(id uint) types.AlarmConfig {
+	var alarmConfig types.AlarmConfig
+	database.Db.Where(types.AlarmConfig{ID: id, Plugin: p.PluginName}).First(&alarmConfig)
+
+	return alarmConfig
+}
+
+func (p *PluginConfig) SetConfig(config types.AlarmConfig) error {
+	config.Plugin = p.PluginName
+	return database.Db.Save(&config).Error
+}
+
+func (p *PluginConfig) DeleteConfig(config types.AlarmConfig) error {
+	config.Plugin = p.PluginName
+	return database.Db.Delete(&config).Error
+}
+
+func (p *PluginConfig) ListConfig(filter types.AlarmConfig) []types.AlarmConfig {
+	var matchedConfigs []types.AlarmConfig
+	database.Db.Find(&matchedConfigs, &filter)
+	return matchedConfigs
+}
diff --git a/database/gorm.go b/database/gorm.go
index 4a6517a..e377bd3 100644
--- a/database/gorm.go
+++ b/database/gorm.go
@@ -9,6 +9,7 @@ import (
 	"gorm.io/gorm"
 	"gorm.io/gorm/logger"
 	"jonasled.dev/firehouse-smokedetection/backend/database/tables"
+	plugintypes "jonasled.dev/firehouse-smokedetection/plugin-interface/types"
 	"jonasled.dev/jonasled/go-libs/config"
 	"jonasled.dev/jonasled/go-libs/log"
 )
@@ -40,6 +41,6 @@ func Init() {
 
 	if config.GetOrDefault("EXECUTE_MIGRATIONS", "true") == "true" {
 		log.Log.Info("Executing database migrations")
-		Db.AutoMigrate(&tables.SmokeDetector{})
+		Db.AutoMigrate(&tables.SmokeDetector{}, &plugintypes.AlarmConfig{})
 	}
 }
diff --git a/go.mod b/go.mod
index 1d80096..a81ac27 100644
--- a/go.mod
+++ b/go.mod
@@ -16,7 +16,7 @@ require (
 	github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f
 	github.com/wind-c/comqtt/v2 v2.6.0
 	gorm.io/gorm v1.25.12
-	jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.10
+	jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.14
 	jonasled.dev/jonasled/go-libs v0.0.3
 )
 
diff --git a/go.sum b/go.sum
index 00cb647..77de2d7 100644
--- a/go.sum
+++ b/go.sum
@@ -212,8 +212,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
 gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
-jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.10 h1:qBk+WBGmYirLjUlziIY5YClc4L0TOPR0hMBIfF2HSj0=
-jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.10/go.mod h1:7OmpERugGg+B1OKE5R2glhdbbF2XmYP0OTfbdNNBm40=
+jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.14 h1:3HxNjEiZbQuIPSxdlnffKIqnYsjgtvgerN/4r4WOjmk=
+jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.14/go.mod h1:7OmpERugGg+B1OKE5R2glhdbbF2XmYP0OTfbdNNBm40=
 jonasled.dev/jonasled/go-libs v0.0.3 h1:2Tg1pYJMufBMPkyYVVAvsUJe/R+TRRtRVW9MCbc24bM=
 jonasled.dev/jonasled/go-libs v0.0.3/go.mod h1:E8Sev4obR0x6y7x0HaIN1tImeLnVJgwJXt++jzTwiFM=
 modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
diff --git a/webserver/plugins/deleteConfig.go b/webserver/plugins/deleteConfig.go
index da3c37e..a3a609e 100644
--- a/webserver/plugins/deleteConfig.go
+++ b/webserver/plugins/deleteConfig.go
@@ -7,7 +7,9 @@ import (
 
 	"github.com/gin-gonic/gin"
 	"jonasled.dev/firehouse-smokedetection/backend/alarm"
+	"jonasled.dev/firehouse-smokedetection/backend/database"
 	"jonasled.dev/firehouse-smokedetection/backend/types"
+	plugintypes "jonasled.dev/firehouse-smokedetection/plugin-interface/types"
 )
 
 // @Summary		Delete Config
@@ -37,7 +39,7 @@ func deleteConfig(ctx *gin.Context) {
 		})
 		return
 	}
-	alarm.Plugins[pluginName].DeleteConfig(uint(configIdInt))
+	database.Db.Delete(plugintypes.AlarmConfig{ID: uint(configIdInt), Plugin: pluginName})
 	ctx.JSON(http.StatusOK, types.GeneralResponse{
 		Success: true,
 		Message: "The config has been deleted",
diff --git a/webserver/plugins/getConfig.go b/webserver/plugins/getConfig.go
index 1dfec04..3166b78 100644
--- a/webserver/plugins/getConfig.go
+++ b/webserver/plugins/getConfig.go
@@ -7,16 +7,18 @@ import (
 
 	"github.com/gin-gonic/gin"
 	"jonasled.dev/firehouse-smokedetection/backend/alarm"
+	"jonasled.dev/firehouse-smokedetection/backend/database"
 	"jonasled.dev/firehouse-smokedetection/backend/types"
+	plugintypes "jonasled.dev/firehouse-smokedetection/plugin-interface/types"
 )
 
-//	@Summary		Get Config
-//	@Description	Get a existing config
-//	@Tags			plugins
-//	@Produce		json
-//	@Param			plugin		path	string	true	"Plugin name"
-//	@Param			configId	path	int		true	"ID of the config to update"
-//	@router			/api/v1/plugins/{plugin}/{configId} [get]
+// @Summary		Get Config
+// @Description	Get a existing config
+// @Tags			plugins
+// @Produce		json
+// @Param			plugin		path	string	true	"Plugin name"
+// @Param			configId	path	int		true	"ID of the config to update"
+// @router			/api/v1/plugins/{plugin}/{configId} [get]
 func getConfig(ctx *gin.Context) {
 	pluginNames := alarm.GetAllPlugins()
 	pluginName := ctx.Param("plugin")
@@ -37,6 +39,8 @@ func getConfig(ctx *gin.Context) {
 		})
 		return
 	}
-	config := alarm.Plugins[pluginName].GetConfig(uint(configIdInt))
-	ctx.JSON(http.StatusOK, &config)
+	var alarmConfig plugintypes.AlarmConfig
+	database.Db.Where(plugintypes.AlarmConfig{ID: uint(configIdInt), Plugin: pluginName}).First(&alarmConfig)
+	ctx.Header("Content-Type", "application/json")
+	ctx.String(http.StatusOK, alarmConfig.Config)
 }
diff --git a/webserver/plugins/list.go b/webserver/plugins/list.go
index 33bdfb1..741ea0c 100644
--- a/webserver/plugins/list.go
+++ b/webserver/plugins/list.go
@@ -5,7 +5,7 @@ import (
 
 	"github.com/gin-gonic/gin"
 	"jonasled.dev/firehouse-smokedetection/backend/alarm"
-	plugininterface "jonasled.dev/firehouse-smokedetection/plugin-interface"
+	plugintypes "jonasled.dev/firehouse-smokedetection/plugin-interface/types"
 )
 
 // @Summary		List plugins
@@ -16,7 +16,7 @@ import (
 // @router			/api/v1/plugins [get]
 func listAll(ctx *gin.Context) {
 	pluginNames := alarm.GetAllPlugins()
-	pluginResponse := []plugininterface.PluginMetadata{}
+	pluginResponse := []plugintypes.PluginMetadata{}
 
 	for _, pluginName := range pluginNames {
 		pluginResponse = append(pluginResponse, alarm.Plugins[pluginName].GetMetadata())
diff --git a/webserver/plugins/setConfig.go b/webserver/plugins/setConfig.go
index 40d934b..deb6294 100644
--- a/webserver/plugins/setConfig.go
+++ b/webserver/plugins/setConfig.go
@@ -1,6 +1,7 @@
 package plugins
 
 import (
+	"encoding/json"
 	"io"
 	"net/http"
 	"slices"
@@ -8,8 +9,9 @@ import (
 
 	"github.com/gin-gonic/gin"
 	"jonasled.dev/firehouse-smokedetection/backend/alarm"
+	"jonasled.dev/firehouse-smokedetection/backend/database"
 	"jonasled.dev/firehouse-smokedetection/backend/types"
-	"jonasled.dev/jonasled/go-libs/log"
+	plugintypes "jonasled.dev/firehouse-smokedetection/plugin-interface/types"
 )
 
 // @Summary		Create Config
@@ -31,15 +33,21 @@ func setNewConfig(ctx *gin.Context) {
 	}
 
 	body, _ := io.ReadAll(ctx.Request.Body)
-	err := alarm.Plugins[pluginName].SetConfig(string(body), 0)
+	pluginConfig := alarm.Plugins[pluginName].GetConfigType()
+	err := json.Unmarshal(body, &pluginConfig)
 	if err != nil {
-		log.Log.Error("Failed saving config: ", err.Error())
 		ctx.JSON(http.StatusBadRequest, types.GeneralResponse{
 			Success: true,
-			Message: "failed updating config, check server log fore more infos",
+			Message: "failed parsing configuration: " + err.Error(),
 		})
 		return
 	}
+	configJson, _ := json.Marshal(&pluginConfig)
+	dbPluginConfig := plugintypes.AlarmConfig{
+		Plugin: pluginName,
+		Config: string(configJson),
+	}
+	database.Db.Save(&dbPluginConfig)
 
 	ctx.JSON(http.StatusOK, types.GeneralResponse{
 		Success: true,
@@ -77,15 +85,22 @@ func updateConfig(ctx *gin.Context) {
 	}
 
 	body, _ := io.ReadAll(ctx.Request.Body)
-	err = alarm.Plugins[pluginName].SetConfig(string(body), uint(configIdInt))
+	pluginConfig := alarm.Plugins[pluginName].GetConfigType()
+	err = json.Unmarshal(body, &pluginConfig)
 	if err != nil {
-		log.Log.Error("Failed saving config: ", err.Error())
 		ctx.JSON(http.StatusBadRequest, types.GeneralResponse{
 			Success: true,
-			Message: "failed updating config, check server log fore more infos",
+			Message: "failed parsing configuration: " + err.Error(),
 		})
 		return
 	}
+	configJson, _ := json.Marshal(&pluginConfig)
+	dbPluginConfig := plugintypes.AlarmConfig{
+		Plugin: pluginName,
+		ID:     uint(configIdInt),
+		Config: string(configJson),
+	}
+	database.Db.Save(&dbPluginConfig)
 
 	ctx.JSON(http.StatusOK, types.GeneralResponse{
 		Success: true,
-- 
GitLab