diff --git a/Readme.md b/Readme.md
index a294be903d82a6d3d380664f75e5da59398f74cc..3710da44533210361d939e642325c5553ee07e03 100644
--- a/Readme.md
+++ b/Readme.md
@@ -16,5 +16,6 @@ The configuration can either be done through environment variables or a file cal
 | EXIT_ON_DISCONNECT | `false` | Exit the application on MQTT disconnect |
 | Z2M_BASETOPIC | `zigbee2mqtt` | Base topic for ZigBee2MQTT |
 | DB_DRIVER | `sqlite` | Database driver, currently ony sqlite is supported |
-| DB_NAME | `./database.db` | Name of the databse, for sqlite path to the DB file
-| EXECUTE_MIGRATIONS | `true` | Execute database migrations on start |
\ No newline at end of file
+| DB_NAME | `./database.db` | Name of the databse, for sqlite path to the DB file |
+| EXECUTE_MIGRATIONS | `true` | Execute database migrations on start |
+| PLUGIN_DIR | `./plugins` | Where to search for plugins |
diff --git a/alarm/init.go b/alarm/init.go
new file mode 100644
index 0000000000000000000000000000000000000000..6d9b398cbf91da627ec21be9b8bc6b748d5e2702
--- /dev/null
+++ b/alarm/init.go
@@ -0,0 +1,47 @@
+package alarm
+
+import (
+	"os"
+	"path/filepath"
+	"plugin"
+	"strings"
+
+	plugininterface "jonasled.dev/firehouse-smokedetection/plugin-interface"
+	"jonasled.dev/jonasled/go-libs/config"
+	"jonasled.dev/jonasled/go-libs/log"
+)
+
+var plugins []plugininterface.Plugin
+
+func Init() {
+	err := filepath.Walk(config.GetOrDefault("PLUGIN_DIR", "./plugins"), func(path string, info os.FileInfo, err error) error {
+		if err != nil {
+			log.Log.Fatal("Failed reading plugin dir: ", err.Error())
+		}
+
+		if !info.IsDir() && strings.HasSuffix(info.Name(), ".so") {
+			log.Log.Debug("Found plugin file at ", path)
+			plg, err := plugin.Open(path)
+			if err != nil {
+				log.Log.Fatalf("Failed reading Plugin %s: %s", path, err.Error())
+			}
+			v, err := plg.Lookup("Plugin")
+			if err != nil {
+				log.Log.Fatalf("Plugin %s doesn't export Plugin var", path)
+			}
+			plugin, ok := v.(plugininterface.Plugin)
+			if !ok {
+				log.Log.Fatalf("Failed parsing plugin %s as Plugin Interface", path)
+			}
+
+			log.Log.Infof("Initialized Plugin %s (v%s)", plugin.GetMetadata().Name, plugin.GetMetadata().Version)
+
+			plugins = append(plugins, plugin)
+		}
+		return nil
+	})
+
+	if err != nil {
+		log.Log.Fatal("Failed reading plugin dir: ", err.Error())
+	}
+}
diff --git a/go.mod b/go.mod
index 55de059b51d9b3f468e9763c6f98b16213335d77..2fb24c4747fe462ba3410b570438a16595b5fbfa 100644
--- a/go.mod
+++ b/go.mod
@@ -10,12 +10,12 @@ require (
 	github.com/nekomeowww/gorm-logger-logrus v1.0.8
 	github.com/sirupsen/logrus v1.9.3
 	github.com/swaggo/files v1.0.1
-	github.com/swaggo/files/v2 v2.0.2
 	github.com/swaggo/gin-swagger v1.6.0
 	github.com/swaggo/swag v1.16.4
 	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.5
 	jonasled.dev/jonasled/go-libs v0.0.3
 )
 
@@ -59,9 +59,9 @@ require (
 	golang.org/x/arch v0.8.0 // indirect
 	golang.org/x/crypto v0.25.0 // indirect
 	golang.org/x/net v0.27.0 // indirect
-	golang.org/x/sync v0.7.0 // indirect
+	golang.org/x/sync v0.12.0 // indirect
 	golang.org/x/sys v0.22.0 // indirect
-	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
 	golang.org/x/tools v0.23.0 // indirect
 	google.golang.org/protobuf v1.34.1 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
diff --git a/go.sum b/go.sum
index 31ecab3477b10045a68ff0d3cbc35665dd639560..3a11e709722b47ee2abeea09e81b3c28e90e68ce 100644
--- a/go.sum
+++ b/go.sum
@@ -125,7 +125,6 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
 github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
-github.com/swaggo/files/v2 v2.0.2/go.mod h1:TVqetIzZsO9OhHX1Am9sRf9LdrFZqoK49N37KON/jr0=
 github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
 github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
 github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=
@@ -158,8 +157,8 @@ golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
 golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
+golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -179,8 +178,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@@ -204,8 +203,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/jonasled/go-libs v0.0.2 h1:QJE0jy9SH8flqAJIJHMG6NE3VPZurCvvMGf5xN0C+Xc=
-jonasled.dev/jonasled/go-libs v0.0.2/go.mod h1:E8Sev4obR0x6y7x0HaIN1tImeLnVJgwJXt++jzTwiFM=
+jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.5 h1:DsxFy25O4HIP2PfxMq8d/RodejFOZviiV4h8DSqYIHM=
+jonasled.dev/firehouse-smokedetection/plugin-interface v0.0.5/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/main.go b/main.go
index 61c5cb0cb9a0184569a755f1fc2bb022e4ba0f5f..04d33347147418ad02d4cdf924e282746bc2a9e0 100644
--- a/main.go
+++ b/main.go
@@ -2,6 +2,7 @@ package main
 
 import (
 	_ "github.com/joho/godotenv/autoload"
+	"jonasled.dev/firehouse-smokedetection/backend/alarm"
 	"jonasled.dev/firehouse-smokedetection/backend/database"
 	"jonasled.dev/firehouse-smokedetection/backend/mqttclient"
 	"jonasled.dev/firehouse-smokedetection/backend/mqttserver"
@@ -26,6 +27,7 @@ func main() {
 	database.Init()
 	mqttclient.Init()
 	webserver.Init()
+	alarm.Init()
 
 	webserver.Run()
 }