diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index 3e4423b..6f2d6da 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -1,5 +1,5 @@ #include "definitions.h" - +#include "version.h" // *************************************************************************** // Load libraries for: WebServer / WiFiManager / WebSockets // *************************************************************************** @@ -483,17 +483,53 @@ void setup() { //first callback is called after the request has ended with all parsed arguments //second callback handles file uploads at that location server.on("/edit", HTTP_POST, []() { + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", ""); }, handleFileUpload); //get heap status, analog input value and all GPIO statuses in one json call server.on("/esp_status", HTTP_GET, []() { - String json = "{"; - json += "\"heap\":" + String(ESP.getFreeHeap()); - // json += ", \"analog\":" + String(analogRead(A0)); - // json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16))); - json += "}"; - server.send(200, "text/json", json); - json = String(); + //String json = "{"; + //json += "\"heap\":" + String(ESP.getFreeHeap()); + //// json += ", \"analog\":" + String(analogRead(A0)); + //// json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16))); + //json += "}"; + + DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(9)); + JsonObject& json = jsonBuffer.createObject(); + + json["HOSTNAME"] = HOSTNAME; + json["version"] = SKETCH_VERSION; + json["heap"] = ESP.getFreeHeap(); + #ifndef USE_NEOANIMATIONFX + json["animation_lib"] = "WS2812FX"; + json["pin"] = PIN; + #else + json["animation_lib"] = "NeoAnimationFX"; + json["pin"] = "Ignored, check NEOMETHOD"; + #endif + json["number_leds"] = NUMLEDS; + #ifdef ENABLE_BUTTON + json["button_mode"] = "ON"; + #else + json["button_mode"] = "OFF"; + #endif + #ifdef ENABLE_AMQTT + json["mqtt"] = "ON"; + #else + json["mqtt"] = "OFF"; + #endif + #ifdef ENABLE_HOMEASSISTANT + json["home_assistant"] = "ON"; + #else + json["home_assistant"] = "OFF"; + #endif + //char buffer[json.measureLength() + 1]; + //json.printTo(buffer, sizeof(buffer)); + String json_str; + json.printTo(json_str); + server.sendHeader("Access-Control-Allow-Origin", "*"); + server.send(200, "application/json", json_str); + //json_str = String(); }); @@ -508,12 +544,14 @@ void setup() { server.on("/restart", []() { DBG_OUTPUT_PORT.printf("/restart\n"); + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", "restarting..." ); ESP.restart(); }); server.on("/reset_wlan", []() { DBG_OUTPUT_PORT.printf("/reset_wlan\n"); + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", "Resetting WLAN and restarting..." ); WiFiManager wifiManager; wifiManager.resetSettings(); @@ -522,6 +560,7 @@ void setup() { server.on("/start_config_ap", []() { DBG_OUTPUT_PORT.printf("/start_config_ap\n"); + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", "Starting config AP ..." ); WiFiManager wifiManager; wifiManager.startConfigPortal(HOSTNAME); @@ -552,6 +591,7 @@ void setup() { server.on("/get_brightness", []() { String str_brightness = String((int) (brightness / 2.55)); + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", str_brightness ); DBG_OUTPUT_PORT.print("/get_brightness: "); DBG_OUTPUT_PORT.println(str_brightness); @@ -578,12 +618,14 @@ void setup() { server.on("/get_speed", []() { String str_speed = String(ws2812fx_speed); + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", str_speed ); DBG_OUTPUT_PORT.print("/get_speed: "); DBG_OUTPUT_PORT.println(str_speed); }); server.on("/get_switch", []() { + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", (mode == OFF) ? "0" : "1" ); DBG_OUTPUT_PORT.printf("/get_switch: %s\n", (mode == OFF) ? "0" : "1"); }); @@ -591,6 +633,7 @@ void setup() { server.on("/get_color", []() { char rgbcolor[7]; snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X", main_color.red, main_color.green, main_color.blue); + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", rgbcolor ); DBG_OUTPUT_PORT.print("/get_color: "); DBG_OUTPUT_PORT.println(rgbcolor); @@ -873,6 +916,7 @@ void loop() { if (mode == SET_MODE) { DBG_OUTPUT_PORT.printf("SET_MODE: %d %d\n", ws2812fx_mode, mode); strip.setMode(ws2812fx_mode); + strip.trigger(); prevmode = SET_MODE; mode = SETCOLOR; } @@ -882,43 +926,52 @@ void loop() { } if (mode == SETCOLOR) { strip.setColor(main_color.red, main_color.green, main_color.blue); + strip.trigger(); mode = (prevmode == SET_MODE) ? SETSPEED : HOLD; } if (mode == SETSPEED) { strip.setSpeed(convertSpeed(ws2812fx_speed)); + strip.trigger(); mode = (prevmode == SET_MODE) ? BRIGHTNESS : HOLD; } if (mode == BRIGHTNESS) { strip.setBrightness(brightness); - if (prevmode == SET_MODE) prevmode == HOLD; + strip.trigger(); + if (prevmode == SET_MODE) prevmode = HOLD; mode = HOLD; } #ifdef ENABLE_LEGACY_ANIMATIONS if (mode == WIPE) { strip.setColor(main_color.red, main_color.green, main_color.blue); strip.setMode(FX_MODE_COLOR_WIPE); + strip.trigger(); mode = HOLD; } if (mode == RAINBOW) { strip.setMode(FX_MODE_RAINBOW); + strip.trigger(); mode = HOLD; } if (mode == RAINBOWCYCLE) { strip.setMode(FX_MODE_RAINBOW_CYCLE); + strip.trigger(); mode = HOLD; } if (mode == THEATERCHASE) { strip.setColor(main_color.red, main_color.green, main_color.blue); strip.setMode(FX_MODE_THEATER_CHASE); + strip.trigger(); mode = HOLD; } if (mode == TWINKLERANDOM) { strip.setColor(main_color.red, main_color.green, main_color.blue); strip.setMode(FX_MODE_TWINKLE_RANDOM); + strip.trigger(); mode = HOLD; } if (mode == THEATERCHASERAINBOW) { strip.setMode(FX_MODE_THEATER_CHASE_RAINBOW); + strip.trigger(); mode = HOLD; } #endif diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index fbc2c0b..a41fb48 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -30,6 +30,9 @@ const char HOSTNAME[] = "McLighting01"; // Friedly hostname #if ( (defined(ENABLE_HOMEASSISTANT) and !defined(ENABLE_MQTT)) and (defined(ENABLE_HOMEASSISTANT) and !defined(ENABLE_AMQTT)) ) #error "To use HA, you have to either enable PubCubClient or AsyncMQTT" #endif +#if ( !defined(ENABLE_HOMEASSISTANT) and defined(MQTT_HOME_ASSISTANT_SUPPORT) ) +#error "To use HA support, you have to either enable Homeassistant component" +#endif // parameters for automatically cycling favorite patterns uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds) diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index 7f42e47..fc6a85a 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -278,35 +278,72 @@ void handleSetWS2812FXMode(uint8_t * mypayload) { ws2812fx_mode = constrain(ws2812fx_mode_tmp, 0, strip.getModeCount() - 1); } -char* listStatusJSON() { - char json[255]; - char modeName[30]; +String listStatusJSON(void) { + //char json[255]; + //char modeName[30]; uint8_t tmp_mode = (mode == SET_MODE) ? (uint8_t) ws2812fx_mode : strip.getMode(); - strncpy_P(modeName, (PGM_P)strip.getModeName(tmp_mode), sizeof(modeName)); // copy from progmem - snprintf(json, sizeof(json), "{\"mode\":%d, \"ws2812fx_mode\":%d, \"ws2812fx_mode_name\":\"%s\", \"speed\":%d, \"brightness\":%d, \"color\":[%d, %d, %d]}", - mode, tmp_mode, modeName, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue); + //strncpy_P(modeName, (PGM_P)strip.getModeName(tmp_mode), sizeof(modeName)); // copy from progmem + + //snprintf(json, sizeof(json), "{\"mode\":%d, \"ws2812fx_mode\":%d, \"ws2812fx_mode_name\":\"%s\", \"speed\":%d, \"brightness\":%d, \"color\":[%d, %d, %d]}", + // mode, tmp_mode, modeName, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue); + + const size_t bufferSize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(6); + DynamicJsonBuffer jsonBuffer(bufferSize); + JsonObject& root = jsonBuffer.createObject(); + root["mode"] = (uint8_t) mode; + root["ws2812fx_mode"] = tmp_mode; + root["ws2812fx_mode_name"] = strip.getModeName(tmp_mode); + root["speed"] = ws2812fx_speed; + root["brightness"] = brightness; + JsonArray& color = root.createNestedArray("color"); + color.add(main_color.red); + color.add(main_color.green); + color.add(main_color.blue); + +// char* json = (char*) malloc(root.measureLength() + 1); +// root.printTo(json, sizeof(json)); + + String json; + root.printTo(json); + return json; } void getStatusJSON() { + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send ( 200, "application/json", listStatusJSON() ); } -String listModesJSON() { - String modes = "["; +String listModesJSON(void) { +// String modes = "["; +// for (uint8_t i = 0; i < strip.getModeCount(); i++) { +// modes += "{\"mode\":"; +// modes += i; +// modes += ", \"name\":\""; +// modes += strip.getModeName(i); +// modes += "\"},"; +// } +// modes += "{}]"; +// return modes; + + const size_t bufferSize = JSON_ARRAY_SIZE(strip.getModeCount()+1) + strip.getModeCount()*JSON_OBJECT_SIZE(2); + DynamicJsonBuffer jsonBuffer(bufferSize); + JsonArray& json = jsonBuffer.createArray(); for (uint8_t i = 0; i < strip.getModeCount(); i++) { - modes += "{\"mode\":"; - modes += i; - modes += ", \"name\":\""; - modes += strip.getModeName(i); - modes += "\"},"; + JsonObject& object = json.createNestedObject(); + object["mode"] = i; + object["name"] = strip.getModeName(i); } - modes += "{}]"; - return modes; + JsonObject& object = json.createNestedObject(); + + String json_str; + json.printTo(json_str); + return json_str; } void getModesJSON() { + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send ( 200, "application/json", listModesJSON() ); } @@ -333,7 +370,8 @@ void handleMinimalUpload() { \ \ " - ); + ); + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send ( 200, "text/html", temp ); } @@ -379,6 +417,264 @@ void handleAutoStop() { strip.stop(); } +void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { + // # ==> Set main color + if (payload[0] == '#') { + handleSetMainColor(payload); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Set main color to: R: [%u] G: [%u] B: [%u]\n", main_color.red, main_color.green, main_color.blue); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + } + + // ? ==> Set speed + if (payload[0] == '?') { + uint8_t d = (uint8_t) strtol((const char *) &payload[1], NULL, 10); + ws2812fx_speed = constrain(d, 0, 255); + mode = SETSPEED; + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Set speed to: [%u]\n", ws2812fx_speed); + #ifdef ENABLE_HOMEASSISTANT + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + } + + // % ==> Set brightness + if (payload[0] == '%') { + uint8_t b = (uint8_t) strtol((const char *) &payload[1], NULL, 10); + brightness = constrain(b, 0, 255); + mode = BRIGHTNESS; + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("WS: Set brightness to: [%u]\n", brightness); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + } + + // * ==> Set main color and light all LEDs (Shortcut) + if (payload[0] == '*') { + handleSetAllMode(payload); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Set main color and light all LEDs [%s]\n", payload); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + } + + // ! ==> Set single LED in given color + if (payload[0] == '!') { + handleSetSingleLED(payload, 1); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Set single LED in given color [%s]\n", payload); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + } + + // + ==> Set multiple LED in the given colors + if (payload[0] == '+') { + handleSetDifferentColors(payload); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Set multiple LEDs in given color [%s]\n", payload); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + } + + // + ==> Set range of LEDs in the given color + if (payload[0] == 'R') { + handleRangeDifferentColors(payload); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Set range of LEDs in given color [%s]\n", payload); + webSocket.sendTXT(num, "OK"); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + } + + #ifdef ENABLE_LEGACY_ANIMATIONS + // = ==> Activate named mode + if (payload[0] == '=') { + // we get mode data + String str_mode = String((char *) &payload[0]); + + handleSetNamedMode(str_mode); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Activated mode [%u]!\n", mode); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_HOMEASSISTANT + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + } + #endif + + // $ ==> Get status Info. + if (payload[0] == '$') { + String json = listStatusJSON(); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, json.c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, json.c_str()); + #endif + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + webSocket.sendTXT(num, json); + } + DBG_OUTPUT_PORT.println("Get status info: " + json); + } + + // ~ ==> Get WS2812 modes. + if (payload[0] == '~') { + String json = listModesJSON(); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + #ifdef ENABLE_MQTT + // TODO: Fix this, doesn't return anything. Too long? + // Hint: https://github.com/knolleary/pubsubclient/issues/110 + DBG_OUTPUT_PORT.printf("Error: Not implemented. Message too large for pubsubclient."); + mqtt_client.publish(mqtt_outtopic, "ERROR: Not implemented. Message too large for pubsubclient."); + //String json_modes = listModesJSON(); + //DBG_OUTPUT_PORT.printf(json_modes.c_str()); + + //int res = mqtt_client.publish(mqtt_outtopic, json_modes.c_str(), json_modes.length()); + //DBG_OUTPUT_PORT.printf("Result: %d / %d", res, json_modes.length()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, json.c_str()); + #endif + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + webSocket.sendTXT(num, json); + } + DBG_OUTPUT_PORT.println("Get WS2812 modes."); + DBG_OUTPUT_PORT.println(json); + } + + // / ==> Set WS2812 mode. + if (payload[0] == '/') { + handleSetWS2812FXMode(payload); + if (mqtt == true) { + DBG_OUTPUT_PORT.print("MQTT: "); + } else { + DBG_OUTPUT_PORT.print("WS: "); + webSocket.sendTXT(num, "OK"); + } + DBG_OUTPUT_PORT.printf("Set WS2812 mode: [%s]\n", payload); + #ifdef ENABLE_MQTT + mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif + } +} + // *************************************************************************** // WS request handlers // *************************************************************************** @@ -400,201 +696,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght case WStype_TEXT: DBG_OUTPUT_PORT.printf("WS: [%u] get Text: %s\n", num, payload); - // # ==> Set main color - if (payload[0] == '#') { - handleSetMainColor(payload); - DBG_OUTPUT_PORT.printf("Set main color to: [%u] [%u] [%u]\n", main_color.red, main_color.green, main_color.blue); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - - // ? ==> Set speed - if (payload[0] == '?') { - uint8_t d = (uint8_t) strtol((const char *) &payload[1], NULL, 10); - ws2812fx_speed = constrain(d, 0, 255); - strip.setSpeed(convertSpeed(ws2812fx_speed)); - DBG_OUTPUT_PORT.printf("WS: Set speed to: [%u]\n", ws2812fx_speed); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_HOMEASSISTANT - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - // % ==> Set brightness - if (payload[0] == '%') { - uint8_t b = (uint8_t) strtol((const char *) &payload[1], NULL, 10); - brightness = ((b >> 0) & 0xFF); - DBG_OUTPUT_PORT.printf("WS: Set brightness to: [%u]\n", brightness); - strip.setBrightness(brightness); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - - // * ==> Set main color and light all LEDs (Shortcut) - if (payload[0] == '*') { - handleSetAllMode(payload); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - - // ! ==> Set single LED in given color - if (payload[0] == '!') { - handleSetSingleLED(payload, 1); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - // + ==> Set multiple LED in the given colors - if (payload[0] == '+') { - handleSetDifferentColors(payload); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - // + ==> Set range of LEDs in the given color - if (payload[0] == 'R') { - handleRangeDifferentColors(payload); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - #ifdef ENABLE_LEGACY_ANIMATIONS - // = ==> Activate named mode - if (payload[0] == '=') { - // we get mode data - String str_mode = String((char *) &payload[0]); - - handleSetNamedMode(str_mode); - - DBG_OUTPUT_PORT.printf("Activated mode [%u]!\n", mode); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - #endif - - // $ ==> Get status Info. - if (payload[0] == '$') { - DBG_OUTPUT_PORT.printf("Get status info."); - - String json = listStatusJSON(); - DBG_OUTPUT_PORT.println(json); - webSocket.sendTXT(num, json); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, listStatusJSON()); - #endif - #ifdef ENABLE_AMQTT - String liststat = (String) listStatusJSON(); - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, liststat.c_str()); - #endif - } - - // ~ ==> Get WS2812 modes. - if (payload[0] == '~') { - DBG_OUTPUT_PORT.printf("Get WS2812 modes."); - - String json = listModesJSON(); - DBG_OUTPUT_PORT.println(json); - webSocket.sendTXT(num, json); - #ifdef ENABLE_MQTT - DBG_OUTPUT_PORT.printf("Error: Not implemented. Message too large for pubsubclient."); - mqtt_client.publish(mqtt_outtopic, "ERROR: Not implemented. Message too large for pubsubclient."); - //String json_modes = listModesJSON(); - //DBG_OUTPUT_PORT.printf(json_modes.c_str()); - - //int res = mqtt_client.publish(mqtt_outtopic, json_modes.c_str(), json_modes.length()); - //DBG_OUTPUT_PORT.printf("Result: %d / %d", res, json_modes.length()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("ERROR: Not implemented. Message too large for AsyncMQTT.").c_str()); - #endif - } - - // / ==> Set WS2812 mode. - if (payload[0] == '/') { - handleSetWS2812FXMode(payload); - webSocket.sendTXT(num, "OK"); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } + checkpayload(payload, false, num); // start auto cycling if (strcmp((char *)payload, "start") == 0 ) { @@ -833,188 +935,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght #endif #endif - // # ==> Set main color - if (payload[0] == '#') { - handleSetMainColor(payload); - DBG_OUTPUT_PORT.printf("MQTT: Set main color to [%u] [%u] [%u]\n", main_color.red, main_color.green, main_color.blue); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - - // ? ==> Set speed - if (payload[0] == '?') { - uint8_t d = (uint8_t) strtol((const char *) &payload[1], NULL, 10); - ws2812fx_speed = constrain(d, 0, 255); - strip.setSpeed(convertSpeed(ws2812fx_speed)); - DBG_OUTPUT_PORT.printf("MQTT: Set speed to [%u]\n", ws2812fx_speed); - #ifdef ENABLE_HOMEASSISTANT - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - // % ==> Set brightness - if (payload[0] == '%') { - uint8_t b = (uint8_t) strtol((const char *) &payload[1], NULL, 10); - brightness = constrain(b, 0, 255); - strip.setBrightness(brightness); - DBG_OUTPUT_PORT.printf("MQTT: Set brightness to [%u]\n", brightness); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - - // * ==> Set main color and light all LEDs (Shortcut) - if (payload[0] == '*') { - handleSetAllMode(payload); - DBG_OUTPUT_PORT.printf("MQTT: Set main color and light all LEDs [%s]\n", payload); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - - // ! ==> Set single LED in given color - if (payload[0] == '!') { - handleSetSingleLED(payload, 1); - DBG_OUTPUT_PORT.printf("MQTT: Set single LED in given color [%s]\n", payload); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - // + ==> Set multiple LED in the given colors - if (payload[0] == '+') { - handleSetDifferentColors(payload); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - // R ==> Set range of LEDs in the given colors - if (payload[0] == 'R') { - handleRangeDifferentColors(payload); - DBG_OUTPUT_PORT.printf("MQTT: Set range of LEDS to single color: [%s]\n", payload); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - } - - #ifdef ENABLE_LEGACY_ANIMATIONS - // = ==> Activate named mode - if (payload[0] == '=') { - String str_mode = String((char *) &payload[0]); - handleSetNamedMode(str_mode); - DBG_OUTPUT_PORT.printf("MQTT: Activate named mode [%s]\n", payload); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } - #endif - - // $ ==> Get status Info. - if (payload[0] == '$') { - DBG_OUTPUT_PORT.printf("MQTT: Get status info.\n"); - DBG_OUTPUT_PORT.println("MQTT: Out: " + String(listStatusJSON())); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, listStatusJSON()); - #endif - #ifdef ENABLE_AMQTT - String liststat = (String) listStatusJSON(); - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, liststat.c_str()); - #endif - } - - // ~ ==> Get WS2812 modes. - // TODO: Fix this, doesn't return anything. Too long? - // Hint: https://github.com/knolleary/pubsubclient/issues/110 - if (payload[0] == '~') { - DBG_OUTPUT_PORT.printf("MQTT: Get WS2812 modes.\n"); - #ifdef ENABLE_MQTT - DBG_OUTPUT_PORT.printf("Error: Not implemented. Message too large for pubsubclient."); - mqtt_client.publish(mqtt_outtopic, "ERROR: Not implemented. Message too large for pubsubclient."); - //String json_modes = listModesJSON(); - //DBG_OUTPUT_PORT.printf(json_modes.c_str()); - - //int res = mqtt_client.publish(mqtt_outtopic, json_modes.c_str(), json_modes.length()); - //DBG_OUTPUT_PORT.printf("Result: %d / %d", res, json_modes.length()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("ERROR: Not implemented. Message too large for AsyncMQTT.").c_str()); - #endif - } - - // / ==> Set WS2812 mode. - if (payload[0] == '/') { - handleSetWS2812FXMode(payload); - DBG_OUTPUT_PORT.printf("MQTT: Set WS2812 mode [%s]\n", payload); - #ifdef ENABLE_MQTT - mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_AMQTT - amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str()); - #endif - #ifdef ENABLE_HOMEASSISTANT - stateOn = true; - if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); - #endif - #ifdef ENABLE_STATE_SAVE_SPIFFS - if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); - #endif - } + checkpayload(payload, true); #ifdef ENABLE_HOMEASSISTANT } @@ -1185,6 +1106,16 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_outtopic, String("OK =static white").c_str()); #endif + #ifdef ENABLE_AMQTT + amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =static white").c_str()); + #endif + #ifdef ENABLE_HOMEASSISTANT + stateOn = true; + if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState); + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState); + #endif } else { mode = OFF; buttonState = false; @@ -1421,7 +1352,7 @@ bool readStateFS() { DBG_OUTPUT_PORT.println("Failed to open \"/stripstate.json\""); } } else { - DBG_OUTPUT_PORT.println("Coudnt find \"/stripstate.json\""); + DBG_OUTPUT_PORT.println("Couldn't find \"/stripstate.json\""); } //end read updateFS = false; diff --git a/Arduino/McLighting/spiffs_webserver.h b/Arduino/McLighting/spiffs_webserver.h index a02fc6a..3dd396b 100644 --- a/Arduino/McLighting/spiffs_webserver.h +++ b/Arduino/McLighting/spiffs_webserver.h @@ -69,6 +69,7 @@ bool handleFileRead(String path) { if (SPIFFS.exists(pathWithGz)) path += ".gz"; File file = SPIFFS.open(path, "r"); + server.sendHeader("Access-Control-Allow-Origin", "*"); size_t sent = server.streamFile(file, contentType); file.close(); return true; @@ -153,5 +154,6 @@ void handleFileList() { } output += "]"; + server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/json", output); } diff --git a/Arduino/McLighting/version.h b/Arduino/McLighting/version.h new file mode 100644 index 0000000..db35e16 --- /dev/null +++ b/Arduino/McLighting/version.h @@ -0,0 +1 @@ +#define SKETCH_VERSION "2.1.1" diff --git a/Arduino/McLighting/version_info.ino b/Arduino/McLighting/version_info.ino new file mode 100644 index 0000000..f381e99 --- /dev/null +++ b/Arduino/McLighting/version_info.ino @@ -0,0 +1,9 @@ +/* + * 07 May 2018 v 2.1.0 + * - Start of versioning v2.1, added version support + * - '/esp_status' returns lot more info + * + * 11 May 2018 v 2.1.1 + * - Use ArduinoJSON to send JSON replies + * - Add strip.trigger() + */