diff --git a/CLC-qthing/SiliconTorch/Service/CyanStripe.cpp b/CLC-qthing/SiliconTorch/Service/CyanStripe.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..faa482e3da7616bc0cbe37cf0810390fd062ede0
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/CyanStripe.cpp
@@ -0,0 +1,27 @@
+#include "CyanStripe.hpp"
+
+
+
+
+// TODO: implement!
+
+
+
+
+
+  //cyanBus = new SiliconTorch::CyanBus::CyanBus(13, 14, 12, 15, 2000000);  // Pinout of CyanStripe
+
+
+  /* auto led0 = cfg.add<qthing::leds::WS2812B_V3>(GPIO_NUM_27, 8);
+
+  cyanRGB = new SiliconTorch::FxCyanRGB8::FxCyanRGB8(8);
+  cyanRGB->registerUDPHandler();
+  cyanRGB->registerAtCyanBus(*cyanBus);
+
+  auto bullshitPtr = std::shared_ptr<qthing::Animation<qthing::RGB>>(cyanRGB, [](void*){});
+  cfg.add<qthing::Animator<qthing::RGBW8>>(led0)->setAnimation(bullshitPtr); */
+
+
+
+
+
diff --git a/CLC-qthing/SiliconTorch/Service/CyanStripe.hpp b/CLC-qthing/SiliconTorch/Service/CyanStripe.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1437ddc325a9215aec56ada11641680223eca287
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/CyanStripe.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+
+
+// TODO: implement!
+
+
+
+
diff --git a/CLC-qthing/SiliconTorch/Service/FxCyanF.cpp b/CLC-qthing/SiliconTorch/Service/FxCyanF.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a4564dea3532cda82981123d863f3508430476b3
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/FxCyanF.cpp
@@ -0,0 +1,42 @@
+#include "FxCyanF.hpp"
+
+// C++ system level
+// #include <cstring>     // memset, strncmp
+// #include <cstdlib>     // TODO: is this for memcpy?
+// #include <functional>
+
+// ESP32 specific
+#include "esp_log.h"
+
+// project specific
+#include <Types.hpp>
+#include "SiliconTorch/NVSExplorer.hpp"
+
+// qthing stuff
+// #include <qthing>
+
+
+
+namespace SiliconTorch {
+
+  namespace Service {
+
+    void FxCyanF::init() {
+      setName("FxCyanF");
+      setNameSpace("fxCyan");  // TODO: "FxCyanF"
+    }
+
+    void FxCyanF::start() {
+      ESP_LOGW(getName().c_str(), "Starting service[ %s ] with order[ %d ]  *WHOOP* *WHOOP*", getName().c_str(), getStartOrder());
+    }
+
+    void FxCyanF::stop() {
+      ESP_LOGW(getName().c_str(), "Stopping service[ %s ]  *sad service noises*", getName().c_str());
+    }
+
+    // str name() { return "FxCyanF"; }
+    // str nameSpace() { return "fxCyan"; }  // TODO: "FxCyanF"
+
+
+  }
+}
diff --git a/CLC-qthing/SiliconTorch/Service/FxCyanF.hpp b/CLC-qthing/SiliconTorch/Service/FxCyanF.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7e08eda3d5b5e88646d1a12fb19e274e73bb0ff5
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/FxCyanF.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+// C++ system level
+// #include <cstring>     // memset, strncmp
+// #include <cstdlib>     // TODO: is this for memcpy?
+// #include <functional>
+
+// ESP32 specific
+#include "esp_log.h"
+
+// project specific
+#include <Types.hpp>
+#include "Service.hpp"
+
+// qthing stuff
+// #include <qthing>
+
+
+namespace SiliconTorch {
+
+  namespace Service {
+
+    class FxCyanF : public ServiceManager::Service {
+
+      public:
+
+
+        void init();
+
+        void start();
+        void stop();
+
+
+
+
+      private:
+
+
+    };
+
+  }
+}
diff --git a/CLC-qthing/SiliconTorch/Service/FxPublish.cpp b/CLC-qthing/SiliconTorch/Service/FxPublish.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dfcf126329258086b767c1c521645aaf1b76b4e5
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/FxPublish.cpp
@@ -0,0 +1,17 @@
+#include "FxPublish.hpp"
+
+
+
+
+// TODO: implement!
+
+
+
+
+  //fxPub = new SiliconTorch::FxPublish::FxPublish();
+  //fxPub->registerAtCyanBus(*cyanBus);
+
+
+
+
+
diff --git a/CLC-qthing/SiliconTorch/Service/FxPublish.hpp b/CLC-qthing/SiliconTorch/Service/FxPublish.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1437ddc325a9215aec56ada11641680223eca287
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/FxPublish.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+
+
+// TODO: implement!
+
+
+
+
diff --git a/CLC-qthing/SiliconTorch/Service/Service.cpp b/CLC-qthing/SiliconTorch/Service/Service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a6b213b50b8b888fb8c28a4dbbe8fcd60fa7cb4
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/Service.cpp
@@ -0,0 +1,110 @@
+#include "Service.hpp"
+
+// C++ system level
+// #include <cstring>     // memset, strncmp
+// #include <cstdlib>     // TODO: is this for memcpy?
+// #include <functional>
+
+// ESP32 specific
+#include "esp_log.h"
+
+// project specific
+#include <Types.hpp>
+#include "SiliconTorch/NVSExplorer.hpp"
+
+// qthing stuff
+// #include <qthing>
+
+
+const char* TAG = "ServiceManager";
+
+
+namespace SiliconTorch {
+
+  namespace ServiceManager {
+
+    const str NVSStateKey = "state";
+
+
+    Service::Service() {
+      // u8 state = 0;  // disabled -> 0   enabled -> 1
+      // state = NVSExplorer::NVSExplorer::instance().getUnsignedInt(nameSpace(), NVSStateKey, state);
+
+      // if (state >= (u8)Invalid) state = (u8)Disabled;
+      // nvsState = (NVSState)state;
+    }
+
+    void Service::postInit() {
+      u8 state = 0;  // disabled -> 0   enabled -> 1
+      state = NVSExplorer::NVSExplorer::instance().getUnsignedInt(getNameSpace(), NVSStateKey, state);
+
+      if (state >= (u8)Invalid) state = (u8)Disabled;
+      nvsState = (NVSState)state;
+    }
+
+    bool Service::isEnabled() {
+      return nvsState == Enabled;
+    }
+
+    void Service::setEnabled(bool enabled) {
+
+      NVSState state = enabled ? Enabled : Disabled;
+      u8 stateValue = (u8)state;
+
+      bool result = SiliconTorch::NVSExplorer::NVSExplorer::instance().setU8(getNameSpace(), NVSStateKey, stateValue);
+
+      if (!result) {
+        SiliconTorch::NVSExplorer::NVSExplorer::instance().removeKey(getNameSpace(), NVSStateKey);
+        result = SiliconTorch::NVSExplorer::NVSExplorer::instance().setU8(getNameSpace(), NVSStateKey, stateValue);
+      }
+
+      if (result) {
+        nvsState = state;
+        ESP_LOGI(TAG, "Setting service[ %s ] to %s", getName().c_str(), enabled ? "enabled[✅]" : "disabled[❌]");
+      } else {
+        ESP_LOGW(TAG, "Error saving service[ %s] state!", getName().c_str());
+      }
+    }
+
+    // u16 Service::startOrder() {
+    //   return 1337;  // actually a sane default 😏
+    // }
+
+
+    void Service::setName(const str& name) {
+      if (!nameSet) {
+        nameSet = true;
+        this->name = name;
+      } else {
+        // TODO: report error somehow?
+      }
+    }
+
+    void Service::setNameSpace(const str& nameSpace) {
+      if (!nameSpaceSet) {
+        nameSpaceSet = true;
+        this->nameSpace = nameSpace;
+      } else {
+        // TODO: report error somehow?
+      }
+    }
+
+    void Service::setStartOrder(u16 startOrder) {
+      this->startOrder = startOrder;
+    }
+
+
+    const str& Service::getName() {
+      return name;
+    }
+
+    const str& Service::getNameSpace() {
+      return nameSpace;
+    }
+
+    u16 Service::getStartOrder() {
+      return startOrder;
+    }
+
+  }
+}
diff --git a/CLC-qthing/SiliconTorch/Service/Service.hpp b/CLC-qthing/SiliconTorch/Service/Service.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..663967764a7a6dd9cba93b8707d3f761062c6786
--- /dev/null
+++ b/CLC-qthing/SiliconTorch/Service/Service.hpp
@@ -0,0 +1,81 @@
+#pragma once
+
+// C++ system level
+// #include <cstring>     // memset, strncmp
+// #include <cstdlib>     // TODO: is this for memcpy?
+// #include <functional>
+
+// ESP32 specific
+#include "esp_log.h"
+
+// project specific
+#include <Types.hpp>
+
+// qthing stuff
+// #include <qthing>
+
+
+namespace SiliconTorch {
+
+  namespace ServiceManager {
+
+    extern const str NVSStateKey;
+
+    enum NVSState : u8 {
+      Disabled = 0,
+      Enabled  = 1,
+      Invalid
+    };
+
+
+    class Service {
+      public:
+
+        Service();
+
+        virtual void init()      = 0;
+
+        // internal stuff, only to be called by ServiceManager!
+        void postInit();
+
+        virtual void start()     = 0;
+        virtual void stop()      = 0;
+
+        const str& getName();
+        const str& getNameSpace();
+
+        // virtual str name()       = 0;
+        // virtual str nameSpace()  = 0;
+
+        u16 getStartOrder();
+
+        // enabled services will be started in this order. higher = later
+        // virtual u16 startOrder();  // defaults to 1337
+
+        bool isEnabled();
+        void setEnabled(bool enabled);
+
+      protected:
+
+        void setName(const str& name);
+        void setNameSpace(const str& nameSpace);
+        void setStartOrder(u16 startOrder);
+
+      private:
+
+        NVSState nvsState = Disabled;
+
+        bool nameSet = false;
+        str name = "";
+
+        bool nameSpaceSet = false;
+        str nameSpace = "";
+
+        u16 startOrder = 1337;
+
+
+    };
+
+
+  }
+}
diff --git a/CLC-qthing/device_main.cpp b/CLC-qthing/device_main.cpp
index 6d2e42f4030b4f3b7ee39917bf6e0d74f6e982f2..3831830e1a350b71ffd70aeb6fbacb8e6e69a3f1 100644
--- a/CLC-qthing/device_main.cpp
+++ b/CLC-qthing/device_main.cpp
@@ -1,10 +1,10 @@
 #include <qthing>
 
 #include "esp_log.h"
