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
 
-[![Gitter](https://badges.gitter.im/mclighting/Lobby.svg)](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+[![Gitter](https://badges.gitter.im/mclighting/Lobby.svg)](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Build Status](https://travis-ci.com/toblum/McLighting.svg?branch=master)](https://travis-ci.com/toblum/McLighting) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![version](https://img.shields.io/badge/version-v2.2.0-blue.svg)](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