diff --git a/gateway.go b/gateway.go
index 2503589a560e1952fcda69d2739db60117b1d8b4..b20235de0ef5358b0de58e6867c16c6a4f292de3 100644
--- a/gateway.go
+++ b/gateway.go
@@ -1,6 +1,9 @@
 package main
 
 import (
+	"encoding/json"
+	"log/slog"
+	"slices"
 	"sync"
 
 	MQTT "github.com/eclipse/paho.mqtt.golang"
@@ -27,10 +30,12 @@ func GetGW() *Gateway {
 	return instance
 }
 
-func NewGW(client MQTT.Client, cfg *Config) *Gateway {
+func NewGW(cfg *Config, eng *xaal.Engine) *Gateway {
 	gw := GetGW()
 	gw.baseAddr = cfg.baseAddr
-	gw.client = client
+	gw.client = mqttSetup(cfg, gw.mqttPublishHander)
+	// NOTE: Wondering if we can setup engine before
+	gw.engine = eng
 	return gw
 }
 
@@ -50,3 +55,46 @@ func (gw *Gateway) GetZDeviceByTopic(topic string) *Z2MDevice {
 	name := topic[len(mqttTopic+"/"):]
 	return gw.GetZDevice(name)
 }
+
+// mqttPublishHander handles all incoming MQTT messages
+// If the topic is /bridge/devices it will parse the json and create new devices
+// Else it will find the device with the topic and call the mqttDeviceHandler
+func (gw *Gateway) mqttPublishHander(client MQTT.Client, msg MQTT.Message) {
+	// we ignore some topics
+	if slices.Contains(ignoredTopics, msg.Topic()) {
+		return
+	}
+	// slog.Debug("Received message on", "topic", msg.Topic())
+	// Is it devices definitions ?
+	if msg.Topic() == mqttTopic+"/bridge/devices" {
+		gw.jsonParseDevices(msg.Payload())
+	} else {
+		dev := gw.GetZDeviceByTopic(msg.Topic())
+		// mqttDumpMsg(msg)
+		if dev != nil {
+			dev.HandleMessage(msg)
+		}
+	}
+}
+
+// jsonParseDevices parses the bridge/devices json and creates new xAAL devices
+// if they don't exist
+func (gw *Gateway) jsonParseDevices(jsonData []byte) {
+	var devices []Z2MDevice
+	err := json.Unmarshal([]byte(jsonData), &devices)
+	if err != nil {
+		slog.Error("Error decoding JSON", "err", err)
+	}
+
+	for _, zDev := range devices {
+		known := gw.GetZDevice(zDev.FriendlyName)
+		if known != nil {
+			continue
+		}
+		zDev.dump()
+		zDev.setupXAALDevices(gw)
+		gw.AddZDevice(&zDev)
+		zDev.Sync()
+		// zDev.Available()
+	}
+}
diff --git a/main.go b/main.go
index a2fccbca2171e53e4e0b5c74f9674665993156fe..2c8b37d7814b67ccdd42dda07cb22548e6376ca6 100644
--- a/main.go
+++ b/main.go
@@ -12,15 +12,15 @@ func main() {
 		slog.Error("Error parsing configuration file: ", "err", err)
 		return
 	}
-	// spew.Dump(cfg)
 
+	// start xAAL stack
 	xaal.SetupLogger()
-	client := mqttSetup(cfg, mqttPublishHander)
-
 	eng := xaal.NewEngine()
-	gw := NewGW(client, cfg)
-	gw.engine = eng
+	// start the gateway
+	gw := NewGW(cfg, eng)
+	// start the xAAL engine
 	eng.Run()
-	client.Disconnect(250)
+	// Engine stops, disconnect MQTT
+	gw.client.Disconnect(250)
 	slog.Debug("MQTT disconnected")
 }
diff --git a/z2m.go b/z2m.go
index c7e19bf3019aa7807bc2c69c4ecdce21558512c8..0a2db0309b6cd0547685486df57eb964a9af0093 100644
--- a/z2m.go
+++ b/z2m.go
@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"log/slog"
-	"slices"
 	"strings"
 
 	MQTT "github.com/eclipse/paho.mqtt.golang"
@@ -226,47 +225,3 @@ func (l AccessLevel) String() string {
 func (l AccessLevel) EnumIndex() int {
 	return int(l)
 }
-
-// jsonParseDevices parses the bridge/devices json and creates new xAAL devices
-// if they don't exist
-func jsonParseDevices(jsonData []byte) {
-	var devices []Z2MDevice
-	err := json.Unmarshal([]byte(jsonData), &devices)
-	if err != nil {
-		slog.Error("Error decoding JSON", "err", err)
-	}
-
-	gw := GetGW()
-	for _, zDev := range devices {
-		known := gw.GetZDevice(zDev.FriendlyName)
-		if known != nil {
-			continue
-		}
-		zDev.dump()
-		zDev.setupXAALDevices(gw)
-		gw.AddZDevice(&zDev)
-		zDev.Sync()
-		// zDev.Available()
-	}
-}
-
-// mqttPublishHander handles all incoming MQTT messages
-// If the topic is /bridge/devices it will parse the json and create new devices
-// Else it will find the device with the topic and call the mqttDeviceHandler
-func mqttPublishHander(client MQTT.Client, msg MQTT.Message) {
-	// we ignore some topics
-	if slices.Contains(ignoredTopics, msg.Topic()) {
-		return
-	}
-	// slog.Debug("Received message on", "topic", msg.Topic())
-	// Is it devices definitions ?
-	if msg.Topic() == mqttTopic+"/bridge/devices" {
-		jsonParseDevices(msg.Payload())
-	} else {
-		dev := GetGW().GetZDeviceByTopic(msg.Topic())
-		// mqttDumpMsg(msg)
-		if dev != nil {
-			dev.HandleMessage(msg)
-		}
-	}
-}