-#include "driver/gpio.h"
 
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
+#include "freertos/semphr.h"
 
 
 #include "CyanLight.hpp"
@@ -13,70 +13,66 @@
 #include <SpiderLib.hpp>
 
 
-// ### LIBS FOR TESTING ###
-#include <cstdlib>
+#include "SiliconTorch/NVSExplorer.hpp"
 
-#include "SiliconTorch/CyanBus.hpp"
 
 
-#include <memory>
-#include "driver/gpio.h"
-#include "SiliconTorch/FxCyanRGB8.hpp"
+#include "SiliconTorch/Service/FxCyanF.hpp"
+#include "SiliconTorch/Service/Service.hpp"
 
 
-//#include "SiliconTorch/FxPublish.hpp"
 
 
-#include "SiliconTorch/NVSExplorer.hpp"
-#include <set>  // remove after NVSExplorer development!
+CyanLight::CyanLightControl* ctrl = NULL;
 
-// ###     END LIBS     ###
 
 
+SiliconTorch::ServiceManager::Service* fxCyan = NULL;
 
-#include <algorithm>
 
 
+void device_main() {
 
-SiliconTorch::CyanBus::CyanBus* cyanBus = NULL;
 
-//SiliconTorch::FxPublish::FxPublish* fxPub = NULL;
-SiliconTorch::FxCyanRGB8::FxCyanRGB8* cyanRGB = NULL;
+  qthing::Config cfg;
 
-CyanLight::CyanLightControl* ctrl = NULL;
+  // Needed for packet parsing, animation rendering and stuff
+  qthing::power_managment_max_power();
 
 
 
-void device_main() {
 
 
-  qthing::Config cfg;
 
-  // Needed for packet parsing, animation rendering and stuff
-  qthing::power_managment_max_power();
+  SemaphoreHandle_t mutex000 = xSemaphoreCreateBinary();
 
+  // Do it in another task do control stack size
+  new SpiderLib::Util::LambdaTask([&]() {
+    // Trigger singleton initialization
+    SiliconTorch::NVSExplorer::NVSExplorer::instance();
+
+
+    fxCyan = new SiliconTorch::Service::FxCyanF();
 
+    fxCyan->start();
 
 
-  //cyanBus = new SiliconTorch::CyanBus::CyanBus(13, 14, 12, 15, 2000000);  // Pinout of CyanStripe
+    xSemaphoreGive(mutex000);
+  });
+
+  xSemaphoreTake(mutex000, portMAX_DELAY);  // avoid races with MQTT subscriptions (TODO: do we lock with WLAN atm???)
 
+  qthing::enable_wifi();
+  return;
 
-  /* auto led0 = cfg.add<qthing::leds::WS2812B_V3>(GPIO_NUM_27, 8);
 
-  cyanRGB = new SiliconTorch::FxCyanRGB8::FxCyanRGB8(8);
-  cyanRGB->registerUDPHandler();
-  cyanRGB->registerAtCyanBus(*cyanBus);
 
-  auto bullshitPtr = std::shared_ptr<qthing::Animation<qthing::RGB>>(cyanRGB, [](void*){});
-  cfg.add<qthing::Animator<qthing::RGBW8>>(led0)->setAnimation(bullshitPtr); */
 
-  //fxPub = new SiliconTorch::FxPublish::FxPublish();
-  //fxPub->registerAtCyanBus(*cyanBus);
 
 
 
-  // TODO: ???
 
+  SemaphoreHandle_t mutex = xSemaphoreCreateBinary();
 
   // Do it in another task do control stack size
   new SpiderLib::Util::LambdaTask([&]() {
@@ -84,8 +80,12 @@ void device_main() {
     SiliconTorch::NVSExplorer::NVSExplorer::instance();
 
     SiliconTorch::FxCyanF::configureFromNVS();
+
+    xSemaphoreGive(mutex);
   });
 
+  xSemaphoreTake(mutex, portMAX_DELAY);  // avoid races with MQTT subscriptions (TODO: do we lock with WLAN atm???)
+
   qthing::enable_wifi();
   return;