diff --git a/platformio.ini b/platformio.ini index 1b7905e5..b6542107 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,8 +15,8 @@ lib_deps = [appmod_leds] build_flags = -D APPMOD_LEDS - ; -D USERMOD_ARTNET - ; -D USERMOD_DDP + -D USERMOD_ARTNET + -D USERMOD_DDP lib_deps = https://github.com/FastLED/FastLED.git diff --git a/src/App/AppModLeds.h b/src/App/AppModLeds.h index 0ac45811..ff6ddcc4 100644 --- a/src/App/AppModLeds.h +++ b/src/App/AppModLeds.h @@ -215,11 +215,11 @@ class AppModLeds:public Module { web->addResponse(var["id"], "comment", "Depends on how much leds fastled has configured"); }); - ui->initNumber(parentVar, "dataPin", DATA_PIN, false, [](JsonObject var) { //uiFun - web->addResponseV(var["id"], "comment", "Not implemented yet (fixed to %d)", DATA_PIN); - }, [](JsonObject var) { //chFun - print->print("Set data pin to %d\n", var["value"].as()); - }); + // ui->initNumber(parentVar, "dataPin", DATA_PIN, false, [](JsonObject var) { //uiFun + // web->addResponseV(var["id"], "comment", "Not implemented yet (fixed to %d)", DATA_PIN); + // }, [](JsonObject var) { //chFun + // print->print("Set data pin to %d\n", var["value"].as()); + // }); effects.push_back(new RainbowEffect); effects.push_back(new RainbowWithGlitterEffect); diff --git a/src/Module.h b/src/Module.h index 15d06062..f39b1d44 100644 --- a/src/Module.h +++ b/src/Module.h @@ -18,7 +18,7 @@ class Module { public: const char * name; bool success; - bool enabled; + bool isEnabled; unsigned long secondMillis = 0; // Feels like it should be private, bit doesn't compile if set as such JsonObject parentVar; @@ -26,7 +26,7 @@ class Module { Module(const char * name) { this->name = name; success = true; - enabled = true; + isEnabled = true; // Serial.printf("Constructor %s %s\n", __PRETTY_FUNCTION__, name); } @@ -34,8 +34,8 @@ class Module { virtual void loop() {} - virtual void connected() {} - virtual void enabledChanged(bool tf) {} + virtual void connectedChanged() {} + virtual void enabledChanged() {} virtual void testManager() {} virtual void performanceManager() {} diff --git a/src/Sys/SysModModules.cpp b/src/Sys/SysModModules.cpp index f48fc591..dc1fd72c 100644 --- a/src/Sys/SysModModules.cpp +++ b/src/Sys/SysModModules.cpp @@ -13,16 +13,18 @@ #include "SysModUI.h" #include "SysModWeb.h" -bool Modules::newConnection = false; -std::vector Modules::modules; +bool SysModModules::newConnection = false; +bool SysModModules::isConnected = false; -Modules::Modules() :Module("Modules") { +std::vector SysModModules::modules; + +SysModModules::SysModModules() :Module("Modules") { print->print("%s %s\n", __PRETTY_FUNCTION__, name); print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); }; -void Modules::setup() { +void SysModModules::setup() { for (Module *module:modules) { module->setup(); } @@ -34,11 +36,11 @@ void Modules::setup() { // web->addResponse(var["id"], "label", "Files"); web->addResponse(var["id"], "comment", "List of modules"); JsonArray rows = web->addResponseA(var["id"], "table"); - for (Module *module:Modules::modules) { + for (Module *module:SysModModules::modules) { JsonArray row = rows.createNestedArray(); row.add(module->name); //create a copy! row.add(module->success); - row.add(module->enabled); + row.add(module->isEnabled); } }); ui->initText(tableVar, "mdlName", nullptr, true, [](JsonObject var) { //uiFun @@ -52,20 +54,24 @@ void Modules::setup() { web->addResponse(var["id"], "label", "Enabled"); }, [](JsonObject var) { //chFun print->printJson("mdlEnabled.chFun", var); - //if value not array, create and initialize uint8_t rowNr = 0; - if (!var["value"].is()) { + + //if value not array, create array + if (!var["value"].is()) var.createNestedArray("value"); + + //if value array not same size as nr of modules + if (var["value"].size() != modules.size()) { for (Module *module: modules) { - var["value"][rowNr] = module->enabled; + var["value"][rowNr] = module->isEnabled; rowNr++; } } else { //read array and set module enabled - for (bool enabled:var["value"].as()) { - if (modules[rowNr]->enabled != enabled) { - print->print(" mdlEnabled.chFun %d %s: %d->%d\n", rowNr, modules[rowNr]->name, modules[rowNr]->enabled, enabled); - modules[rowNr]->enabled = enabled; - modules[rowNr]->enabledChanged(enabled); + for (bool isEnabled:var["value"].as()) { + if (modules[rowNr]->isEnabled != isEnabled) { + print->print(" mdlEnabled.chFun %d %s: %d->%d\n", rowNr, modules[rowNr]->name, modules[rowNr]->isEnabled, isEnabled); + modules[rowNr]->isEnabled = isEnabled; + modules[rowNr]->enabledChanged(); } rowNr++; } @@ -73,9 +79,9 @@ void Modules::setup() { }); } -void Modules::loop() { +void SysModModules::loop() { for (Module *module:modules) { - if (module->enabled && module->success) { + if (module->isEnabled && module->success) { module->loop(); // module->testManager(); // module->performanceManager(); @@ -84,17 +90,18 @@ void Modules::loop() { } } if (newConnection) { - connected(); newConnection = false; + isConnected = true; + connectedChanged(); } } -void Modules::add(Module* module) { +void SysModModules::add(Module* module) { modules.push_back(module); } -void Modules::connected() { +void SysModModules::connectedChanged() { for (Module *module:modules) { - module->connected(); + module->connectedChanged(); } } \ No newline at end of file diff --git a/src/Sys/SysModModules.h b/src/Sys/SysModModules.h index 241caffb..7ec43d65 100644 --- a/src/Sys/SysModModules.h +++ b/src/Sys/SysModModules.h @@ -13,11 +13,12 @@ #include -class Modules:public Module { +class SysModModules:public Module { public: static bool newConnection; //need to be static otherwise crash + static bool isConnected; - Modules(); + SysModModules(); void setup(); @@ -25,10 +26,10 @@ class Modules:public Module { void add(Module* module); - void connected(); + void connectedChanged(); private: static std::vector modules; }; -static Modules *mdls; \ No newline at end of file +static SysModModules *mdls; \ No newline at end of file diff --git a/src/Sys/SysModNetwork.cpp b/src/Sys/SysModNetwork.cpp index 602f9c37..af1eee2e 100644 --- a/src/Sys/SysModNetwork.cpp +++ b/src/Sys/SysModNetwork.cpp @@ -82,7 +82,7 @@ void SysModNetwork::handleConnection() { interfacesInited = true; - Modules::newConnection = true; // send all modules connect notification + SysModModules::newConnection = true; // send all modules connect notification // shut down AP if (apActive) { //apBehavior != AP_BEHAVIOR_ALWAYS @@ -131,7 +131,7 @@ void SysModNetwork::initAP() { { mdl->setValueP("nwstatus", "AP %s / %s @ %s", apSSID, apPass, WiFi.softAPIP().toString().c_str()); - Modules::newConnection = true; // send all modules connect notification + SysModModules::newConnection = true; // send all modules connect notification dnsServer.setErrorReplyCode(DNSReplyCode::NoError); dnsServer.start(53, "*", WiFi.softAPIP()); diff --git a/src/Sys/SysModWeb.cpp b/src/Sys/SysModWeb.cpp index 4715a617..b7adfbc9 100644 --- a/src/Sys/SysModWeb.cpp +++ b/src/Sys/SysModWeb.cpp @@ -13,6 +13,7 @@ #include "SysModUI.h" #include "SysModPrint.h" #include "SysModFiles.h" +#include "SysModModules.h" #include "AsyncJson.h" @@ -112,15 +113,18 @@ void SysModWeb::loop() { } } -void SysModWeb::connected() { - ws->onEvent(wsEvent); - // ws->onEvent(wsEvent2); - server->addHandler(ws); +void SysModWeb::connectedChanged() { + if (SysModModules::isConnected) { + ws->onEvent(wsEvent); + // ws->onEvent(wsEvent2); + server->addHandler(ws); - server->begin(); + server->begin(); - // print->print("%s server (re)started\n", name); //causes crash for some reason... - print->print("server (re)started\n"); //and this not causes crash ??? whats with name? + // print->print("%s server (re)started\n", name); //causes crash for some reason... + print->print("server (re)started\n"); //and this not causes crash ??? whats with name? + } + //else remove handlers... } //WebSocket connection to 'ws://192.168.8.152/ws' failed: The operation couldn’t be completed. Protocol error diff --git a/src/Sys/SysModWeb.h b/src/Sys/SysModWeb.h index 157d9205..d021990a 100644 --- a/src/Sys/SysModWeb.h +++ b/src/Sys/SysModWeb.h @@ -24,7 +24,7 @@ class SysModWeb:public Module { void loop(); - void connected(); + void connectedChanged(); static void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); static void wsEvent2(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); diff --git a/src/User/UserModArtNet.h b/src/User/UserModArtNet.h index 057ba275..7a6c5dab 100644 --- a/src/User/UserModArtNet.h +++ b/src/User/UserModArtNet.h @@ -22,6 +22,8 @@ class UserModArtNet:public Module { UserModArtNet() :Module("ArtNet") { print->print("%s %s\n", __PRETTY_FUNCTION__, name); + isEnabled = false; + print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); }; @@ -33,15 +35,16 @@ class UserModArtNet:public Module { print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); } - void connected() { - print->print("%s %s - Connected\n", __PRETTY_FUNCTION__, name); - isConnected = true; - } + // void connectedChanged() { + // if (SysModModules::isConnected) { + // print->print("%s %s - Connected\n", __PRETTY_FUNCTION__, name); + // } + // } void loop(){ // Module::loop(); - if(!isConnected) return; + if(!SysModModules::isConnected) return; if(!lds->newFrame) return; @@ -107,7 +110,6 @@ class UserModArtNet:public Module { } private: - bool isConnected = false; size_t sequenceNumber = 0; }; diff --git a/src/User/UserModDDP.h b/src/User/UserModDDP.h index 3bf264bb..8f914ae5 100644 --- a/src/User/UserModDDP.h +++ b/src/User/UserModDDP.h @@ -38,6 +38,8 @@ class UserModDDP:public Module { UserModDDP() :Module("DDP") { print->print("%s %s\n", __PRETTY_FUNCTION__, name); + isEnabled = false; + print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); }; @@ -49,15 +51,15 @@ class UserModDDP:public Module { print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); } - void connected() { - print->print("%s %s - Connected\n", __PRETTY_FUNCTION__, name); - isConnected = true; + void connectedChanged() { + if (SysModModules::isConnected) + print->print("%s %s - Connected\n", __PRETTY_FUNCTION__, name); } void loop(){ // Module::loop(); - if(!isConnected) return; + if(!SysModModules::isConnected) return; if(!lds->newFrame) return; @@ -129,7 +131,6 @@ class UserModDDP:public Module { } private: - bool isConnected = false; size_t sequenceNumber = 0; }; diff --git a/src/User/UserModE131.h b/src/User/UserModE131.h index cf45a1e5..39cef4ee 100644 --- a/src/User/UserModE131.h +++ b/src/User/UserModE131.h @@ -30,6 +30,8 @@ class UserModE131:public Module { UserModE131() :Module("e131/sACN support") { print->print("%s %s\n", __PRETTY_FUNCTION__, name); + isEnabled = false; + print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); }; @@ -39,24 +41,19 @@ class UserModE131:public Module { print->print("%s %s\n", __PRETTY_FUNCTION__, name); } - void connected() { - print->print("UserModE131::connected\n"); - if(e131Created) { // TODO: crashes here - no idea why! - print->print("UserModE131 - ESPAsyncE131 created already\n"); - return; + void connectedChanged() { + if (SysModModules::isConnected) { + print->print("UserModE131::connected\n"); + setOn(); + print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); } - print->print("UserModE131 - Create ESPAsyncE131\n"); + } - e131 = ESPAsyncE131(universeCount); - if (this->e131.begin(E131_MULTICAST, universe, universeCount)) { // TODO: multicast igmp failing, so only works with unicast currently - print->print("Network exists, begin e131.begin ok\n"); - success = true; - } - else { - print->print("Network exists, begin e131.begin FALED\n"); - } - e131Created = true; - print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); + void enabledChanged() { + if (isEnabled) + setOn(); + else + setOff(); } void loop(){ @@ -65,34 +62,59 @@ class UserModE131:public Module { return; } if (!e131.isEmpty()) { - e131_packet_t packet; - e131.pull(&packet); // Pull packet from ring buffer - - for (int i=0; i < maxChannels; i++) { - if (packet.property_values[i] != varsToWatch[i].savedValue) { - - print->print("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH%d: %u -> %u", - htons(packet.universe), // The Universe for this packet - htons(packet.property_value_count) - 1, // Start code is ignored, we're interested in dimmer data - e131.stats.num_packets, // Packet counter - e131.stats.packet_errors, // Packet error counter - i, - varsToWatch[i].savedValue, - packet.property_values[i]); // Dimmer data for Channel i - - varsToWatch[i].savedValue = packet.property_values[i]; - - if (varsToWatch[i].id != nullptr) { - print->print(" var: %s\n", varsToWatch[i].id); - mdl->setValueI(varsToWatch[i].id, varsToWatch[i].savedValue%varsToWatch[i].max); // TODO: ugly to have magic string - } - else - print->print("\n"); + e131_packet_t packet; + e131.pull(&packet); // Pull packet from ring buffer + + for (int i=0; i < maxChannels; i++) { + if (packet.property_values[i] != varsToWatch[i].savedValue) { + + print->print("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH%d: %u -> %u", + htons(packet.universe), // The Universe for this packet + htons(packet.property_value_count) - 1, // Start code is ignored, we're interested in dimmer data + e131.stats.num_packets, // Packet counter + e131.stats.packet_errors, // Packet error counter + i, + varsToWatch[i].savedValue, + packet.property_values[i]); // Dimmer data for Channel i + + varsToWatch[i].savedValue = packet.property_values[i]; + + if (varsToWatch[i].id != nullptr) { + print->print(" var: %s\n", varsToWatch[i].id); + mdl->setValueI(varsToWatch[i].id, varsToWatch[i].savedValue%varsToWatch[i].max); // TODO: ugly to have magic string } + else + print->print("\n"); } + } } } + void setOn() { + if (SysModModules::isConnected && isEnabled) { + + if (e131Created) { // TODO: crashes here - no idea why! + print->print("UserModE131 - ESPAsyncE131 created already\n"); + return; + } + print->print("UserModE131 - Create ESPAsyncE131\n"); + + e131 = ESPAsyncE131(universeCount); + if (this->e131.begin(E131_MULTICAST, universe, universeCount)) { // TODO: multicast igmp failing, so only works with unicast currently + print->print("Network exists, begin e131.begin ok\n"); + success = true; + } + else { + print->print("Network exists, begin e131.begin FAILED\n"); + } + e131Created = true; + } + } + + void setOff() { + e131Created = false; + } + void addWatch(uint8_t channel, const char * id, uint16_t max) { varsToWatch[channel].id = id; varsToWatch[channel].max = max; diff --git a/src/User/UserModHA.h b/src/User/UserModHA.h index 81c2f91f..2ff26a52 100644 --- a/src/User/UserModHA.h +++ b/src/User/UserModHA.h @@ -20,6 +20,8 @@ class UserModHA:public Module { UserModHA() :Module("Home Assistant support") { print->print("%s %s\n", __PRETTY_FUNCTION__, name); + isEnabled = false; + print->print("%s %s %s\n", __PRETTY_FUNCTION__, name, success?"success":"failed"); }; @@ -48,12 +50,13 @@ class UserModHA:public Module { sender->setRGBColor(color); // report color back to the Home Assistant } - void connected() { + void connectedChanged() { print->print("%s %s\n", __PRETTY_FUNCTION__, name); - // set device's details (optional) - device.setName("StarMod"); - device.setSoftwareVersion("0.0.1"); - + if (SysModModules::isConnected) { + // set device's details (optional) + device.setName("StarMod"); + device.setSoftwareVersion("0.0.1"); + } // configure light (optional) light->setName("LEDs"); diff --git a/src/main.cpp b/src/main.cpp index 24a88481..5c0941cc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,7 +41,7 @@ //setup all modules void setup() { - mdls = new Modules(); + mdls = new SysModModules(); print = new SysModPrint(); files = new SysModFiles();