From 1bbff1eb4ad4616e6b2f424945e026a3949be659 Mon Sep 17 00:00:00 2001 From: BPoH_Voodoo Date: Sun, 8 Jul 2018 21:10:39 +0200 Subject: [PATCH] update to 2.1.2 --- Arduino/McLighting/McLighting.ino | 79 +++++++---- Arduino/McLighting/request_handlers.h | 186 ++++++++++++-------------- Arduino/McLighting/version.h | 2 +- Arduino/McLighting/version_info.ino | 7 +- README.md | 6 +- documentation/pcb/Gerber.zip | Bin 0 -> 41306 bytes documentation/pcb/PCB_Schematic.pdf | Bin 0 -> 46946 bytes documentation/pcb/Photo View.svg | 10 ++ 8 files changed, 157 insertions(+), 133 deletions(-) create mode 100644 documentation/pcb/Gerber.zip create mode 100644 documentation/pcb/PCB_Schematic.pdf create mode 100644 documentation/pcb/Photo View.svg diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index 1aa2223..b240938 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -70,8 +70,8 @@ ESP8266WebServer server(80); WebSocketsServer webSocket = WebSocketsServer(81); #ifdef HTTP_OTA - #include - ESP8266HTTPUpdateServer httpUpdater; +#include +ESP8266HTTPUpdateServer httpUpdater; #endif #ifdef USE_NEOANIMATIONFX @@ -100,11 +100,11 @@ NeoAnimationFX strip(neoStrip); #endif #ifdef USE_WS2812FX - // *************************************************************************** - // Load libraries / Instanciate WS2812FX library - // *************************************************************************** - // https://github.com/kitesurfer1404/WS2812FX - #include "WS2812FX.h" +// *************************************************************************** +// Load libraries / Instanciate WS2812FX library +// *************************************************************************** +// https://github.com/kitesurfer1404/WS2812FX +#include "WS2812FX.h" #ifdef RGBW WS2812FX strip = WS2812FX(NUMLEDS, PIN, NEO_GRBW + NEO_KHZ800); @@ -112,13 +112,13 @@ NeoAnimationFX strip(neoStrip); WS2812FX strip = WS2812FX(NUMLEDS, PIN, NEO_GRB + NEO_KHZ800); #endif - // Parameter 1 = number of pixels in strip - // Parameter 2 = Arduino pin number (most are valid) - // Parameter 3 = pixel type flags, add together as needed: - // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) - // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) - // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) - // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) +// Parameter 1 = number of pixels in strip +// Parameter 2 = Arduino pin number (most are valid) +// Parameter 3 = pixel type flags, add together as needed: +// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) +// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) +// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products) +// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input @@ -348,6 +348,10 @@ DBG_OUTPUT_PORT.println("Starting...."); WiFi.setSleepMode(WIFI_NONE_SLEEP); + // Uncomment if you want to set static IP + // Order is: IP, Gateway and Subnet + //wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,128), IPAddress(192,168,0,1), IPAddress(255,255,255,0)); + //fetches ssid and pass and tries to connect //if it does not connect it starts an access point with the specified name //here "AutoConnectAP" @@ -516,18 +520,21 @@ DBG_OUTPUT_PORT.println("Starting...."); }, 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 += "}"; - - DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(9)); - JsonObject& json = jsonBuffer.createObject(); + DynamicJsonDocument jsonBuffer; + JsonObject& json = jsonBuffer.to(); json["HOSTNAME"] = HOSTNAME; json["version"] = SKETCH_VERSION; json["heap"] = ESP.getFreeHeap(); + json["sketch_size"] = ESP.getSketchSize(); + json["free_sketch_space"] = ESP.getFreeSketchSpace(); + json["flash_chip_size"] = ESP.getFlashChipSize(); + json["flash_chip_real_size"] = ESP.getFlashChipRealSize(); + json["flash_chip_speed"] = ESP.getFlashChipSpeed(); + json["sdk_version"] = ESP.getSdkVersion(); + json["core_version"] = ESP.getCoreVersion(); + json["cpu_freq"] = ESP.getCpuFreqMHz(); + json["chip_id"] = ESP.getFlashChipId(); #ifndef USE_NEOANIMATIONFX json["animation_lib"] = "WS2812FX"; json["pin"] = PIN; @@ -542,22 +549,38 @@ DBG_OUTPUT_PORT.println("Starting...."); json["button_mode"] = "OFF"; #endif #ifdef ENABLE_AMQTT + json["amqtt"] = "ON"; + #endif + #ifdef ENABLE_MQTT 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)); + #ifdef ENABLE_LEGACY_ANIMATIONS + json["legacy_animations"] = "ON"; + #else + json["legacy_animations"] = "OFF"; + #endif + #ifdef HTTP_OTA + json["esp8266_http_updateserver"] = "ON"; + #endif + #ifdef ENABLE_OTA + json["arduino_ota"] = "ON"; + #endif + #ifdef ENABLE_STATE_SAVE_SPIFFS + json["state_save"] = "SPIFFS"; + #endif + #ifdef ENABLE_STATE_SAVE_EEPROM + json["state_save"] = "EEPROM"; + #endif + String json_str; - json.printTo(json_str); + serializeJson(json, json_str); server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "application/json", json_str); - //json_str = String(); }); diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index 76c8bcf..74f0962 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -97,10 +97,6 @@ void handleSetAllMode(uint8_t * mypayload) { main_color.green = ((rgb >> 8) & 0xFF); main_color.blue = ((rgb ) & 0xFF); -// for (int i = 0; i < strip.numPixels(); i++) { -// strip.setPixelColor(i, main_color.red, main_color.green, main_color.blue, main_color.white); -// } -// strip.show(); DBG_OUTPUT_PORT.printf("WS: Set all leds to main color: W: [%u] R: [%u] G: [%u] B: [%u]\n", main_color.white, main_color.red, main_color.green, main_color.blue); #ifdef ENABLE_LEGACY_ANIMATIONS exit_func = true; @@ -296,18 +292,11 @@ void handleSetWS2812FXMode(uint8_t * mypayload) { } 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); - const size_t bufferSize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(6); - DynamicJsonBuffer jsonBuffer(bufferSize); - JsonObject& root = jsonBuffer.createObject(); + DynamicJsonDocument jsonBuffer(bufferSize); + JsonObject& root = jsonBuffer.to(); root["mode"] = (uint8_t) mode; root["ws2812fx_mode"] = tmp_mode; root["ws2812fx_mode_name"] = strip.getModeName(tmp_mode); @@ -319,11 +308,8 @@ String listStatusJSON(void) { 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); + serializeJson(root, json); return json; } @@ -334,20 +320,9 @@ void getStatusJSON() { } 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(); + DynamicJsonDocument jsonBuffer(bufferSize); + JsonArray& json = jsonBuffer.to(); for (uint8_t i = 0; i < strip.getModeCount(); i++) { JsonObject& object = json.createNestedObject(); object["mode"] = i; @@ -356,7 +331,7 @@ String listModesJSON(void) { JsonObject& object = json.createNestedObject(); String json_str; - json.printTo(json_str); + serializeJson(json, json_str); return json_str; } @@ -372,7 +347,7 @@ void handleMinimalUpload() { char temp[1500]; snprintf ( temp, 1500, - "\ + "\ \ \ ESP8266 Upload\ @@ -470,7 +445,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { 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)); + mode = SETSPEED; Dbg_Prefix(mqtt, num); DBG_OUTPUT_PORT.printf("Set speed to: [%u]\n", ws2812fx_speed); #ifdef ENABLE_HOMEASSISTANT @@ -488,7 +463,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { if (payload[0] == '%') { uint8_t b = (uint8_t) strtol((const char *) &payload[1], NULL, 10); brightness = constrain(b, 0, 255); - strip.setBrightness(brightness); + mode = BRIGHTNESS; Dbg_Prefix(mqtt, num); DBG_OUTPUT_PORT.printf("Set brightness to: [%u]\n", brightness); #ifdef ENABLE_MQTT @@ -593,41 +568,51 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { // $ ==> Get status Info. if (payload[0] == '$') { String json = listStatusJSON(); - Dbg_Prefix(mqtt, num); + 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); - 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] == '~') { String json = listModesJSON(); - Dbg_Prefix(mqtt, num); + 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); - #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, json.c_str()); - #endif } // / ==> Set WS2812 mode. - // TODO: Fix this, doesn't return anything. Too long? - // Hint: https://github.com/knolleary/pubsubclient/issues/110 if (payload[0] == '/') { handleSetWS2812FXMode(payload); Dbg_Prefix(mqtt, num); @@ -648,7 +633,6 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) { } } - // *************************************************************************** // WS request handlers // *************************************************************************** @@ -764,9 +748,8 @@ 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); - //StaticJsonBuffer jsonBuffer; - DynamicJsonBuffer jsonBuffer(bufferSize); - JsonObject& root = jsonBuffer.createObject(); + DynamicJsonDocument jsonBuffer(bufferSize); + JsonObject& root = jsonBuffer.to(); root["state"] = (stateOn) ? on_cmd : off_cmd; JsonObject& color = root.createNestedObject("color"); @@ -784,8 +767,8 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght strncpy_P(modeName, (PGM_P)strip.getModeName(strip.getMode()), sizeof(modeName)); // copy from progmem root["effect"] = modeName; - char buffer[root.measureLength() + 1]; - root.printTo(buffer, sizeof(buffer)); + char buffer[measureJson(root) + 1]; + serializeJson(root, buffer, sizeof(buffer)); #ifdef ENABLE_MQTT mqtt_client.publish(mqtt_ha_state_out.c_str(), buffer, true); @@ -802,16 +785,16 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght bool processJson(char* message) { const size_t bufferSize = JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + 150; - //StaticJsonBuffer jsonBuffer; - DynamicJsonBuffer jsonBuffer(bufferSize); - JsonObject& root = jsonBuffer.parseObject(message); - - if (!root.success()) { - DBG_OUTPUT_PORT.println("parseObject() failed"); + DynamicJsonDocument jsonBuffer(bufferSize); + DeserializationError error = deserializeJson(jsonBuffer, message); + if (error) { + DBG_OUTPUT_PORT.print("parseObject() failed: "); + DBG_OUTPUT_PORT.println(error.c_str()); return false; } //DBG_OUTPUT_PORT.println("JSON ParseObject() done!"); - + JsonObject& root = jsonBuffer.as(); + if (root.containsKey("state")) { const char* state_in = root["state"]; if (strcmp(state_in, on_cmd) == 0 and !(animation_on)) { @@ -860,7 +843,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght if (root.containsKey("effect")) { animation_on = true; - String effectString = root["effect"].asString(); + String effectString = root["effect"].as(); for (uint8_t i = 0; i < strip.getModeCount(); i++) { if(String(strip.getModeName(i)) == effectString) { @@ -937,8 +920,8 @@ 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 - DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(11)); - JsonObject& json = jsonBuffer.createObject(); + DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(11)); + JsonObject& json = jsonBuffer.to(); json["name"] = HOSTNAME; json["platform"] = "mqtt_json"; json["state_topic"] = mqtt_ha_state_out; @@ -953,8 +936,8 @@ 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)); } - char buffer[json.measureLength() + 1]; - json.printTo(buffer, sizeof(buffer)); + char buffer[json.measureJson() + 1]; + serializeJson(json, buffer, sizeof(buffer)); mqtt_client.publish(String("homeassistant/light/" + String(HOSTNAME) + "/config").c_str(), buffer, true); #endif #endif @@ -1017,8 +1000,8 @@ 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 - DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(11)); - JsonObject& json = jsonBuffer.createObject(); + DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip.getModeCount()) + JSON_OBJECT_SIZE(11)); + JsonObject& json = jsonBuffer.to(); json["name"] = HOSTNAME; json["platform"] = "mqtt_json"; json["state_topic"] = mqtt_ha_state_out; @@ -1033,8 +1016,8 @@ 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)); } - char buffer[json.measureLength() + 1]; - json.printTo(buffer, sizeof(buffer)); + char buffer[json.measureJson() + 1]; + serializeJson(json, buffer, sizeof(buffer)); DBG_OUTPUT_PORT.println(buffer); amqttClient.publish(String("homeassistant/light/" + String(HOSTNAME) + "/config").c_str(), qospub, true, buffer); #endif @@ -1258,9 +1241,8 @@ bool writeConfigFS(bool saveConfig){ //FS save updateFS = true; DBG_OUTPUT_PORT.print("Saving config: "); - DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(4)); -// StaticJsonBuffer jsonBuffer; - JsonObject& json = jsonBuffer.createObject(); + DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(4)); + JsonObject& json = jsonBuffer.to(); json["mqtt_host"] = mqtt_host; json["mqtt_port"] = mqtt_port; json["mqtt_user"] = mqtt_user; @@ -1270,8 +1252,8 @@ bool writeConfigFS(bool saveConfig){ File configFile = SPIFFS.open("/config.json", "w"); if (!configFile) DBG_OUTPUT_PORT.println("failed to open config file for writing"); - json.printTo(DBG_OUTPUT_PORT); - json.printTo(configFile); + serializeJson(json, DBG_OUTPUT_PORT); + serializeJson(json, configFile); configFile.close(); updateFS = false; return true; @@ -1295,13 +1277,13 @@ bool readConfigFS() { size_t size = configFile.size(); std::unique_ptr buf(new char[size]); configFile.readBytes(buf.get(), size); - DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(4)+300); -// StaticJsonBuffer jsonBuffer; - JsonObject& json = jsonBuffer.parseObject(buf.get()); + DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(4)+300); + DeserializationError error = deserializeJson(jsonBuffer, buf.get()); DBG_OUTPUT_PORT.print("Config: "); - json.printTo(DBG_OUTPUT_PORT); - if (json.success()) { + if (!error) { DBG_OUTPUT_PORT.println(" Parsed!"); + JsonObject& json = jsonBuffer.as(); + serializeJson(json, DBG_OUTPUT_PORT); strcpy(mqtt_host, json["mqtt_host"]); strcpy(mqtt_port, json["mqtt_port"]); strcpy(mqtt_user, json["mqtt_user"]); @@ -1309,7 +1291,8 @@ bool readConfigFS() { updateFS = false; return true; } else { - DBG_OUTPUT_PORT.println("Failed to load json config"); + DBG_OUTPUT_PORT.print("Failed to load json config: "); + DBG_OUTPUT_PORT.println(error.c_str()); } } else { DBG_OUTPUT_PORT.println("Failed to open /config.json"); @@ -1327,9 +1310,8 @@ bool writeStateFS(){ updateFS = true; //save the strip state to FS JSON DBG_OUTPUT_PORT.print("Saving cfg: "); - DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(7)); -// StaticJsonBuffer jsonBuffer; - JsonObject& json = jsonBuffer.createObject(); + DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(7)); + JsonObject& json = jsonBuffer.to(); json["mode"] = static_cast(mode); json["strip_mode"] = (int) strip.getMode(); json["brightness"] = brightness; @@ -1348,8 +1330,8 @@ bool writeStateFS(){ updateStateFS = false; return false; } - json.printTo(DBG_OUTPUT_PORT); - json.printTo(configFile); + serializeJson(json, DBG_OUTPUT_PORT); + serializeJson(json, configFile); configFile.close(); updateFS = false; spiffs_save_state.detach(); @@ -1371,11 +1353,11 @@ bool readStateFS() { // Allocate a buffer to store contents of the file. std::unique_ptr buf(new char[size]); configFile.readBytes(buf.get(), size); - DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(7)+200); -// StaticJsonBuffer jsonBuffer; - JsonObject& json = jsonBuffer.parseObject(buf.get()); - json.printTo(DBG_OUTPUT_PORT); - if (json.success()) { + DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(7)+200); + DeserializationError error = deserializeJson(jsonBuffer, buf.get()); + if (!error) { + JsonObject& json = jsonBuffer.as(); + serializeJson(json, DBG_OUTPUT_PORT); mode = static_cast((int) json["mode"]); ws2812fx_mode = json["strip_mode"]; brightness = json["brightness"]; @@ -1399,7 +1381,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/version.h b/Arduino/McLighting/version.h index db35e16..78f074b 100644 --- a/Arduino/McLighting/version.h +++ b/Arduino/McLighting/version.h @@ -1 +1 @@ -#define SKETCH_VERSION "2.1.1" +#define SKETCH_VERSION "2.1.2" diff --git a/Arduino/McLighting/version_info.ino b/Arduino/McLighting/version_info.ino index f381e99..bafde4f 100644 --- a/Arduino/McLighting/version_info.ino +++ b/Arduino/McLighting/version_info.ino @@ -6,4 +6,9 @@ * 11 May 2018 v 2.1.1 * - Use ArduinoJSON to send JSON replies * - Add strip.trigger() - */ + * + * 17 Jun 2018 v 2.1.2 + * - Upgrade to ArduinoJSON 6.xx from ArduinoJSON 5.xx + * - Added example for static IP + * - Added more internal variables to /esp_status + */ diff --git a/README.md b/README.md index 7ac6a4a..7851c69 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ [![Demo video Apple Homekit integration](https://j.gifs.com/gJP2o6.gif)](https://youtu.be/4JnGXZaPnrw) ___ +Update 13.05.2018: +I've worked on a new web UI for the last weeks. It's now available as an early preview. There is a [video](https://youtu.be/lryDPMA2qpY) that shows the new features. [Try it out](https://github.com/toblum/McLightingUI) if you want and leave some feedback. + Update 07.04.2018: And even more changes to McLighting! Most of them were contributed by user @debsahu. Thank you! - Update arduino-esp8266 to latest, at least version 2.4.1 @@ -130,7 +133,7 @@ I hope I didn't miss any sources and mentioned every author. In case I forgot so ## Todos - [x] MQTT support - [ ] Support multiple strips and control them separately or together [Issue](https://github.com/toblum/McLighting/issues/118) -- [ ] Save favourite effects? [Issue](https://github.com/toblum/McLighting/issues/35) +- [x] Save favourite effects? [Issue](https://github.com/toblum/McLighting/issues/35) - [ ] Make number of pixels, MQTT and PIN configurable via front end [Issue](https://github.com/toblum/McLighting/issues/93) and [Issue](https://github.com/toblum/McLighting/issues/101) - [x] OTA update [Issue](https://github.com/toblum/McLighting/issues/93) - [ ] Bundle webpages instead of SPIFFS [Issue](https://github.com/toblum/McLighting/issues/93) @@ -149,6 +152,7 @@ I hope I didn't miss any sources and mentioned every author. In case I forgot so - [ ] If no wifi, at least enable button mode. - [ ] Also enable McLighting in Wifi AP mode. - [x] Make a set of NodeRed nodes. +- [ ] IR remote support [issue](https://github.com/toblum/McLightingUI/issues/3) - [ ] Multiple buttons/GPIO Inputs. [Issue](https://github.com/toblum/McLighting/issues/119) - [ ] Music visualizer / Bring back ArtNet [Issue](https://github.com/toblum/McLighting/issues/111) - [ ] Display version and parameters (Number of LEDs, definition settings, ..) in the web UI [Issue](https://github.com/toblum/McLighting/issues/150) diff --git a/documentation/pcb/Gerber.zip b/documentation/pcb/Gerber.zip new file mode 100644 index 0000000000000000000000000000000000000000..45211348a65ecf3ce1dec9b8ca9cfe358354a1e4 GIT binary patch literal 41306 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 H{Pq6;N><8x literal 0 HcmV?d00001 diff --git a/documentation/pcb/PCB_Schematic.pdf b/documentation/pcb/PCB_Schematic.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6bc6a48d0a8b4ccea8e4d69f9b1cc6f953a45877 GIT binary patch literal 46946 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 tg zb`e7OrqhT7I&$fdNQ8m6?g&Adau}<4=GuA?4M78GEXbFx*1%@yX_Xh&wyvL`nP}Tf zK)*X1)a@TD7c?_TuWwBf6{L-YoN*r_id!<^TD!P1su8|~V-kX0| z3}6*#^94gQ<=7XxR4yhuH0KEoIDUm^RC1^2hKHBZbyHJDlGxk_=g&X+OjTPE;#3V0 zKL0w}l{!SV#|l}+lP5T4{O9~7oX zaLZ%(cUaPY1Y$`_h>0i({sqL6v$Bx30{kynELQeMEEWR@iv{w91AribKkOU+4=2AL zfUaM#SU+%4e>?esTKS)`SdW05UlBS#7vJxL{?Xj8-W7jhvHr{G|05iW{Re*McZeIo z_uT(LM*fdztRHx#KfkkptU3OUJ>r#q9zV|hzV~?cd+9%sQcQoLx_+31V&&vF0Sorw)J4R3c=r{O#jFp)MG{wKg7+3)y^TOX_Oe_GvpLLm8Sn2@yP!8{MSQ(gq$-Ny= z7i4D&{QioUH*qn1T&IsfL^&%fJCN___Z|Fr{pcPhoto View + \ No newline at end of file