From edc7c56c1aea417a1e4f22e997b8181385d37da5 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Tue, 11 Dec 2018 22:42:15 -0500 Subject: [PATCH 01/10] e131 mode Submit "=e131" via mqtt or websocket to activate --- Arduino/McLighting/McLighting.ino | 46 +++++++++++++++++++++++-- Arduino/McLighting/definitions.h | 14 ++++++-- Arduino/McLighting/request_handlers.h | 49 +++++++++++++++++++++++++++ Arduino/McLighting/version.h | 2 +- Arduino/McLighting/version_info.ino | 3 ++ clients/web/build/index.htm | 5 +++ clients/web/src/index.htm | 5 +++ platformio.ini | 4 ++- 8 files changed, 122 insertions(+), 6 deletions(-) diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index 4c78190..eb556a0 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -53,11 +53,17 @@ #endif #ifdef ARDUINOJSON_VERSION - #if !(ARDUINOJSON_VERSION_MAJOR == 6 and ARDUINOJSON_VERSION_MINOR == 6) - #error "Install ArduinoJson v6.6.0-beta" + #if !(ARDUINOJSON_VERSION_MAJOR == 6 and ARDUINOJSON_VERSION_MINOR == 7) + #error "Install ArduinoJson v6.7.0-beta" #endif #endif +#ifdef ENABLE_E131 + #include <ESPAsyncUDP.h> //https://github.com/me-no-dev/ESPAsyncUDP + #include <ESPAsyncE131.h> //https://github.com/forkineye/ESPAsyncE131 + ESPAsyncE131 e131(UNIVERSE_COUNT); +#endif + // *************************************************************************** // Instanciate HTTP(80) / WebSockets(81) Server @@ -351,6 +357,8 @@ void setup() { strcpy(mqtt_user, custom_mqtt_user.getValue()); strcpy(mqtt_pass, custom_mqtt_pass.getValue()); + Serial.printf(">>>>>%s %s %s %s<<<<<<<<<\n", mqtt_host, mqtt_port, mqtt_user, mqtt_pass); + //save the custom parameters to FS #if defined(ENABLE_STATE_SAVE_SPIFFS) and (defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)) (writeConfigFS(shouldSaveConfig)) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Save success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Save failure!"); @@ -840,6 +848,26 @@ void setup() { if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); #endif }); + + #ifdef ENABLE_E131 + server.on("/e131", []() { + exit_func = true; + mode = E131; + getStatusJSON(); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String("OK =e131").c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =131").c_str()); + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + }); + #endif server.on("/tv", []() { exit_func = true; @@ -895,6 +923,15 @@ void setup() { if (mdns_result) { MDNS.addService("http", "tcp", 80); } + + #ifdef ENABLE_E131 + // Choose one to begin listening for E1.31 data + // if (e131.begin(E131_UNICAST)) // Listen via Unicast + if (e131.begin(E131_MULTICAST, UNIVERSE, UNIVERSE_COUNT)) // Listen via Multicast + Serial.println(F("Listening for data...")); + else + Serial.println(F("*** e131.begin failed ***")); + #endif #ifdef ENABLE_STATE_SAVE_SPIFFS (readStateFS()) ? DBG_OUTPUT_PORT.println(" Success!") : DBG_OUTPUT_PORT.println(" Failure!"); #endif @@ -1013,6 +1050,11 @@ void loop() { strip.trigger(); mode = HOLD; } + #ifdef ENABLE_E131 + if (mode == E131) { + handleE131(); + } + #endif #endif if (mode == HOLD || mode == CUSTOM) { if(!strip.isRunning()) strip.start(); diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index 44bc8eb..4b76888 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -16,7 +16,13 @@ const char HOSTNAME[] = "McLighting01"; // Friedly hostname #define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT or ENABLE_AMQTT must be active #define ENABLE_BUTTON // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control //#define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth -#define ENABLE_LEGACY_ANIMATIONS +#define ENABLE_LEGACY_ANIMATIONS // Dont disbale this for now +#define ENABLE_E131 // E1.31 implementation + +#ifdef ENABLE_E131 + #define UNIVERSE 1 // First DMX Universe to listen for + #define UNIVERSE_COUNT 7 // Total number of Universes to listen for, starting at UNIVERSE +#endif //#define WIFIMGR_PORTAL_TIMEOUT 180 //#define WIFIMGR_SET_MANUAL_IP @@ -104,7 +110,11 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds) // List of all color modes #ifdef ENABLE_LEGACY_ANIMATIONS - enum MODE { SET_MODE, HOLD, OFF, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW, TV, CUSTOM }; + #ifdef ENABLE_E131 + enum MODE { SET_MODE, HOLD, OFF, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW, TV, CUSTOM, E131 }; + #else + enum MODE { SET_MODE, HOLD, OFF, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW, TV, CUSTOM }; + #endif MODE mode = RAINBOW; // Standard mode that is active when software starts bool exit_func = false; // Global helper variable to get out of the color modes when mode changes #else diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index bb10c1f..b91bd83 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -1,6 +1,38 @@ // *************************************************************************** // Request handlers // *************************************************************************** +#ifdef ENABLE_E131 +void handleE131(){ + if (!e131.isEmpty()) + { + e131_packet_t packet; + e131.pull(&packet); // Pull packet from ring buffer + + uint16_t universe = htons(packet.universe); + uint8_t *data = packet.property_values + 1; + + if (!e131.stats.num_packets || universe < UNIVERSE || universe > UNIVERSE_COUNT) return; + + // Serial.printf("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH1: %u\n", + // 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 + // packet.property_values[1]); // Dimmer data for Channel 1 + + uint16_t len = e131.stats.num_packets / 3; + uint16_t multipacketOffset = (universe - UNIVERSE) * 170; //if more than 170 LEDs (510 channels), client will send in next higher universe + if (NUMLEDS <= multipacketOffset) return; + if (len + multipacketOffset > NUMLEDS) len = NUMLEDS - multipacketOffset; + for (uint16_t i = 0; i < len; i++){ + uint16_t j = i * 3; + strip.setPixelColor(i, data[j], data[j + 1], data[j + 2]); + } + strip.show(); + } +} +#endif + #ifdef ENABLE_HOMEASSISTANT void tickerSendState(){ new_ha_mqtt_msg = true; @@ -268,6 +300,18 @@ void setModeByStateString(String saved_state_string) { } #endif +#ifdef ENABLE_E131 + void handleE131NamedMode(String str_mode) { + exit_func = true; + if (str_mode.startsWith("=e131")) { + mode = E131; + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + #endif + } + } +#endif + void handleSetWS2812FXMode(uint8_t * mypayload) { mode = SET_MODE; uint8_t ws2812fx_mode_tmp = (uint8_t) strtol((const char *) &mypayload[1], NULL, 10); @@ -556,6 +600,9 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { String str_mode = String((char *) &payload[0]); handleSetNamedMode(str_mode); + #ifdef ENABLE_E131 + handleE131NamedMode(str_mode); + #endif if (mqtt == true) { DBG_OUTPUT_PORT.print("MQTT: "); } else { @@ -1202,6 +1249,8 @@ bool writeConfigFS(bool saveConfig){ json["mqtt_port"] = mqtt_port; json["mqtt_user"] = mqtt_user; json["mqtt_pass"] = mqtt_pass; + + Serial.printf(">>>>>%s %s %s %s<<<<<<<<<\n", mqtt_host, mqtt_port, mqtt_user, mqtt_pass); // SPIFFS.remove("/config.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file"); File configFile = SPIFFS.open("/config.json", "w"); diff --git a/Arduino/McLighting/version.h b/Arduino/McLighting/version.h index 293818a..81b616b 100644 --- a/Arduino/McLighting/version.h +++ b/Arduino/McLighting/version.h @@ -1 +1 @@ -#define SKETCH_VERSION "2.1.8" +#define SKETCH_VERSION "2.1.9" \ No newline at end of file diff --git a/Arduino/McLighting/version_info.ino b/Arduino/McLighting/version_info.ino index d13e1d7..a2f6942 100644 --- a/Arduino/McLighting/version_info.ino +++ b/Arduino/McLighting/version_info.ino @@ -35,4 +35,7 @@ * 11 Dec 2018 v 2.1.8 * - Fix Auto-Discovery for HA version >= 0.84 #286 * - Fix #283 + * + * 12 Dec 2018 v 2.1.9 + * - Add E1.31 mode */ diff --git a/clients/web/build/index.htm b/clients/web/build/index.htm index 365cbbd..b9dc297 100644 --- a/clients/web/build/index.htm +++ b/clients/web/build/index.htm @@ -130,6 +130,11 @@ <i class="material-icons right">send</i> </a> </div> + <div class="col s12 m6 l6 btn_grid"> + <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="E131">E131 + <i class="material-icons right">send</i> + </a> + </div> <div id="modes"> <div class="input-field col s12"> diff --git a/clients/web/src/index.htm b/clients/web/src/index.htm index 7adb7f0..8ee3614 100644 --- a/clients/web/src/index.htm +++ b/clients/web/src/index.htm @@ -130,6 +130,11 @@ <i class="material-icons right">send</i> </a> </div> + <div class="col s12 m6 l6 btn_grid"> + <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="E131">E131 + <i class="material-icons right">send</i> + </a> + </div> <div id="modes"> <div class="input-field col s12"> diff --git a/platformio.ini b/platformio.ini index 26fa778..20ec3da 100644 --- a/platformio.ini +++ b/platformio.ini @@ -49,7 +49,9 @@ upload_resetmethod = ${common.upload_resetmethod} lib_deps = WiFiManager@0.14 AsyncMqttClient - https://github.com/bblanchon/ArduinoJson.git#v6.6.0-beta + https://github.com/bblanchon/ArduinoJson.git#v6.7.0-beta WS2812FX NeoPixelBus WebSockets + ESPAsyncE131 + ESPAsyncUDP \ No newline at end of file From 1519ba81c42e909fcc30740ed837518e3a0e93f1 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Tue, 11 Dec 2018 22:51:20 -0500 Subject: [PATCH 02/10] Update request_handlers.h --- Arduino/McLighting/request_handlers.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index b91bd83..a0e2eb0 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -1249,8 +1249,6 @@ bool writeConfigFS(bool saveConfig){ json["mqtt_port"] = mqtt_port; json["mqtt_user"] = mqtt_user; json["mqtt_pass"] = mqtt_pass; - - Serial.printf(">>>>>%s %s %s %s<<<<<<<<<\n", mqtt_host, mqtt_port, mqtt_user, mqtt_pass); // SPIFFS.remove("/config.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file"); File configFile = SPIFFS.open("/config.json", "w"); From 35b989e98d3e625e1d08b9339f92461cd7f4ce74 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Wed, 12 Dec 2018 20:46:56 -0500 Subject: [PATCH 03/10] e131 update + HA: sendState() update - Stop strip when e131 is sent - sendState() needs extra memory for jsonBuffer - sensState() effect can be sent directly instead of copying from PROGMEM --- Arduino/McLighting/McLighting.ino | 2 -- Arduino/McLighting/request_handlers.h | 19 +++++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index eb556a0..deb5f0d 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -357,8 +357,6 @@ void setup() { strcpy(mqtt_user, custom_mqtt_user.getValue()); strcpy(mqtt_pass, custom_mqtt_pass.getValue()); - Serial.printf(">>>>>%s %s %s %s<<<<<<<<<\n", mqtt_host, mqtt_port, mqtt_user, mqtt_pass); - //save the custom parameters to FS #if defined(ENABLE_STATE_SAVE_SPIFFS) and (defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)) (writeConfigFS(shouldSaveConfig)) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Save success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Save failure!"); diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index a0e2eb0..c15e9f3 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -304,6 +304,7 @@ void setModeByStateString(String saved_state_string) { void handleE131NamedMode(String str_mode) { exit_func = true; if (str_mode.startsWith("=e131")) { + if(strip.isRunning()) strip.stop(); mode = E131; #ifdef ENABLE_HOMEASSISTANT stateOn = true; @@ -812,7 +813,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght } void sendState() { - const size_t bufferSize = JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6); + const size_t bufferSize = JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 500; DynamicJsonDocument jsonBuffer(bufferSize); JsonObject root = jsonBuffer.to<JsonObject>(); @@ -828,9 +829,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght root["speed"] = ws2812fx_speed; - char modeName[30]; - strncpy_P(modeName, (PGM_P)strip.getModeName(strip.getMode()), sizeof(modeName)); // copy from progmem - root["effect"] = modeName; + //char modeName[30]; + //strncpy_P(modeName, (PGM_P)strip.getModeName(strip.getMode()), sizeof(modeName)); // copy from progmem + root["effect"] = strip.getModeName(strip.getMode()); char buffer[measureJson(root) + 1]; serializeJson(root, buffer, sizeof(buffer)); @@ -1250,7 +1251,7 @@ bool writeConfigFS(bool saveConfig){ json["mqtt_user"] = mqtt_user; json["mqtt_pass"] = mqtt_pass; -// SPIFFS.remove("/config.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file"); + //SPIFFS.remove("/config.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file"); File configFile = SPIFFS.open("/config.json", "w"); if (!configFile) DBG_OUTPUT_PORT.println("failed to open config file for writing"); @@ -1322,7 +1323,7 @@ bool writeStateFS(){ json["green"] = main_color.green; json["blue"] = main_color.blue; -// SPIFFS.remove("/state.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file"); + //SPIFFS.remove("/stripstate.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file"); File configFile = SPIFFS.open("/stripstate.json", "w"); if (!configFile) { DBG_OUTPUT_PORT.println("Failed!"); @@ -1371,6 +1372,12 @@ bool readStateFS() { strip.setSpeed(convertSpeed(ws2812fx_speed)); strip.setBrightness(brightness); strip.setColor(main_color.red, main_color.green, main_color.blue); + + #ifdef ENABLE_E131 + if (mode == E131) { + strip.stop(); + } + #endif updateFS = false; return true; From 26c1996e2a00590063b6034ba43eb5898a5bdd01 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Thu, 13 Dec 2018 11:27:53 -0500 Subject: [PATCH 04/10] keeping up with v 2.1.9 --- Arduino/McLighting/version.h | 2 +- Arduino/McLighting/version_info.ino | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Arduino/McLighting/version.h b/Arduino/McLighting/version.h index 81b616b..510ef45 100644 --- a/Arduino/McLighting/version.h +++ b/Arduino/McLighting/version.h @@ -1 +1 @@ -#define SKETCH_VERSION "2.1.9" \ No newline at end of file +#define SKETCH_VERSION "2.2.0" \ No newline at end of file diff --git a/Arduino/McLighting/version_info.ino b/Arduino/McLighting/version_info.ino index a2f6942..ad04dc2 100644 --- a/Arduino/McLighting/version_info.ino +++ b/Arduino/McLighting/version_info.ino @@ -36,6 +36,13 @@ * - Fix Auto-Discovery for HA version >= 0.84 #286 * - Fix #283 * - * 12 Dec 2018 v 2.1.9 - * - Add E1.31 mode + * 12 Dec 2018 v 2.2.0 + * - Add E1.31 mode initial commit + * - E1.31 mode when activated now stops current animation + * + * 13 Dec 2018 v 2.1.9 + * - HA is not getting the correct animation name being run, boils down to changes to ArduinoJson library + * - Bump ArduinoJson library requirment for v6.7.0-beta (better memory management) + * - sendState() needs extra memory for jsonBuffer + * - sensState() effect can be sent directly instead of copying from PROGMEM */ From 189254afcdf532a8a9a70a833894cb2c767f7cc8 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Thu, 13 Dec 2018 22:02:30 -0500 Subject: [PATCH 05/10] e131 quick fixes - 170 LEDs per universe predefined - >Second universe data fixed - Reduce the number of default universe --- Arduino/McLighting/definitions.h | 2 +- Arduino/McLighting/request_handlers.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index 4b76888..82272ca 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -21,7 +21,7 @@ const char HOSTNAME[] = "McLighting01"; // Friedly hostname #ifdef ENABLE_E131 #define UNIVERSE 1 // First DMX Universe to listen for - #define UNIVERSE_COUNT 7 // Total number of Universes to listen for, starting at UNIVERSE + #define UNIVERSE_COUNT 2 // Total number of Universes to listen for, starting at UNIVERSE #endif //#define WIFIMGR_PORTAL_TIMEOUT 180 diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index c15e9f3..dcfee5d 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -11,7 +11,7 @@ void handleE131(){ uint16_t universe = htons(packet.universe); uint8_t *data = packet.property_values + 1; - if (!e131.stats.num_packets || universe < UNIVERSE || universe > UNIVERSE_COUNT) return; + if (universe < UNIVERSE || universe > UNIVERSE_COUNT) return; //async will take care about filling the buffer // Serial.printf("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH1: %u\n", // htons(packet.universe), // The Universe for this packet @@ -20,13 +20,13 @@ void handleE131(){ // e131.stats.packet_errors, // Packet error counter // packet.property_values[1]); // Dimmer data for Channel 1 - uint16_t len = e131.stats.num_packets / 3; + uint16_t len = 170; // (htons(packet.property_value_count) - 1) /3; uint16_t multipacketOffset = (universe - UNIVERSE) * 170; //if more than 170 LEDs (510 channels), client will send in next higher universe if (NUMLEDS <= multipacketOffset) return; if (len + multipacketOffset > NUMLEDS) len = NUMLEDS - multipacketOffset; for (uint16_t i = 0; i < len; i++){ uint16_t j = i * 3; - strip.setPixelColor(i, data[j], data[j + 1], data[j + 2]); + strip.setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2]); } strip.show(); } From 763b0dab2cbe26fbc695ec16d3b8ef5794eafe68 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Sat, 15 Dec 2018 22:57:43 -0500 Subject: [PATCH 06/10] Update request_handlers.h --- Arduino/McLighting/request_handlers.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index dcfee5d..c9a9062 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -20,10 +20,9 @@ void handleE131(){ // e131.stats.packet_errors, // Packet error counter // packet.property_values[1]); // Dimmer data for Channel 1 - uint16_t len = 170; // (htons(packet.property_value_count) - 1) /3; uint16_t multipacketOffset = (universe - UNIVERSE) * 170; //if more than 170 LEDs (510 channels), client will send in next higher universe if (NUMLEDS <= multipacketOffset) return; - if (len + multipacketOffset > NUMLEDS) len = NUMLEDS - multipacketOffset; + uint16_t len = (170 + multipacketOffset > NUMLEDS) ? (NUMLEDS - multipacketOffset) : 170; for (uint16_t i = 0; i < len; i++){ uint16_t j = i * 3; strip.setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2]); From 1c80fefd7eedc0f97e96fd6fced69463974db213 Mon Sep 17 00:00:00 2001 From: Tobias Blum <github@tobiasblum.de> Date: Sun, 16 Dec 2018 16:14:21 +0100 Subject: [PATCH 07/10] =e131 mode payload has to be lowercase. --- clients/web/build/index.htm | 2 +- clients/web/src/index.htm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/web/build/index.htm b/clients/web/build/index.htm index b9dc297..a9bbaac 100644 --- a/clients/web/build/index.htm +++ b/clients/web/build/index.htm @@ -131,7 +131,7 @@ </a> </div> <div class="col s12 m6 l6 btn_grid"> - <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="E131">E131 + <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="e131">E131 <i class="material-icons right">send</i> </a> </div> diff --git a/clients/web/src/index.htm b/clients/web/src/index.htm index 8ee3614..86f262c 100644 --- a/clients/web/src/index.htm +++ b/clients/web/src/index.htm @@ -131,7 +131,7 @@ </a> </div> <div class="col s12 m6 l6 btn_grid"> - <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="E131">E131 + <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="e131">E131 <i class="material-icons right">send</i> </a> </div> From 00ff5c3aeecb1e0949b3fe42074739502ba65e00 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Mon, 24 Dec 2018 00:25:05 -0500 Subject: [PATCH 08/10] update getModes() - Add E1.31 mode to getModes(), no need to change McLightingUI - "=e131" and "/e131" will activate E131 mode via websockets or MQTT - Reverted McLightingUI back to stock --- Arduino/McLighting/request_handlers.h | 21 ++++++++++++++------- Arduino/McLighting/version_info.ino | 10 ++++++++++ clients/web/build/index.htm | 5 ----- clients/web/src/index.htm | 5 ----- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index c9a9062..47efd63 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -302,7 +302,7 @@ void setModeByStateString(String saved_state_string) { #ifdef ENABLE_E131 void handleE131NamedMode(String str_mode) { exit_func = true; - if (str_mode.startsWith("=e131")) { + if (str_mode.startsWith("=e131") or str_mode.startsWith("/e131")) { if(strip.isRunning()) strip.stop(); mode = E131; #ifdef ENABLE_HOMEASSISTANT @@ -321,7 +321,7 @@ void handleSetWS2812FXMode(uint8_t * mypayload) { String listStatusJSON(void) { uint8_t tmp_mode = (mode == SET_MODE) ? (uint8_t) ws2812fx_mode : strip.getMode(); - const size_t bufferSize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(6); + const size_t bufferSize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(6) + 500; DynamicJsonDocument jsonBuffer(bufferSize); JsonObject root = jsonBuffer.to<JsonObject>(); root["mode"] = (uint8_t) mode; @@ -346,9 +346,14 @@ void getStatusJSON() { } String listModesJSON(void) { - const size_t bufferSize = JSON_ARRAY_SIZE(strip.getModeCount()+1) + strip.getModeCount()*JSON_OBJECT_SIZE(2); + const size_t bufferSize = JSON_ARRAY_SIZE(strip.getModeCount()+1) + strip.getModeCount()*JSON_OBJECT_SIZE(2) + 1000; DynamicJsonDocument jsonBuffer(bufferSize); JsonArray json = jsonBuffer.to<JsonArray>(); + #ifdef ENABLE_E131 + JsonObject objecte131 = json.createNestedObject(); + objecte131["mode"] = "e131"; + objecte131["name"] = "E131"; + #endif for (uint8_t i = 0; i < strip.getModeCount(); i++) { JsonObject object = json.createNestedObject(); object["mode"] = i; @@ -675,6 +680,10 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { // / ==> Set WS2812 mode. if (payload[0] == '/') { handleSetWS2812FXMode(payload); + #ifdef ENABLE_E131 + String str_mode = String((char *) &payload[0]); + handleE131NamedMode(str_mode); + #endif if (mqtt == true) { DBG_OUTPUT_PORT.print("MQTT: "); } else { @@ -983,11 +992,10 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght ha_send_data.detach(); mqtt_client.subscribe(mqtt_ha_state_in.c_str(), qossub); #ifdef MQTT_HOME_ASSISTANT_SUPPORT - DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(12)); + DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(12) + 1500); JsonObject json = jsonBuffer.to<JsonObject>(); json["name"] = HOSTNAME; #ifdef MQTT_HOME_ASSISTANT_0_84_SUPPORT - json["platform"] = "mqtt"; json["schema"] = "json"; #else json["platform"] = "mqtt_json"; @@ -1068,11 +1076,10 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght uint16_t packetIdSub2 = amqttClient.subscribe((char *)mqtt_ha_state_in.c_str(), qossub); DBG_OUTPUT_PORT.printf("Subscribing at QoS %d, packetId: ", qossub); DBG_OUTPUT_PORT.println(packetIdSub2); #ifdef MQTT_HOME_ASSISTANT_SUPPORT - DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(12)); + DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(12) + 1500); JsonObject json = jsonBuffer.to<JsonObject>(); json["name"] = HOSTNAME; #ifdef MQTT_HOME_ASSISTANT_0_84_SUPPORT - json["platform"] = "mqtt"; json["schema"] = "json"; #else json["platform"] = "mqtt_json"; diff --git a/Arduino/McLighting/version_info.ino b/Arduino/McLighting/version_info.ino index ad04dc2..ebd91fb 100644 --- a/Arduino/McLighting/version_info.ino +++ b/Arduino/McLighting/version_info.ino @@ -45,4 +45,14 @@ * - Bump ArduinoJson library requirment for v6.7.0-beta (better memory management) * - sendState() needs extra memory for jsonBuffer * - sensState() effect can be sent directly instead of copying from PROGMEM + * + * 16 Dec 2018 v 2.1.10 + * - more ArduinoJson library memory managment fixes + * + * 18 Dec 2018 v 2.1.11 + * - More Auto-Discovery fix for HA version >= 0.84 #286 + * - Suggestions from https://github.com/home-assistant/home-assistant/issues/19420 + * + * 23 Dec 2018 v 2.2.0 + * - Add E1.31 mode to getModes(), no need to change McLightingUI */ diff --git a/clients/web/build/index.htm b/clients/web/build/index.htm index a9bbaac..365cbbd 100644 --- a/clients/web/build/index.htm +++ b/clients/web/build/index.htm @@ -130,11 +130,6 @@ <i class="material-icons right">send</i> </a> </div> - <div class="col s12 m6 l6 btn_grid"> - <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="e131">E131 - <i class="material-icons right">send</i> - </a> - </div> <div id="modes"> <div class="input-field col s12"> diff --git a/clients/web/src/index.htm b/clients/web/src/index.htm index 86f262c..7adb7f0 100644 --- a/clients/web/src/index.htm +++ b/clients/web/src/index.htm @@ -130,11 +130,6 @@ <i class="material-icons right">send</i> </a> </div> - <div class="col s12 m6 l6 btn_grid"> - <a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="e131">E131 - <i class="material-icons right">send</i> - </a> - </div> <div id="modes"> <div class="input-field col s12"> From 2551240e634a77b1896ba63c0bfa79b1c543ee55 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Sun, 6 Jan 2019 15:19:14 -0500 Subject: [PATCH 09/10] UART methods & HA 1.31 support - Update UART 1 and 2 methods for NeoPixelBus v2.4.1 - HA E1.31 support --- Arduino/McLighting/McLighting.ino | 14 ++++++++----- Arduino/McLighting/definitions.h | 7 ++++--- Arduino/McLighting/request_handlers.h | 29 ++++++++++++++++++++++++--- clients/HomeAssistant/light.yaml | 5 +++-- platformio.ini | 2 +- 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index deb5f0d..3806f66 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -61,7 +61,7 @@ #ifdef ENABLE_E131 #include <ESPAsyncUDP.h> //https://github.com/me-no-dev/ESPAsyncUDP #include <ESPAsyncE131.h> //https://github.com/forkineye/ESPAsyncE131 - ESPAsyncE131 e131(UNIVERSE_COUNT); + ESPAsyncE131 e131(END_UNIVERSE - START_UNIVERSE + 1); #endif @@ -96,14 +96,18 @@ WS2812FX strip = WS2812FX(NUMLEDS, PIN, NEO_GRB + NEO_KHZ800); // and minimize distance between Arduino and first pixel. Avoid connecting // on a live circuit...if you must, connect GND first. -#ifdef USE_WS2812FX_DMA +#ifdef USE_WS2812FX_DMA // Uses GPIO3/RXD0/RX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #include <NeoPixelBus.h> NeoEsp8266Dma800KbpsMethod dma = NeoEsp8266Dma800KbpsMethod(NUMLEDS, 3); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) //NeoEsp8266Dma400KbpsMethod dma = NeoEsp8266Dma400KbpsMethod(NUMLEDS, 3); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) #endif -#ifdef USE_WS2812FX_UART +#ifdef USE_WS2812FX_UART1 // Uses UART1: GPIO1/TXD0/TX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods #include <NeoPixelBus.h> - NeoEsp8266Uart800KbpsMethod dma = NeoEsp8266Uart800KbpsMethod(NUMLEDS, 3); + NeoEsp8266Uart0800KbpsMethod dma = NeoEsp8266Uart0800KbpsMethod(NUMLEDS, 3); +#endif +#ifdef USE_WS2812FX_UART2 // Uses UART2: GPIO2/TXD1/D4, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods + #include <NeoPixelBus.h> + NeoEsp8266Uart1800KbpsMethod dma = NeoEsp8266Uart1800KbpsMethod(NUMLEDS, 3); #endif #if defined(USE_WS2812FX_DMA) or defined(USE_WS2812FX_UART) void DMA_Show(void) { @@ -925,7 +929,7 @@ void setup() { #ifdef ENABLE_E131 // Choose one to begin listening for E1.31 data // if (e131.begin(E131_UNICAST)) // Listen via Unicast - if (e131.begin(E131_MULTICAST, UNIVERSE, UNIVERSE_COUNT)) // Listen via Multicast + if (e131.begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) // Listen via Multicast Serial.println(F("Listening for data...")); else Serial.println(F("*** e131.begin failed ***")); diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index 82272ca..d54de2b 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -1,5 +1,6 @@ //#define USE_WS2812FX_DMA // Uses PIN is ignored & set to RX/GPIO3 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX -//#define USE_WS2812FX_UART // Uses PIN is ignored & set to D4/GPIO2 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX +//#define USE_WS2812FX_UART1 // Uses PIN is ignored & set to D4/GPIO2 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX +//#define USE_WS2812FX_UART2 // Uses PIN is ignored & set to TX/GPIO1 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX // Neopixel #define PIN 14 // PIN (14 / D5) where neopixel / WS2811 strip is attached @@ -20,8 +21,8 @@ const char HOSTNAME[] = "McLighting01"; // Friedly hostname #define ENABLE_E131 // E1.31 implementation #ifdef ENABLE_E131 - #define UNIVERSE 1 // First DMX Universe to listen for - #define UNIVERSE_COUNT 2 // Total number of Universes to listen for, starting at UNIVERSE + #define START_UNIVERSE 1 // First DMX Universe to listen for + #define END_UNIVERSE 2 // Total number of Universes to listen for, starting at UNIVERSE #endif //#define WIFIMGR_PORTAL_TIMEOUT 180 diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index 47efd63..7c62099 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -2,6 +2,8 @@ // Request handlers // *************************************************************************** #ifdef ENABLE_E131 +void checkForRequests(void); //prototype + void handleE131(){ if (!e131.isEmpty()) { @@ -11,7 +13,7 @@ void handleE131(){ uint16_t universe = htons(packet.universe); uint8_t *data = packet.property_values + 1; - if (universe < UNIVERSE || universe > UNIVERSE_COUNT) return; //async will take care about filling the buffer + if (universe < START_UNIVERSE || universe > END_UNIVERSE) return; //async will take care about filling the buffer // Serial.printf("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH1: %u\n", // htons(packet.universe), // The Universe for this packet @@ -20,7 +22,7 @@ void handleE131(){ // e131.stats.packet_errors, // Packet error counter // packet.property_values[1]); // Dimmer data for Channel 1 - uint16_t multipacketOffset = (universe - UNIVERSE) * 170; //if more than 170 LEDs (510 channels), client will send in next higher universe + uint16_t multipacketOffset = (universe - START_UNIVERSE) * 170; //if more than 170 LEDs (510 channels), client will send in next higher universe if (NUMLEDS <= multipacketOffset) return; uint16_t len = (170 + multipacketOffset > NUMLEDS) ? (NUMLEDS - multipacketOffset) : 170; for (uint16_t i = 0; i < len; i++){ @@ -28,6 +30,7 @@ void handleE131(){ strip.setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2]); } strip.show(); + checkForRequests(); } } #endif @@ -839,7 +842,14 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght //char modeName[30]; //strncpy_P(modeName, (PGM_P)strip.getModeName(strip.getMode()), sizeof(modeName)); // copy from progmem - root["effect"] = strip.getModeName(strip.getMode()); + #if defined(ENABLE_E131) and defined(ENABLE_HOMEASSISTANT) + if (mode == E131) + root["effect"] = "E131"; + else + root["effect"] = strip.getModeName(strip.getMode()); + #else + root["effect"] = strip.getModeName(strip.getMode()); + #endif char buffer[measureJson(root) + 1]; serializeJson(root, buffer, sizeof(buffer)); @@ -918,6 +928,13 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght String effectString = root["effect"].as<String>(); for (uint8_t i = 0; i < strip.getModeCount(); i++) { + #if defined(ENABLE_E131) and defined(ENABLE_HOMEASSISTANT) + if(effectString == "E131"){ + if(strip.isRunning()) strip.stop(); + mode = E131; + break; + } + #endif if(String(strip.getModeName(i)) == effectString) { mode = SET_MODE; ws2812fx_mode = i; @@ -1012,6 +1029,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght for (uint8_t i = 0; i < strip.getModeCount(); i++) { effect_list.add(strip.getModeName(i)); } + #if defined(ENABLE_E131) and defined(MQTT_HOME_ASSISTANT_SUPPORT) + effect_list.add("E131"); + #endif char buffer[measureJson(json) + 1]; serializeJson(json, buffer, sizeof(buffer)); mqtt_client.publish(String("homeassistant/light/" + String(HOSTNAME) + "/config").c_str(), buffer, true); @@ -1096,6 +1116,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght for (uint8_t i = 0; i < strip.getModeCount(); i++) { effect_list.add(strip.getModeName(i)); } + #if defined(ENABLE_E131) and defined(MQTT_HOME_ASSISTANT_SUPPORT) + effect_list.add("E131"); + #endif char buffer[measureJson(json) + 1]; serializeJson(json, buffer, sizeof(buffer)); DBG_OUTPUT_PORT.println(buffer); diff --git a/clients/HomeAssistant/light.yaml b/clients/HomeAssistant/light.yaml index 91c201f..a5c4e3c 100644 --- a/clients/HomeAssistant/light.yaml +++ b/clients/HomeAssistant/light.yaml @@ -63,6 +63,7 @@ light: - "Bicolor Chase" - "Tricolor Chase" - "ICU" + - "E131" brightness: true color_temp: true rgb: true @@ -79,7 +80,7 @@ input_number: step: 5 automation: - - id: 71938579813759813757 + - id: "71938579813759813757" alias: NeoPixel Animation Speed Send initial_state: true hide_entity: false @@ -93,7 +94,7 @@ automation: topic: home/McLighting01_ha/state/in service: mqtt.publish - - id: 93786598732698756967 + - id: "93786598732698756967" alias: NeoPixel Animation Speed Receive trigger: - platform: mqtt diff --git a/platformio.ini b/platformio.ini index 20ec3da..13570e8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -51,7 +51,7 @@ lib_deps = AsyncMqttClient https://github.com/bblanchon/ArduinoJson.git#v6.7.0-beta WS2812FX - NeoPixelBus + NeoPixelBus@2.4.1 WebSockets ESPAsyncE131 ESPAsyncUDP \ No newline at end of file From a78f4882e0e218134a0eb817b4e9a94dc166b9e3 Mon Sep 17 00:00:00 2001 From: Debashish Sahu <debashish.sahu@gmail.com> Date: Sun, 6 Jan 2019 15:27:06 -0500 Subject: [PATCH 10/10] Travis CI - Added Travis CI support --- .travis.yml | 14 ++++++++++++++ Arduino/McLighting/version_info.ino | 4 ++++ README.md | 2 +- platformio.ini | 2 -- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9a80a94 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: python +python: + - "2.7" +sudo: false +cache: + directories: + - "~/.platformio" +env: + - PLATFORMIO_CI_SRC=Arduino/McLighting +install: + - pip install -U platformio + - platformio update +script: + - platformio ci --project-conf=./platformio.ini -v \ No newline at end of file diff --git a/Arduino/McLighting/version_info.ino b/Arduino/McLighting/version_info.ino index ebd91fb..8364126 100644 --- a/Arduino/McLighting/version_info.ino +++ b/Arduino/McLighting/version_info.ino @@ -55,4 +55,8 @@ * * 23 Dec 2018 v 2.2.0 * - Add E1.31 mode to getModes(), no need to change McLightingUI + * + * 6 Jan 2018 v 2.2.0 + * - fix webserver not responding when E1.31 is mode is acivated: do a webserver.loop() for every 1.31 packet + * - HA E1.31 mode added */ diff --git a/README.md b/README.md index 970e775..99ff7af 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # McLighting v2 - The ESP8266 based multi-client lighting gadget -[](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +[](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [](https://travis-ci.com/toblum/McLighting) [](https://opensource.org/licenses/MIT) [](https://github.com/toblum/McLighting/blob/master/Arduino/McLighting/version.h) > Mc Lighting (the multi-client lighting gadget) is a very cheap internet-controllable lighting solution based on the famous ESP8266 microcontroller and WS2811/2812 led strips. It features a self-hosted responsive web-interface, a REST-API and a websocket connector. diff --git a/platformio.ini b/platformio.ini index 13570e8..7959436 100644 --- a/platformio.ini +++ b/platformio.ini @@ -44,8 +44,6 @@ monitor_speed = ${common.monitor_speed} upload_speed = ${common.upload_speed} upload_resetmethod = ${common.upload_resetmethod} - - lib_deps = WiFiManager@0.14 AsyncMqttClient