diff --git a/.github/updateversion.py b/.github/updateversion.py index 6a0d955..e42dfa7 100644 --- a/.github/updateversion.py +++ b/.github/updateversion.py @@ -5,15 +5,16 @@ print("Usage: python3 updateversion.py ") sys.exit(1) -tag = sys.argv[1] +# Ensure the filename will not be a directory path by replacing '/' with '-' +tag = sys.argv[1].replace('/', '-') content_new = '' -with open ('./src/PixelIt.ino', 'r' ) as f: +with open ('./platformio.ini', 'r' ) as f: content = f.read() - content_new = re.sub('(#define\s+VERSION\s+\")(.*)(\")', r'\g<1>'+ tag + r'\g<3>', content, flags = re.M) + content_new = re.sub('pixelit_version\s*=\s*.*', 'pixelit_version = ' + tag, content, flags = re.M) f.close() if content_new != "": - with open ('./src/PixelIt.ino', 'w' ) as f: + with open ('./platformio.ini', 'w' ) as f: f.write(content_new) f.close() diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 7583853..c6ce005 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -67,7 +67,7 @@ jobs: run: | python .github/webui.py - - name: Update version in PixelIt.ino 🔧 + - name: Update version in platformio.ini 🔧 run: | python .github/updateversion.py ${{ github.ref_name }} diff --git a/extra_script.py b/extra_script.py index fffac74..1eb17da 100644 --- a/extra_script.py +++ b/extra_script.py @@ -1,34 +1,17 @@ -import mmap -import os -import re Import("env") -SOURCECODE = "./src/PixelIt.ino" - # Access to global construction environment build_tag = env['PIOENV'] +# Read version from platformio.ini [common].pixelit_version +version = env.GetProjectConfig().get("common", "pixelit_version") -# Dump construction environment (for debug purpose) -# print(env.Dump()) - -# Search Version -version = "" -file1 = open(SOURCECODE, 'r') -Lines = file1.readlines() - -count = 0 -# Strips the newline character -for line in Lines: - match = re.search(r"^#define\s+VERSION\s+[\"'](.*)[\"'].*$", line) - if match: - version = match.group(1) - file1.close - break +prog_name = f"firmware_v{version}_{build_tag}" -if version == "": - raise Exception(f"No version found in {SOURCECODE}") +print(f"[extra_script] build_tag: {build_tag}") +print(f"[extra_script] version: {version}") +print(f"[extra_script] PROGNAME: {prog_name}") # Rename binary according to environnement/board # ex: firmware_esp32dev.bin or firmware_nodemcuv2.bin -env.Replace(PROGNAME=f"firmware_v{version}_{build_tag}") +env.Replace(PROGNAME=prog_name) diff --git a/include/Tools.h b/include/Tools.h index 7235964..425e643 100644 --- a/include/Tools.h +++ b/include/Tools.h @@ -253,12 +253,35 @@ float CelsiusToFahrenheit(float celsius) return (celsius * 9 / 5) + 32; } +/// +/// RGB Color struct. +/// +/// Can be auto casted to uint16_t using Framebuffer_GFX::Color() +/// +/// Default: RGB(255, 255, 255) = White +/// +struct RGBColor +{ + uint8_t r = 255; + uint8_t g = 255; + uint8_t b = 255; + + RGBColor() {} + RGBColor(uint8_t _r, uint8_t _g, uint8_t _b) : r(_r), g(_g), b(_b) {} + + // Auto cast to uint16_t using Framebuffer_GFX::Color() + operator uint16_t() const + { + return Framebuffer_GFX::Color(r, g, b); + } +}; + // RGBtoHEX -String RGBtoHEX(int r, int g, int b) +String RGBtoHEX(RGBColor color) { - String rs = String(r, HEX); - String gs = String(g, HEX); - String bs = String(b, HEX); + String rs = String(color.r, HEX); + String gs = String(color.g, HEX); + String bs = String(color.b, HEX); if (rs.length() == 1) rs = "0" + rs; @@ -271,7 +294,7 @@ String RGBtoHEX(int r, int g, int b) } // HEXtoRGB -void HEXtoRGB(String hex, uint8_t &r, uint8_t &g, uint8_t &b) +void HEXtoRGB(String hex, RGBColor &result) { // Remove # if it exists hex.replace("#", ""); @@ -281,14 +304,31 @@ void HEXtoRGB(String hex, uint8_t &r, uint8_t &g, uint8_t &b) // regex: ^#?([a-f0-9]{6}|[a-f0-9]{3})$ if (hex.length() == 6) { - r = strtol(hex.substring(0, 2).c_str(), nullptr, 16); - g = strtol(hex.substring(2, 4).c_str(), nullptr, 16); - b = strtol(hex.substring(4, 6).c_str(), nullptr, 16); + result.r = strtol(hex.substring(0, 2).c_str(), nullptr, 16); + result.g = strtol(hex.substring(2, 4).c_str(), nullptr, 16); + result.b = strtol(hex.substring(4, 6).c_str(), nullptr, 16); } else { - r = 0; - g = 0; - b = 0; + result.r = 0; + result.g = 0; + result.b = 0; } -} \ No newline at end of file +} + +/// +/// Converts a JSON object with either a hexColor or r,g,b values to an RGBColor struct +/// +void JsonToRGB(JsonVariant parent, RGBColor &result) +{ + if (parent["hexColor"].is()) + { + HEXtoRGB(parent["hexColor"], result); + } + else if (parent["color"]["r"].is() && parent["color"]["g"].is() && parent["color"]["b"].is()) + { + result.r = parent["color"]["r"]; + result.g = parent["color"]["g"]; + result.b = parent["color"]["b"]; + } +} diff --git a/include/UpdateScreen.h b/include/UpdateScreen.h index 8fc901b..009aae2 100644 --- a/include/UpdateScreen.h +++ b/include/UpdateScreen.h @@ -1,24 +1,22 @@ #include -void BuildUpdateScreenJSON(JsonObject &root) +void BuildUpdateScreenJSON(JsonDocument doc) { - - JsonObject &text = root.createNestedObject("text"); + JsonObject text = doc["text"].add(); text["textString"] = "New FW available"; text["hexColor"] = "#FFFFFF"; text["scrollText"] = true; + + JsonObject position = text["position"].add(); + position["x"] = 7; + position["y"] = 1; - JsonObject &text_position = text.createNestedObject("position"); - text_position["x"] = 7; - text_position["y"] = 1; - - JsonObject &bitmapAnimation = root.createNestedObject("bitmapAnimation"); + JsonObject bitmapAnimation = doc["bitmapAnimation"].add(); bitmapAnimation["animationDelay"] = 400; bitmapAnimation["limitLoops"] = 0; - JsonArray &bitmapAnimation_data = bitmapAnimation.createNestedArray("data"); - - JsonArray &bitmapAnimation_data_0 = bitmapAnimation_data.createNestedArray(); + JsonArray bitmapAnimation_data = bitmapAnimation["data"].to(); + JsonArray bitmapAnimation_data_0 = bitmapAnimation_data.add().to(); bitmapAnimation_data_0.add(0); bitmapAnimation_data_0.add(0); bitmapAnimation_data_0.add(0); @@ -84,7 +82,7 @@ void BuildUpdateScreenJSON(JsonObject &root) bitmapAnimation_data_0.add(0); bitmapAnimation_data_0.add(0); - JsonArray &bitmapAnimation_data_1 = bitmapAnimation_data.createNestedArray(); + JsonArray bitmapAnimation_data_1 = bitmapAnimation_data.add().to(); bitmapAnimation_data_1.add(0); bitmapAnimation_data_1.add(0); bitmapAnimation_data_1.add(0); @@ -150,7 +148,7 @@ void BuildUpdateScreenJSON(JsonObject &root) bitmapAnimation_data_1.add(63488); bitmapAnimation_data_1.add(0); - JsonArray &bitmapAnimation_data_2 = bitmapAnimation_data.createNestedArray(); + JsonArray bitmapAnimation_data_2 = bitmapAnimation_data.add().to(); bitmapAnimation_data_2.add(0); bitmapAnimation_data_2.add(0); bitmapAnimation_data_2.add(0); @@ -216,7 +214,7 @@ void BuildUpdateScreenJSON(JsonObject &root) bitmapAnimation_data_2.add(0); bitmapAnimation_data_2.add(0); - JsonArray &bitmapAnimation_data_3 = bitmapAnimation_data.createNestedArray(); + JsonArray bitmapAnimation_data_3 = bitmapAnimation_data.add().to(); bitmapAnimation_data_3.add(0); bitmapAnimation_data_3.add(0); bitmapAnimation_data_3.add(0); @@ -282,7 +280,7 @@ void BuildUpdateScreenJSON(JsonObject &root) bitmapAnimation_data_3.add(0); bitmapAnimation_data_3.add(0); - JsonArray &bitmapAnimation_data_4 = bitmapAnimation_data.createNestedArray(); + JsonArray bitmapAnimation_data_4 = bitmapAnimation_data.add().to(); bitmapAnimation_data_4.add(0); bitmapAnimation_data_4.add(0); bitmapAnimation_data_4.add(63517); @@ -348,7 +346,7 @@ void BuildUpdateScreenJSON(JsonObject &root) bitmapAnimation_data_4.add(0); bitmapAnimation_data_4.add(0); - JsonArray &bitmapAnimation_data_5 = bitmapAnimation_data.createNestedArray(); + JsonArray bitmapAnimation_data_5 = bitmapAnimation_data.add().to(); bitmapAnimation_data_5.add(0); bitmapAnimation_data_5.add(0); bitmapAnimation_data_5.add(0); @@ -414,7 +412,7 @@ void BuildUpdateScreenJSON(JsonObject &root) bitmapAnimation_data_5.add(0); bitmapAnimation_data_5.add(0); - JsonArray &bitmapAnimation_data_6 = bitmapAnimation_data.createNestedArray(); + JsonArray bitmapAnimation_data_6 = bitmapAnimation_data.add().to(); bitmapAnimation_data_6.add(0); bitmapAnimation_data_6.add(0); bitmapAnimation_data_6.add(0); diff --git a/platformio.ini b/platformio.ini index 479403d..9fab848 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,9 +13,11 @@ framework = arduino monitor_speed = 115200 upload_speed = 460800 extra_scripts = pre:extra_script.py +pixelit_version = 0.0.0-dev build_flags = -DMATRIX_WIDTH=32 ; Pixel cols -DMATRIX_HEIGHT=8 ; Pixel rows + -DPIXELIT_VERSION=\"${common.pixelit_version}\" esp32_build_flags = ${common.build_flags} -DLDR_PIN=34 @@ -36,32 +38,33 @@ esp8266_build_flags = -DDEFAULT_PIN_SDA="Pin_D3" -DDEFAULT_PIN_DFPRX="Pin_D7" -DDEFAULT_PIN_DFPTX="Pin_D8" - -DDEFAULT_PIN_ONEWIRE="Pin_D1" + -DDEFAULT_PIN_ONEWIRE="Pin_D1" -DDEFAULT_MATRIX_TYPE=1 -DDEFAULT_LDR=GL5516 -DVBAT_PIN=0 lib_deps = - adafruit/Adafruit BME280 Library@2.2.4 - adafruit/Adafruit BME680 Library@2.0.4 - adafruit/Adafruit BMP280 Library@2.6.8 - adafruit/Adafruit BusIO@1.16.1 - adafruit/Adafruit GFX Library@1.11.11 + adafruit/Adafruit BME280 Library@2.3.0 + adafruit/Adafruit BME680 Library@2.0.6 + adafruit/Adafruit BMP280 Library@3.0.0 + adafruit/Adafruit BusIO@1.17.4 + adafruit/Adafruit GFX Library@1.12.6 adafruit/Adafruit SHT31 Library@2.2.2 - adafruit/Adafruit Unified Sensor@1.1.4 + adafruit/Adafruit Unified Sensor@1.1.15 arduino-libraries/ArduinoHttpClient@0.6.1 - bakercp/CRC32 @ 2.0.0 - bblanchon/ArduinoJson@5.13.4 + bakercp/CRC32 @ 2.0.1 + bblanchon/ArduinoJson@7.4.3 beegee-tokyo/DHT sensor library for ESPx@1.19.0 claws/BH1750@1.3.0 - fastled/FastLED@3.7.0 + fastled/FastLED@3.10.3 knolleary/PubSubClient@2.8.0 Hash = https://github.com/bbx10/Hash_tng.git#1f100823284a28e8aedeae7e7f593e189fe16982 LightDependentResistor=https://github.com/QuentinCG/Arduino-Light-Dependent-Resistor-Library.git#1.4.0 - links2004/WebSockets@2.4.1 + links2004/WebSockets@2.7.3 marcmerlin/FastLED NeoMatrix@1.2.0 powerbroker2/DFPlayerMini_Fast@1.2.4 - robtillaart/Max44009@0.6.0 + robtillaart/Max44009@0.6.2 TimeLib = https://github.com/PaulStoffregen/Time.git#v1.6.1 + tzapu/WiFiManager@^2.0.17 [env:ESP32_generic] platform = espressif32 @@ -78,11 +81,10 @@ platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.17 lib_deps = ${common.lib_deps} - plerup/EspSoftwareSerial@^8.2.0 - WiFiManager = https://github.com/tzapu/WiFiManager.git#v2.0.17 + plerup/EspSoftwareSerial@^6.11.4 [env:ESP8266_generic] -platform = espressif8266@2.6.3 +platform = espressif8266@4.2.1 board = esp12e framework = ${common.framework} board_build.filesystem = littlefs @@ -94,7 +96,6 @@ build_flags = -DBUILD_SECTION="ESP8266_generic" lib_deps = ${common.lib_deps} - tzapu/WiFiManager@^0.16.0 [env:ESP8266_d1_mini] extends = env:ESP8266_generic diff --git a/src/PixelIt.ino b/src/PixelIt.ino index 5838157..6ae0cc8 100644 --- a/src/PixelIt.ino +++ b/src/PixelIt.ino @@ -69,8 +69,8 @@ #define SEND_SENSOR_INTERVAL 1000 * 3 // 10 Seconds #define UPDATE_BATTERY_LEVEL_INTERVAL 1000 * 30 // 30 Seconds -// Version config - will be replaced by build piple with Git-Tag! -#define VERSION "0.0.0-beta" // will be replaced by build piple with Git-Tag! +// PIXELIT_VERSION Comes in from platformio.ini, the version is replaced by the build pipeline with Git-Tag +#define VERSION PIXELIT_VERSION // Workaround for String in defines #define XSTR(x) #x @@ -260,7 +260,7 @@ uint clockCounterClock = 0; uint clockCounterDate = 0; float clockTimeZone = 1; time_t clockLastUpdate; -uint8_t clockColorR = 255, clockColorG = 255, clockColorB = 255; +RGBColor clockColor = RGBColor(); uint clockAutoFallbackTime = 30; bool forceClock = false; bool clockBlinkAnimated = true; @@ -440,89 +440,88 @@ void EnteredHotspotCallback(WiFiManager *manager) { Log(F("Hotspot"), "Waiting for WiFi configuration"); matrix->clear(); - DrawTextHelper("HOTSPOT", false, false, false, false, false, 255, 255, 255, 3, 1); + DrawTextHelper("HOTSPOT", false, false, false, false, false, RGBColor(), 3, 1); FadeIn(); } void SaveConfig() { // save the custom parameters to FS - DynamicJsonBuffer jsonBuffer; - JsonObject &json = jsonBuffer.createObject(); - - json["version"] = VERSION; - json["isESP8266"] = isESP8266; - json["temperatureUnit"] = static_cast(temperatureUnit); - json["matrixBrightnessAutomatic"] = matrixBrightnessAutomatic; - json["mbaDimMin"] = mbaDimMin; - json["mbaDimMax"] = mbaDimMax; - json["mbaLuxMin"] = mbaLuxMin; - json["mbaLuxMax"] = mbaLuxMax; - json["matrixBrightness"] = currentMatrixBrightness; - json["matrixType"] = matrixType; - json["note"] = note; - json["hostname"] = hostname; - json["matrixTempCorrection"] = matrixTempCorrection; - json["ntpServer"] = ntpServer; - json["clockTimeZone"] = clockTimeZone; - json["clockColor"] = "#" + RGBtoHEX(clockColorR, clockColorG, clockColorB); - json["clockSwitchAktiv"] = clockSwitchAktiv; - json["clockSwitchSec"] = clockSwitchSec; - json["clock24Hours"] = clock24Hours; - json["clockDayLightSaving"] = clockDayLightSaving; - json["clockWithSeconds"] = clockWithSeconds; - json["clockAutoFallbackActive"] = clockAutoFallbackActive; - json["clockAutoFallbackTime"] = clockAutoFallbackTime; - json["clockAutoFallbackAnimation"] = clockAutoFallbackAnimation; - json["clockDateDayMonth"] = clockDateDayMonth; - json["clockDayOfWeekFirstMonday"] = clockDayOfWeekFirstMonday; - json["clockBlinkAnimated"] = clockBlinkAnimated; - json["clockLargeFont"] = clockLargeFont; - json["clockFatFont"] = clockFatFont; - json["clockDrawWeekDays"] = clockDrawWeekDays; - json["scrollTextDefaultDelay"] = scrollTextDefaultDelay; - json["bootScreenAktiv"] = bootScreenAktiv; - json["bootBatteryScreen"] = bootBatteryScreen; - json["bootSound"] = bootSound; - json["mqttAktiv"] = mqttAktiv; - json["mqttUser"] = mqttUser; - json["mqttPassword"] = mqttPassword; - json["mqttServer"] = mqttServer; - json["mqttMasterTopic"] = mqttMasterTopic; - json["mqttPort"] = mqttPort; - json["mqttUseDeviceTopic"] = mqttUseDeviceTopic; - json["mqttHAdiscoverable"] = mqttHAdiscoverable; - json["luxOffset"] = luxOffset; - json["temperatureOffset"] = temperatureOffset; - json["humidityOffset"] = humidityOffset; - json["pressureOffset"] = pressureOffset; - json["gasOffset"] = gasOffset; - - json["dfpRXpin"] = dfpRXPin; - json["dfpTXpin"] = dfpTXPin; - json["onewirePin"] = onewirePin; - json["SCLPin"] = SCLPin; - json["SDAPin"] = SDAPin; + JsonDocument doc; + + doc["version"] = VERSION; + doc["isESP8266"] = isESP8266; + doc["temperatureUnit"] = static_cast(temperatureUnit); + doc["matrixBrightnessAutomatic"] = matrixBrightnessAutomatic; + doc["mbaDimMin"] = mbaDimMin; + doc["mbaDimMax"] = mbaDimMax; + doc["mbaLuxMin"] = mbaLuxMin; + doc["mbaLuxMax"] = mbaLuxMax; + doc["matrixBrightness"] = currentMatrixBrightness; + doc["matrixType"] = matrixType; + doc["note"] = note; + doc["hostname"] = hostname; + doc["matrixTempCorrection"] = matrixTempCorrection; + doc["ntpServer"] = ntpServer; + doc["clockTimeZone"] = clockTimeZone; + doc["clockColor"] = "#" + RGBtoHEX(clockColor); + doc["clockSwitchAktiv"] = clockSwitchAktiv; + doc["clockSwitchSec"] = clockSwitchSec; + doc["clock24Hours"] = clock24Hours; + doc["clockDayLightSaving"] = clockDayLightSaving; + doc["clockWithSeconds"] = clockWithSeconds; + doc["clockAutoFallbackActive"] = clockAutoFallbackActive; + doc["clockAutoFallbackTime"] = clockAutoFallbackTime; + doc["clockAutoFallbackAnimation"] = clockAutoFallbackAnimation; + doc["clockDateDayMonth"] = clockDateDayMonth; + doc["clockDayOfWeekFirstMonday"] = clockDayOfWeekFirstMonday; + doc["clockBlinkAnimated"] = clockBlinkAnimated; + doc["clockLargeFont"] = clockLargeFont; + doc["clockFatFont"] = clockFatFont; + doc["clockDrawWeekDays"] = clockDrawWeekDays; + doc["scrollTextDefaultDelay"] = scrollTextDefaultDelay; + doc["bootScreenAktiv"] = bootScreenAktiv; + doc["bootBatteryScreen"] = bootBatteryScreen; + doc["bootSound"] = bootSound; + doc["mqttAktiv"] = mqttAktiv; + doc["mqttUser"] = mqttUser; + doc["mqttPassword"] = mqttPassword; + doc["mqttServer"] = mqttServer; + doc["mqttMasterTopic"] = mqttMasterTopic; + doc["mqttPort"] = mqttPort; + doc["mqttUseDeviceTopic"] = mqttUseDeviceTopic; + doc["mqttHAdiscoverable"] = mqttHAdiscoverable; + doc["luxOffset"] = luxOffset; + doc["temperatureOffset"] = temperatureOffset; + doc["humidityOffset"] = humidityOffset; + doc["pressureOffset"] = pressureOffset; + doc["gasOffset"] = gasOffset; + + doc["dfpRXpin"] = dfpRXPin; + doc["dfpTXpin"] = dfpTXPin; + doc["onewirePin"] = onewirePin; + doc["SCLPin"] = SCLPin; + doc["SDAPin"] = SDAPin; for (uint b = 0; b < 3; b++) { - json["btn" + String(b) + "Pin"] = btnPin[b]; - json["btn" + String(b) + "PressedLevel"] = btnPressedLevel[b]; - json["btn" + String(b) + "Enabled"] = btnEnabled[b]; - json["btn" + String(b) + "Action"] = static_cast(btnAction[b]); + doc["btn" + String(b) + "Pin"] = btnPin[b]; + doc["btn" + String(b) + "PressedLevel"] = btnPressedLevel[b]; + doc["btn" + String(b) + "Enabled"] = btnEnabled[b]; + doc["btn" + String(b) + "Action"] = static_cast(btnAction[b]); } - json["ldrDevice"] = ldrDevice; - json["ldrPulldown"] = ldrPulldown; - json["ldrSmoothing"] = ldrSmoothing; - json["initialVolume"] = initialVolume; - json["sendTelemetry"] = sendTelemetry; - json["checkUpdateScreen"] = checkUpdateScreen; + doc["ldrDevice"] = ldrDevice; + doc["ldrPulldown"] = ldrPulldown; + doc["ldrSmoothing"] = ldrSmoothing; + doc["initialVolume"] = initialVolume; + doc["sendTelemetry"] = sendTelemetry; + doc["checkUpdateScreen"] = checkUpdateScreen; #if defined(ESP8266) File configFile = LittleFS.open("/config.json", "w"); #elif defined(ESP32) File configFile = SPIFFS.open("/config.json", "w"); #endif - json.printTo(configFile); + serializeJson(doc, configFile); configFile.close(); Log("SaveConfig", "Saved"); // end save @@ -544,12 +543,11 @@ void LoadConfig() { // Serial.println("opened config file"); - DynamicJsonBuffer jsonBuffer; - JsonObject &json = jsonBuffer.parseObject(configFile); - - if (json.success()) + JsonDocument doc; + DeserializationError error = deserializeJson(doc, configFile); + if (!error) { - SetConfigVariables(json); + SetConfigVariables(doc); Log("LoadConfig", "Loaded"); } } @@ -561,67 +559,67 @@ void LoadConfig() } } -void SetConfig(JsonObject &json) +void SetConfig(JsonDocument doc) { - SetConfigVariables(json); + SetConfigVariables(doc); SaveConfig(); } -void SetConfigVariables(JsonObject &json) +void SetConfigVariables(JsonDocument json) { - if (json.containsKey("version")) + if (json["version"].is()) { optionsVersion = json["version"].as(); } - if (json.containsKey("temperatureUnit")) + if (json["temperatureUnit"].is()) { temperatureUnit = static_cast(json["temperatureUnit"].as()); } - if (json.containsKey("matrixBrightnessAutomatic")) + if (json["matrixBrightnessAutomatic"].is()) { matrixBrightnessAutomatic = json["matrixBrightnessAutomatic"].as(); } - if (json.containsKey("mbaDimMin")) + if (json["mbaDimMin"].is()) { mbaDimMin = json["mbaDimMin"].as(); } - if (json.containsKey("mbaDimMax")) + if (json["mbaDimMax"].is()) { mbaDimMax = json["mbaDimMax"].as(); } - if (json.containsKey("mbaLuxMin")) + if (json["mbaLuxMin"].is()) { mbaLuxMin = json["mbaLuxMin"].as(); } - if (json.containsKey("mbaLuxMax")) + if (json["mbaLuxMax"].is()) { mbaLuxMax = json["mbaLuxMax"].as(); } - if (json.containsKey("matrixBrightness")) + if (json["matrixBrightness"].is()) { SetCurrentMatrixBrightness(json["matrixBrightness"].as()); } - if (json.containsKey("matrixType")) + if (json["matrixType"].is()) { matrixType = json["matrixType"].as(); } - if (json.containsKey("note")) + if (json["note"].is()) { - note = json["note"].as(); + note = json["note"].as(); } - if (json.containsKey("hostname")) + if (json["hostname"].is()) { - String hostname_raw = json["hostname"].as(); + String hostname_raw = json["hostname"].as(); hostname = ""; for (uint8_t n = 0; n < hostname_raw.length(); n++) { @@ -630,138 +628,138 @@ void SetConfigVariables(JsonObject &json) } } - if (json.containsKey("matrixTempCorrection")) + if (json["matrixTempCorrection"].is()) { - matrixTempCorrection = json["matrixTempCorrection"].as(); + matrixTempCorrection = json["matrixTempCorrection"].as(); } - if (json.containsKey("ntpServer")) + if (json["ntpServer"].is()) { - ntpServer = json["ntpServer"].as(); + ntpServer = json["ntpServer"].as(); } - if (json.containsKey("clockTimeZone")) + if (json["clockTimeZone"].is()) { clockTimeZone = json["clockTimeZone"].as(); } - if (json.containsKey("clockColor")) + if (json["clockColor"].is()) { - HEXtoRGB(json["clockColor"].as(), clockColorR, clockColorG, clockColorB); + HEXtoRGB(json["clockColor"].as(), clockColor); } - if (json.containsKey("clockSwitchAktiv")) + if (json["clockSwitchAktiv"].is()) { clockSwitchAktiv = json["clockSwitchAktiv"].as(); } - if (json.containsKey("clockSwitchSec")) + if (json["clockSwitchSec"].is()) { clockSwitchSec = json["clockSwitchSec"].as(); } - if (json.containsKey("clock24Hours")) + if (json["clock24Hours"].is()) { clock24Hours = json["clock24Hours"].as(); } - if (json.containsKey("clockDayLightSaving")) + if (json["clockDayLightSaving"].is()) { clockDayLightSaving = json["clockDayLightSaving"].as(); } - if (json.containsKey("clockWithSeconds")) + if (json["clockWithSeconds"].is()) { clockWithSeconds = json["clockWithSeconds"].as(); } - if (json.containsKey("clockBlinkAnimated")) + if (json["clockBlinkAnimated"].is()) { clockBlinkAnimated = json["clockBlinkAnimated"].as(); } - if (json.containsKey("clockAutoFallbackActive")) + if (json["clockAutoFallbackActive"].is()) { clockAutoFallbackActive = json["clockAutoFallbackActive"].as(); } - if (json.containsKey("clockAutoFallbackAnimation")) + if (json["clockAutoFallbackAnimation"].is()) { clockAutoFallbackAnimation = json["clockAutoFallbackAnimation"].as(); } - if (json.containsKey("clockAutoFallbackTime")) + if (json["clockAutoFallbackTime"].is()) { clockAutoFallbackTime = json["clockAutoFallbackTime"].as(); } - if (json.containsKey("clockDateDayMonth")) + if (json["clockDateDayMonth"].is()) { clockDateDayMonth = json["clockDateDayMonth"].as(); } - if (json.containsKey("clockDayOfWeekFirstMonday")) + if (json["clockDayOfWeekFirstMonday"].is()) { clockDayOfWeekFirstMonday = json["clockDayOfWeekFirstMonday"].as(); } - if (json.containsKey("clockLargeFont")) + if (json["clockLargeFont"].is()) { clockLargeFont = json["clockLargeFont"].as(); } - if (json.containsKey("clockFatFont")) + if (json["clockFatFont"].is()) { clockFatFont = json["clockFatFont"].as(); } - if (json.containsKey("clockDrawWeekDays")) + if (json["clockDrawWeekDays"].is()) { clockDrawWeekDays = json["clockDrawWeekDays"].as(); } - if (json.containsKey("scrollTextDefaultDelay")) + if (json["scrollTextDefaultDelay"].is()) { scrollTextDefaultDelay = json["scrollTextDefaultDelay"].as(); } - if (json.containsKey("bootScreenAktiv")) + if (json["bootScreenAktiv"].is()) { bootScreenAktiv = json["bootScreenAktiv"].as(); } - if (json.containsKey("bootBatteryScreen")) + if (json["bootBatteryScreen"].is()) { bootBatteryScreen = json["bootBatteryScreen"].as(); } - if (json.containsKey("bootSound")) + if (json["bootSound"].is()) { bootSound = json["bootSound"].as(); } - if (json.containsKey("mqttAktiv")) + if (json["mqttAktiv"].is()) { mqttAktiv = json["mqttAktiv"].as(); } - if (json.containsKey("mqttUser")) + if (json["mqttUser"].is()) { - mqttUser = json["mqttUser"].as(); + mqttUser = json["mqttUser"].as(); } - if (json.containsKey("mqttPassword")) + if (json["mqttPassword"].is()) { - mqttPassword = json["mqttPassword"].as(); + mqttPassword = json["mqttPassword"].as(); } - if (json.containsKey("mqttServer")) + if (json["mqttServer"].is()) { - mqttServer = json["mqttServer"].as(); + mqttServer = json["mqttServer"].as(); } - if (json.containsKey("mqttMasterTopic")) + if (json["mqttMasterTopic"].is()) { - mqttMasterTopic = json["mqttMasterTopic"].as(); + mqttMasterTopic = json["mqttMasterTopic"].as(); mqttMasterTopic.trim(); if (!mqttMasterTopic.endsWith("/")) { @@ -769,117 +767,117 @@ void SetConfigVariables(JsonObject &json) } } - if (json.containsKey("mqttPort")) + if (json["mqttPort"].is()) { mqttPort = json["mqttPort"].as(); } - if (json.containsKey("mqttUseDeviceTopic")) + if (json["mqttUseDeviceTopic"].is()) { mqttUseDeviceTopic = json["mqttUseDeviceTopic"].as(); } - if (json.containsKey("mqttHAdiscoverable")) + if (json["mqttHAdiscoverable"].is()) { mqttHAdiscoverable = json["mqttHAdiscoverable"].as(); } - if (json.containsKey("luxOffset")) + if (json["luxOffset"].is()) { luxOffset = json["luxOffset"].as(); } - if (json.containsKey("temperatureOffset")) + if (json["temperatureOffset"].is()) { temperatureOffset = json["temperatureOffset"].as(); } - if (json.containsKey("humidityOffset")) + if (json["humidityOffset"].is()) { humidityOffset = json["humidityOffset"].as(); } - if (json.containsKey("pressureOffset")) + if (json["pressureOffset"].is()) { pressureOffset = json["pressureOffset"].as(); } - if (json.containsKey("gasOffset")) + if (json["gasOffset"].is()) { gasOffset = json["gasOffset"].as(); } - if (json.containsKey("dfpRXpin")) + if (json["dfpRXpin"].is()) { - dfpRXPin = json["dfpRXpin"].as(); + dfpRXPin = json["dfpRXpin"].as(); } - if (json.containsKey("dfpTXpin")) + if (json["dfpTXpin"].is()) { - dfpTXPin = json["dfpTXpin"].as(); + dfpTXPin = json["dfpTXpin"].as(); } - if (json.containsKey("onewirePin")) + if (json["onewirePin"].is()) { - onewirePin = json["onewirePin"].as(); + onewirePin = json["onewirePin"].as(); } - if (json.containsKey("SCLPin")) + if (json["SCLPin"].is()) { - SCLPin = json["SCLPin"].as(); + SCLPin = json["SCLPin"].as(); } - if (json.containsKey("SDAPin")) + if (json["SDAPin"].is()) { - SDAPin = json["SDAPin"].as(); + SDAPin = json["SDAPin"].as(); } for (uint b = 0; b < 3; b++) { - if (json.containsKey("btn" + String(b) + "Pin")) + if (json["btn" + String(b) + "Pin"].is()) { - btnPin[b] = json["btn" + String(b) + "Pin"].as(); + btnPin[b] = json["btn" + String(b) + "Pin"].as(); } - if (json.containsKey("btn" + String(b) + "PressedLevel")) + if (json["btn" + String(b) + "PressedLevel"].is()) { btnPressedLevel[b] = json["btn" + String(b) + "PressedLevel"].as(); } - if (json.containsKey("btn" + String(b) + "Enabled")) + if (json["btn" + String(b) + "Enabled"].is()) { btnEnabled[b] = json["btn" + String(b) + "Enabled"].as(); } - if (json.containsKey("btn" + String(b) + "Action")) + if (json["btn" + String(b) + "Action"].is()) { btnAction[b] = static_cast(json["btn" + String(b) + "Action"].as()); } } - if (json.containsKey("ldrDevice")) + if (json["ldrDevice"].is()) { - ldrDevice = json["ldrDevice"].as(); + ldrDevice = json["ldrDevice"].as(); } - if (json.containsKey("ldrPulldown")) + if (json["ldrPulldown"].is()) { ldrPulldown = json["ldrPulldown"].as(); } - if (json.containsKey("ldrSmoothing")) + if (json["ldrSmoothing"].is()) { ldrSmoothing = json["ldrSmoothing"].as(); } - if (json.containsKey("initialVolume")) + if (json["initialVolume"].is()) { initialVolume = json["initialVolume"].as(); } - if (json.containsKey("sendTelemetry")) + if (json["sendTelemetry"].is()) { sendTelemetry = json["sendTelemetry"].as(); } - if (json.containsKey("checkUpdateScreen")) + if (json["checkUpdateScreen"].is()) { checkUpdateScreen = json["checkUpdateScreen"].as(); } @@ -913,17 +911,17 @@ void HandleNotFound() void HandleScreen() { - DynamicJsonBuffer jsonBuffer; + JsonDocument doc; String args = String(server.arg("plain").c_str()); - JsonObject &json = jsonBuffer.parseObject(args.begin()); + DeserializationError error = deserializeJson(doc, args); server.sendHeader(F("Connection"), F("close")); server.sendHeader(F("Access-Control-Allow-Origin"), "*"); - if (json.success()) + if (!error) { server.send(200, F("application/json"), F("{\"response\":\"OK\"}")); - Log(F("HandleScreen"), "Incoming JSON length: " + String(json.measureLength())); - CreateFrames(json); + Log(F("HandleScreen"), "Incoming JSON length: " + String(measureJson(doc))); + CreateFrames(doc); } else { @@ -933,14 +931,14 @@ void HandleScreen() void HandleSetConfig() { - DynamicJsonBuffer jsonBuffer; - JsonObject &json = jsonBuffer.parseObject(server.arg("plain")); + JsonDocument doc; + DeserializationError error = deserializeJson(doc, server.arg("plain")); server.sendHeader(F("Connection"), F("close")); - if (json.success()) + if (!error) { - Log(F("SetConfig"), "Incoming JSON length: " + String(json.measureLength())); - SetConfig(json); + Log(F("SetConfig"), "Incoming JSON length: " + String(measureJson(doc))); + SetConfig(doc); server.send(200, F("application/json"), F("{\"response\":\"OK\"}")); delay(500); ESP.restart(); @@ -1024,13 +1022,13 @@ void SleepScreen(bool startSleep, bool forceClockOnWake) { Log(F("SleepScreen"), F("Sleeping...")); matrix->clear(); - DrawTextHelper("z", false, false, false, false, false, 0, 0, 255, (MATRIX_WIDTH / 2) - 6, 1); + DrawTextHelper("z", false, false, false, false, false, RGBColor(0, 0, 255), (MATRIX_WIDTH / 2) - 6, 1); matrix->show(); delay(200); - DrawTextHelper("Z", false, false, false, false, false, 0, 0, 255, (MATRIX_WIDTH / 2) - 1, 1); + DrawTextHelper("Z", false, false, false, false, false, RGBColor(0, 0, 255), (MATRIX_WIDTH / 2) - 1, 1); matrix->show(); delay(200); - DrawTextHelper("z", false, false, false, false, false, 0, 0, 255, (MATRIX_WIDTH / 2) + 4, 1); + DrawTextHelper("z", false, false, false, false, false, RGBColor(0, 0, 255), (MATRIX_WIDTH / 2) + 4, 1); matrix->show(); delay(500); FadeOut(30, 0); @@ -1048,6 +1046,19 @@ void SleepScreen(bool startSleep, bool forceClockOnWake) } } +#if defined(ESP8266) +inline void SendWsText(unsigned int clientNum, const String &payload) +{ + String mutablePayload = payload; + webSocket.sendTXT(static_cast(clientNum), mutablePayload); +} +#else +inline void SendWsText(unsigned int clientNum, String &payload) +{ + webSocket.sendTXT(clientNum, payload); +} +#endif + void HandleAndSendButtonPress(uint button, bool state) { btnLastPublishState[button] = state; @@ -1067,8 +1078,7 @@ void HandleAndSendButtonPress(uint button, bool state) { for (uint i = 0; i < sizeof websocketConnection / sizeof websocketConnection[0]; i++) { - String payload = "{\"buttons\":{\"" + btnAPINames[button] + "\":" + (state ? "true" : "false") + "}}"; - webSocket.sendTXT(i, payload); + SendWsText(i, "{\"buttons\":{\"" + btnAPINames[button] + "\":" + (state ? "true" : "false") + "}}"); } } @@ -1120,19 +1130,19 @@ void callback(char *topic, byte *payload, unsigned int length) channel = channel.substring(lastSlashIndex + 1); } - DynamicJsonBuffer jsonBuffer; - JsonObject &json = jsonBuffer.parseObject(payload); + JsonDocument doc; + deserializeJson(doc, payload); - Log("MQTT_callback", "Incoming JSON (Topic: " + String(topic) + ", Cmd: " + channel + ", Bytes: " + String(length) + "/" + String(json.measureLength()) + ") "); + Log("MQTT_callback", "Incoming JSON (Topic: " + String(topic) + ", Cmd: " + channel + ", Bytes: " + String(length) + "/" + String(measureJson(doc)) + ") "); - if (json.measureLength() == 2) + if (measureJson(doc) == 2) { Log("MQTT_callback", "JSON message empty or too long"); return; } if (channel.equals("setScreen")) { - CreateFrames(json); + CreateFrames(doc); } else if (channel.equals("getLuxsensor")) { @@ -1160,7 +1170,7 @@ void callback(char *topic, byte *payload, unsigned int length) } else if (channel.equals("setConfig")) { - SetConfig(json); + SetConfig(doc); } } } @@ -1191,58 +1201,56 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) SendLDR(true); SendSensor(true); SendConfig(); - String payload = "{\"buttons\":" + GetButtons() + "}"; - webSocket.sendTXT(num, payload); - payload = "{\"telemetry\":" + GetTelemetry() + "}"; - webSocket.sendTXT(num, payload); + SendWsText(num, "{\"buttons\":" + GetButtons() + "}"); + SendWsText(num, "{\"telemetry\":" + GetTelemetry() + "}"); break; } case WStype_TEXT: { if (((char *)payload)[0] == '{') { - DynamicJsonBuffer jsonBuffer; - JsonObject &json = jsonBuffer.parseObject(payload); + JsonDocument doc; + deserializeJson(doc, payload); int forcedDuration = 0; // Logging - Log(F("WebSocketEvent"), "Incoming JSON (Length: " + String(length) + "/" + String(json.measureLength()) + ")"); - if (length != json.measureLength()) + Log(F("WebSocketEvent"), "Incoming JSON (Length: " + String(length) + "/" + String(measureJson(doc)) + ")"); + if (length != measureJson(doc)) { Log("MQTT_callback", "JSON length mismatch! JSON Message to long :("); return; } - if (json.containsKey("forcedDuration")) + if (doc["forcedDuration"].is()) { - forcedDuration = json["forcedDuration"].as(); + forcedDuration = doc["forcedDuration"].as(); } - if (json.containsKey("setScreen")) + if (doc["setScreen"].is()) { - CreateFrames(json["setScreen"], forcedDuration); + CreateFrames(doc["setScreen"], forcedDuration); } - else if (json.containsKey("setConfig")) + else if (doc["setConfig"].is()) { - SetConfig(json["setConfig"]); + SetConfig(doc["setConfig"]); delay(500); ESP.restart(); } - else if (json.containsKey("wifiReset")) + else if (doc["wifiReset"].is()) { - if (json["wifiReset"].as() == true) + if (doc["wifiReset"].as() == true) { HandelWifiConfigReset(); } } - else if (json.containsKey("factoryReset")) + else if (doc["factoryReset"].is()) { - if (json["factoryReset"].as() == true) + if (doc["factoryReset"].as() == true) { HandleFactoryReset(); } } - else if (json.containsKey("sendTelemetry")) + else if (doc["sendTelemetry"].is()) { sendTelemetryPrevMillis = 0; } @@ -1268,25 +1276,23 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) } } -void CreateFrames(JsonObject &json) +void CreateFrames(JsonDocument doc) { - CreateFrames(json, 0); + CreateFrames(doc, 0); } -void CreateFrames(JsonObject &json, int forceDuration) +void CreateFrames(JsonDocument doc, int forceDuration) { bool sendMatrixInfo = false; - String logMessage = F("JSON contains "); - if (json.containsKey("sleepMode")) + if (doc["sleepMode"].is()) { - logMessage += F("Sleep Control, "); - Serial.printf("SleepMode: %s\n", json["sleepMode"].as() ? "true" : "false"); + Serial.printf("SleepMode: %s\n", doc["sleepMode"] ? "true" : "false"); // Update internal sleep state - bool newSleepMode = json["sleepMode"].as(); + bool newSleepMode = doc["sleepMode"]; if (newSleepMode != sleepMode) { @@ -1300,39 +1306,41 @@ void CreateFrames(JsonObject &json, int forceDuration) // Restore last frame if sleep mode is disabled if (sleepMode == false && currentScreenJsonBuffer.length() > 0) { - DynamicJsonBuffer jsonBuffer; - JsonObject &tmpJson = jsonBuffer.parseObject(currentScreenJsonBuffer); - CreateFrames(tmpJson); + JsonDocument tmpDoc; + deserializeJson(tmpDoc, currentScreenJsonBuffer); + CreateFrames(tmpDoc); return; } } } // Ist eine Display Helligkeit übergeben worden? - if (json.containsKey("brightness") && !sleepMode) + if (doc["brightness"].is() && !sleepMode) { logMessage += F("Brightness Control, "); - if (json["brightness"].as() != currentMatrixBrightness) + if (doc["brightness"].as() != currentMatrixBrightness) { sendMatrixInfo = true; - currentMatrixBrightness = json["brightness"].as(); + currentMatrixBrightness = doc["brightness"]; matrix->setBrightness(currentMatrixBrightness); matrix->show(); } } // Set GPIO - if (json.containsKey("setGpio")) + if (doc["setGpio"].is()) { + JsonObject setGpio = doc["setGpio"]; logMessage += F("Set Gpio, "); - if (json["setGpio"]["set"].is() && json["setGpio"]["gpio"].is()) + if (setGpio["set"].is() && setGpio["gpio"].is()) { - uint8_t gpio = json["setGpio"]["gpio"].as(); + bool setValue = setGpio["set"].as(); + uint8_t gpio = setGpio["gpio"]; // If the GPIO is already present in the array? // has been found, this is to be replaced. - if (json["setGpio"]["duration"].is()) + if (setGpio["duration"].is()) { int arrayIndex = -1; for (int i = 0; i < SET_GPIO_SIZE; i++) @@ -1364,61 +1372,62 @@ void CreateFrames(JsonObject &json, int forceDuration) { // Save data in array for the reset. setGPIOReset[arrayIndex].gpio = gpio; - setGPIOReset[arrayIndex].resetMillis = (millis() + json["setGpio"]["duration"].as()); - Log(F("SetGPIO"), "Pos: " + String(arrayIndex) + ", GPIO: " + String(gpio) + ", Duration: " + String(json["setGpio"]["duration"].as()) + ", Value: " + json["setGpio"]["set"].as()); + setGPIOReset[arrayIndex].resetMillis = (millis() + setGpio["duration"].as()); + Log(F("SetGPIO"), "Pos: " + String(arrayIndex) + ", GPIO: " + String(gpio) + ", Duration: " + String(setGpio["duration"].as()) + ", Value: " + String(setValue)); } } else { - Log(F("SetGPIO"), "GPIO: " + String(gpio) + ", Value: " + json["setGpio"]["set"].as()); + Log(F("SetGPIO"), "GPIO: " + String(gpio) + ", Value: " + String(setValue)); } // Set GPIO pinMode(gpio, OUTPUT); - digitalWrite(gpio, json["setGpio"]["set"].as()); + digitalWrite(gpio, setValue); } } // Sound - if (json.containsKey("sound")) + if (doc["sound"].is()) { + JsonObject sound = doc["sound"]; logMessage += F("Sound, "); // Volume - if (json["sound"]["volume"] != NULL && json["sound"]["volume"].is()) + if (sound["volume"].is()) { - mp3Player.volume(json["sound"]["volume"].as()); + mp3Player.volume(sound["volume"]); // Sometimes, mp3Player gets hickups. A brief delay might help - but also might hinder scrolling. // So, do it only if there are more commands to come. - if (json["sound"]["control"].as() == "") + if (sound["control"].as() == "") { Log(F("Sound"), F("Changing volume can prevent DFPlayer from executing a control command at the same time. Better make two separate API calls.")); delay(200); } } // Play - if (json["sound"]["control"] == "play") + if (sound["control"] == "play" && sound["file"].is()) { - if (json["sound"]["folder"]) + if (sound["folder"].is()) { - mp3Player.playFolder(json["sound"]["folder"].as(), json["sound"]["file"].as()); + mp3Player.playFolder(sound["folder"], sound["file"]); } else { - mp3Player.play(json["sound"]["file"].as()); + mp3Player.play(sound["file"]); } } // Stop - else if (json["sound"]["control"] == "pause") + else if (sound["control"] == "pause") { mp3Player.pause(); } // Play Next - else if (json["sound"]["control"] == "next") + else if (sound["control"] == "next") { mp3Player.playNext(); } // Play Previous - else if (json["sound"]["control"] == "previous") + else if (sound["control"] == "previous") { mp3Player.playPrevious(); } @@ -1428,12 +1437,12 @@ void CreateFrames(JsonObject &json, int forceDuration) // - no sleepmode control is in message // - not sleeping // - no forced screen is active OR forceDuration is set - if (!json.containsKey("sleepMode") && !sleepMode && (millis() >= forcedScreenIsActiveUntil || forceDuration > 0)) + if (!doc["sleepMode"].is() && !sleepMode && (millis() >= forcedScreenIsActiveUntil || forceDuration > 0)) { matrix->setBrightness(currentMatrixBrightness); // Prüfung für die Unterbrechnung der lokalen Schleifen - if (json.containsKey("bitmap") || json.containsKey("bitmaps") || json.containsKey("text") || json.containsKey("bar") || json.containsKey("bars") || json.containsKey("bitmapAnimation")) + if (doc["bitmap"].is() || doc["bitmaps"].is() || doc["text"].is() || doc["bar"].is() || doc["bars"].is() || doc["bitmapAnimation"].is()) { lastScreenMessageMillis = millis(); clockAktiv = false; @@ -1446,30 +1455,31 @@ void CreateFrames(JsonObject &json, int forceDuration) bool coloredBarWipeAnimationAktiv = false; bool zigzagWipeAnimationAktiv = false; bool bitmapWipeAnimationAktiv = false; - if (json.containsKey("switchAnimation")) + if (doc["switchAnimation"].is()) { + JsonObject switchAnimation = doc["switchAnimation"]; logMessage += F("SwitchAnimation, "); // Switch Animation aktiv? - if (json["switchAnimation"]["aktiv"]) + if (switchAnimation["aktiv"]) { // Fade Animation aktiv? - if (json["switchAnimation"]["animation"] == "fade") + if (switchAnimation["animation"] == "fade") { fadeAnimationAktiv = true; } - else if (json["switchAnimation"]["animation"] == "coloredBarWipe") + else if (switchAnimation["animation"] == "coloredBarWipe") { coloredBarWipeAnimationAktiv = true; } - else if (json["switchAnimation"]["animation"] == "zigzagWipe") + else if (switchAnimation["animation"] == "zigzagWipe") { zigzagWipeAnimationAktiv = true; } - else if (json["switchAnimation"]["animation"] == "bitmapWipe") + else if (switchAnimation["animation"] == "bitmapWipe") { bitmapWipeAnimationAktiv = true; } - else if (json["switchAnimation"]["animation"] == "random") + else if (switchAnimation["animation"] == "random") { switch (millis() % 3) { @@ -1485,42 +1495,32 @@ void CreateFrames(JsonObject &json, int forceDuration) } } } - } - // Fade aktiv? - if (fadeAnimationAktiv) - { - FadeOut(); - } - else if (coloredBarWipeAnimationAktiv) - { - ColoredBarWipe(); - } - else if (zigzagWipeAnimationAktiv) - { - uint8_t r = 255; - uint8_t g = 255; - uint8_t b = 255; - if (json["switchAnimation"]["hexColor"].as() != NULL) + // Fade aktiv? + if (fadeAnimationAktiv) { - HEXtoRGB(json["switchAnimation"]["hexColor"].as(), r, g, b); + FadeOut(); } - else if (json["switchAnimation"]["color"]["r"].as() != NULL) + else if (coloredBarWipeAnimationAktiv) { - r = json["switchAnimation"]["color"]["r"].as(); - g = json["switchAnimation"]["color"]["g"].as(); - b = json["switchAnimation"]["color"]["b"].as(); + ColoredBarWipe(); + } + else if (zigzagWipeAnimationAktiv) + { + RGBColor wipeColor; + JsonToRGB(switchAnimation, wipeColor); + ZigZagWipe(wipeColor); + } + else if (bitmapWipeAnimationAktiv) + { + BitmapWipe(switchAnimation["data"], switchAnimation["width"]); } - ZigZagWipe(r, g, b); - } - else if (bitmapWipeAnimationAktiv) - { - BitmapWipe(json["switchAnimation"]["data"].as(), json["switchAnimation"]["width"].as()); } // Clock - if (json.containsKey("clock")) + if (doc["clock"].is()) { + JsonObject clock = doc["clock"]; logMessage += F("InternalClock Control, Params: ("); scrollTextAktivLoop = false; animateBMPAktivLoop = false; @@ -1529,65 +1529,55 @@ void CreateFrames(JsonObject &json, int forceDuration) clockCounterClock = 0; clockCounterDate = 0; - bool isSwitchAktivSet = json["clock"]["switchAktiv"].is(); + bool isSwitchAktivSet = clock["switchAktiv"].is(); if (isSwitchAktivSet) { logMessage += F("clockSwitchAktiv, "); - clockSwitchAktiv = json["clock"]["switchAktiv"]; + clockSwitchAktiv = clock["switchAktiv"]; } - bool isClockSwitchSecSet = json["clock"]["switchSec"] != NULL; + bool isClockSwitchSecSet = clock["switchSec"].is(); if (clockSwitchAktiv && isClockSwitchSecSet) { logMessage += F("clockSwitchSec, "); - clockSwitchSec = json["clock"]["switchSec"]; + clockSwitchSec = clock["switchSec"]; } - bool isClockWithSecondsSet = json["clock"]["withSeconds"].is(); + bool isClockWithSecondsSet = clock["withSeconds"].is(); if (isClockWithSecondsSet) { logMessage += F("withSeconds, "); - clockWithSeconds = json["clock"]["withSeconds"]; + clockWithSeconds = clock["withSeconds"]; } - bool isClockBlinkAnimatedSet = json["clock"]["blinkAnimated"].is(); + bool isClockBlinkAnimatedSet = clock["blinkAnimated"].is(); if (isClockBlinkAnimatedSet) { logMessage += F("blinkAnimated, "); - clockBlinkAnimated = json["clock"]["blinkAnimated"]; + clockBlinkAnimated = clock["blinkAnimated"]; } - bool isFatFontSet = json["clock"]["fatFont"].is(); + bool isFatFontSet = clock["fatFont"].is(); if (isFatFontSet) { logMessage += F("fatFont, "); - clockFatFont = json["clock"]["fatFont"]; + clockFatFont = clock["fatFont"]; } - bool isLargeFontSet = json["clock"]["largeFont"].is(); + bool isLargeFontSet = clock["largeFont"].is(); if (isLargeFontSet) { logMessage += F("largeFont, "); - clockLargeFont = json["clock"]["largeFont"]; + clockLargeFont = clock["largeFont"]; } - bool isDrawWeekDaysSet = json["clock"]["drawWeekDays"].is(); + bool isDrawWeekDaysSet = clock["drawWeekDays"].is(); if (isDrawWeekDaysSet) { logMessage += F("drawWeekDays, "); - clockDrawWeekDays = json["clock"]["drawWeekDays"]; + clockDrawWeekDays = clock["drawWeekDays"]; } - if (json["clock"]["color"]["r"].as() != NULL) - { - logMessage += F("color, "); - clockColorR = json["clock"]["color"]["r"].as(); - clockColorG = json["clock"]["color"]["g"].as(); - clockColorB = json["clock"]["color"]["b"].as(); - } - else if (json["clock"]["hexColor"].as() != NULL) - { - logMessage += F("hexColor, "); - HEXtoRGB(json["clock"]["hexColor"].as(), clockColorR, clockColorG, clockColorB); - } + JsonToRGB(clock, clockColor); + if (logMessage.endsWith(", ")) { logMessage.remove(logMessage.length() - 2); @@ -1596,61 +1586,45 @@ void CreateFrames(JsonObject &json, int forceDuration) DrawClock(true); } - if (json.containsKey("bitmap") || json.containsKey("bitmaps") || json.containsKey("bitmapAnimation") || json.containsKey("text") || json.containsKey("bar") || json.containsKey("bars")) + if (doc["bitmap"].is() || doc["bitmaps"].is() || doc["bitmapAnimation"].is() || doc["text"].is() || doc["bar"].is() || doc["bars"].is()) { // Alle Pixel löschen matrix->clear(); } // Bar - if (json.containsKey("bar")) + if (doc["bar"].is()) { + JsonObject bar = doc["bar"]; logMessage += F("Bar, "); - uint8_t r, g, b; - if (json["bar"]["hexColor"].as() != NULL) - { - HEXtoRGB(json["bar"]["hexColor"].as(), r, g, b); - } - else - { - r = json["bar"]["color"]["r"].as(); - g = json["bar"]["color"]["g"].as(); - b = json["bar"]["color"]["b"].as(); - } - matrix->drawLine(json["bar"]["position"]["x"], json["bar"]["position"]["y"], json["bar"]["position"]["x2"], json["bar"]["position"]["y2"], matrix->Color(r, g, b)); + RGBColor barColor = {0, 0, 0}; + JsonToRGB(bar, barColor); + + matrix->drawLine(bar["position"]["x"], bar["position"]["y"], bar["position"]["x2"], bar["position"]["y2"], barColor); } // Bars - if (json.containsKey("bars")) + if (doc["bars"].is()) { logMessage += F("Bars, "); - for (JsonVariant x : json["bars"].as()) + for (JsonVariant x : doc["bars"].as()) { - uint8_t r, g, b; - if (x["hexColor"].as() != NULL) - { - HEXtoRGB(x["hexColor"].as(), r, g, b); - } - else - { - r = x["color"]["r"].as(); - g = x["color"]["g"].as(); - b = x["color"]["b"].as(); - } - matrix->drawLine(x["position"]["x"], x["position"]["y"], x["position"]["x2"], x["position"]["y2"], matrix->Color(r, g, b)); + RGBColor barColor = {0, 0, 0}; + JsonToRGB(x, barColor); + matrix->drawLine(x["position"]["x"], x["position"]["y"], x["position"]["x2"], x["position"]["y2"], barColor); } } // clear withBMP only if no sleepMode is in the same message - if (!json.containsKey("sleepMode")) + if (!doc["sleepMode"].is()) { withBMP = false; } // Restore withBMP from (stored) message - if (json.containsKey("withBMPRestore")) + if (doc["withBMPRestore"].is()) { - withBMP = json["withBMPRestore"]; + withBMP = doc["withBMPRestore"]; if (withBMP == true) { matrix->drawRGBBitmap(bmpPosX, bmpPosY, bmpArray, bmpWidth, bmpHeight); @@ -1658,46 +1632,47 @@ void CreateFrames(JsonObject &json, int forceDuration) } // Restore a animateBMPAktivLoop from (stored) message - if (json.containsKey("animateBMPAktivLoopRestore")) + if (doc["animateBMPAktivLoopRestore"].is()) { - animateBMPAktivLoop = json["animateBMPAktivLoopRestore"]; + animateBMPAktivLoop = doc["animateBMPAktivLoopRestore"]; } // Ist ein Bitmap übergeben worden? - if (json.containsKey("bitmap")) + if (doc["bitmap"].is()) { logMessage += F("Bitmap, "); - DrawSingleBitmap(json["bitmap"]); + DrawSingleBitmap(doc["bitmap"]); } // Sind mehrere Bitmaps übergeben worden? - if (json.containsKey("bitmaps")) + if (doc["bitmaps"].is()) { logMessage += F("Bitmaps ("); - for (JsonVariant singleBitmap : json["bitmaps"].as()) + for (JsonVariant singleBitmap : doc["bitmaps"].as()) { DrawSingleBitmap(singleBitmap); } - logMessage += json["bitmaps"].as().size(); + logMessage += doc["bitmaps"].as().size(); logMessage += F("), "); } // Ist eine BitmapAnimation übergeben worden? - if (json.containsKey("bitmapAnimation")) + if (doc["bitmapAnimation"].is()) { + JsonObject bitmapAnimation = doc["bitmapAnimation"]; bmpPosX = 0; bmpPosY = 0; bmpWidth = 8; bmpHeight = 8; - if (json["bitmapAnimation"]["position"]["x"].is() && json["bitmapAnimation"]["position"]["y"].is()) + if (bitmapAnimation["position"]["x"].is() && bitmapAnimation["position"]["y"].is()) { - bmpPosX = json["bitmapAnimation"]["position"]["x"].as(); - bmpPosY = json["bitmapAnimation"]["position"]["y"].as(); + bmpPosX = bitmapAnimation["position"]["x"]; + bmpPosY = bitmapAnimation["position"]["y"]; } - if (json["bitmapAnimation"]["size"]["width"].is() && json["bitmapAnimation"]["size"]["height"].is()) + if (bitmapAnimation["size"]["width"].is() && bitmapAnimation["size"]["height"].is()) { - bmpWidth = json["bitmapAnimation"]["size"]["width"].as(); - bmpHeight = json["bitmapAnimation"]["size"]["height"].as(); + bmpWidth = bitmapAnimation["size"]["width"]; + bmpHeight = bitmapAnimation["size"]["height"]; } withBMP = true; @@ -1709,10 +1684,10 @@ void CreateFrames(JsonObject &json, int forceDuration) } int counter = 0; - for (JsonVariant x : json["bitmapAnimation"]["data"].as()) + for (JsonVariant x : bitmapAnimation["data"].as()) { // JsonArray in IntArray konvertieren - x.as().copyTo(bmpArray); + copyArray(x.as(), bmpArray); // Speichern für die Ausgabe for (int i = 0; i < 64; i++) { @@ -1723,13 +1698,13 @@ void CreateFrames(JsonObject &json, int forceDuration) // Serial.printf("Counter: %d\n", counter); - animateBMPDelay = json["bitmapAnimation"]["animationDelay"]; - animateBMPRubberbandingAktiv = json["bitmapAnimation"]["rubberbanding"]; + animateBMPDelay = bitmapAnimation["animationDelay"]; + animateBMPRubberbandingAktiv = bitmapAnimation["rubberbanding"]; animateBMPLimitLoops = 0; - if (json["bitmapAnimation"]["limitLoops"]) + if (bitmapAnimation["limitLoops"].is()) { - animateBMPLimitLoops = json["bitmapAnimation"]["limitLoops"].as(); + animateBMPLimitLoops = bitmapAnimation["limitLoops"]; } // Hier einmal den Counter zurücksetzten @@ -1743,58 +1718,49 @@ void CreateFrames(JsonObject &json, int forceDuration) // Ist ein Text übergeben worden? bool scrollTextAktiv = false; - if (json.containsKey("text")) + if (doc["text"].is()) { + JsonObject text = doc["text"]; logMessage += F("Text, "); // Always assume the default delay first. scrollTextDelay = scrollTextDefaultDelay; // Is ScrollText auto or true selected? - scrollTextAktiv = ((json["text"]["scrollText"] == "auto" || ((json["text"]["scrollText"]).is() && json["text"]["scrollText"]))); + scrollTextAktiv = text["scrollText"] == "auto" || (text["scrollText"].is() && text["scrollText"]); - uint8_t r, g, b; - if (json["text"]["hexColor"].as() != NULL) - { - HEXtoRGB(json["text"]["hexColor"].as(), r, g, b); - } - else - { - r = json["text"]["color"]["r"].as(); - g = json["text"]["color"]["g"].as(); - b = json["text"]["color"]["b"].as(); - } + RGBColor textColor; + JsonToRGB(text, textColor); // Is ScrollText auto or true selected? if (scrollTextAktiv) { + bool centerText = text["centerText"]; - bool centerText = json["text"]["centerText"]; - - bool fadeInRequired = ((json.containsKey("bars") || json.containsKey("bar") || json.containsKey("bitmap") || json.containsKey("bitmapAnimation")) && fadeAnimationAktiv); + bool fadeInRequired = ((doc["bars"].is() || doc["bar"].is() || doc["bitmap"].is() || doc["bitmapAnimation"].is()) && fadeAnimationAktiv); // Wurde ein Benutzerdefeniertes Delay übergeben? - if (json["text"]["scrollTextDelay"]) + if (text["scrollTextDelay"]) { - scrollTextDelay = json["text"]["scrollTextDelay"]; + scrollTextDelay = text["scrollTextDelay"]; } - if (!(json["text"]["scrollText"]).is() && json["text"]["scrollText"] == "auto") + if (!(text["scrollText"]).is() && text["scrollText"] == "auto") { - DrawAutoTextScrolled(json["text"]["textString"], json["text"]["bigFont"], centerText, fadeInRequired, r, g, b, json["text"]["position"]["x"], json["text"]["position"]["y"]); + DrawAutoTextScrolled(text["textString"], text["bigFont"], centerText, fadeInRequired, textColor, text["position"]["x"], text["position"]["y"]); } else { - DrawTextScrolled(json["text"]["textString"], json["text"]["bigFont"], centerText, fadeInRequired, r, g, b, json["text"]["position"]["x"], json["text"]["position"]["y"]); + DrawTextScrolled(text["textString"], text["bigFont"], centerText, fadeInRequired, textColor, text["position"]["x"], text["position"]["y"]); } } // is centerText selected? - else if (json["text"]["centerText"]) + else if (text["centerText"]) { - DrawTextCenter(json["text"]["textString"], json["text"]["bigFont"], r, g, b, json["text"]["position"]["x"], json["text"]["position"]["y"]); + DrawTextCenter(text["textString"], text["bigFont"], textColor, text["position"]["x"], text["position"]["y"]); } else { - DrawText(json["text"]["textString"], json["text"]["bigFont"], r, g, b, json["text"]["position"]["x"], json["text"]["position"]["y"]); + DrawText(text["textString"], text["bigFont"], textColor, text["position"]["x"], text["position"]["y"]); } } @@ -1811,7 +1777,7 @@ void CreateFrames(JsonObject &json, int forceDuration) } } - if (sleepMode && !json.containsKey("sleepMode")) + if (sleepMode && !doc["sleepMode"].is()) { logMessage += F("[not all data processed because sleepMode is active]"); } @@ -1821,24 +1787,24 @@ void CreateFrames(JsonObject &json, int forceDuration) logMessage.remove(logMessage.length() - 2); logMessage += F(" "); } - Log(F("CreateFrames"), logMessage + "(Length: " + json.measureLength() + ")"); + Log(F("CreateFrames"), logMessage + "(Length: " + measureJson(doc) + ")"); - if (forceDuration > 0 && (json.containsKey("bitmap") || json.containsKey("bitmaps") || json.containsKey("text") || json.containsKey("bar") || json.containsKey("bars") || json.containsKey("bitmapAnimation"))) + if (forceDuration > 0 && (doc["bitmap"].is() || doc["bitmaps"].is() || doc["text"].is() || doc["bar"].is() || doc["bars"].is() || doc["bitmapAnimation"].is())) { forcedScreenIsActiveUntil = millis() + forceDuration; } - if (!json.containsKey("sleepMode") && !sleepMode) + if (!doc["sleepMode"].is() && !sleepMode) { // Store last frame - json.remove("bitmap"); - json.remove("bitmaps"); - json.remove("bitmapAnimation"); - json["withBMPRestore"] = withBMP; - json["animateBMPAktivLoopRestore"] = animateBMPAktivLoop; + doc.remove("bitmap"); + doc.remove("bitmaps"); + doc.remove("bitmapAnimation"); + doc["withBMPRestore"] = withBMP; + doc["animateBMPAktivLoopRestore"] = animateBMPAktivLoop; currentScreenJsonBuffer = ""; - json.printTo(currentScreenJsonBuffer); + serializeJson(doc, currentScreenJsonBuffer); } if (sendMatrixInfo) @@ -1863,12 +1829,11 @@ String GetConfig() std::unique_ptr buf(new char[size]); configFile.readBytes(buf.get(), size); - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.parseObject(buf.get()); + JsonDocument doc; + deserializeJson(doc, buf.get()); String json; - root.printTo(json); - + serializeJson(doc, json); return json; } return ""; @@ -1876,32 +1841,31 @@ String GetConfig() String GetSensor() { - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.createObject(); + JsonDocument doc; if (tempSensor == TempSensor_BME280) { const float currentTemp = bme280->readTemperature(); - root["temperature"] = currentTemp + temperatureOffset; - root["humidity"] = bme280->readHumidity() + humidityOffset; - root["pressure"] = (bme280->readPressure() / 100.0F) + pressureOffset; - root["gas"] = "Not installed"; + doc["temperature"] = currentTemp + temperatureOffset; + doc["humidity"] = bme280->readHumidity() + humidityOffset; + doc["pressure"] = (bme280->readPressure() / 100.0F) + pressureOffset; + doc["gas"] = "Not installed"; if (temperatureUnit == TemperatureUnit_Fahrenheit) { - root["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; + doc["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; } } else if (tempSensor == TempSensor_DHT) { const float currentTemp = dht.getTemperature(); - root["temperature"] = currentTemp + temperatureOffset; - root["humidity"] = roundf(dht.getHumidity() + humidityOffset); - root["pressure"] = "Not installed"; - root["gas"] = "Not installed"; + doc["temperature"] = currentTemp + temperatureOffset; + doc["humidity"] = roundf(dht.getHumidity() + humidityOffset); + doc["pressure"] = "Not installed"; + doc["gas"] = "Not installed"; if (temperatureUnit == TemperatureUnit_Fahrenheit) { - root["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; + doc["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; } } else if (tempSensor == TempSensor_BME680) @@ -1936,13 +1900,13 @@ String GetSensor() bme680->beginReading(); // start measurement process // return previous values const float currentTemp = bme680->temperature; - root["temperature"] = currentTemp + temperatureOffset; - root["humidity"] = bme680->humidity + humidityOffset; - root["pressure"] = (bme680->pressure / 100.0F) + pressureOffset; - root["gas"] = (bme680->gas_resistance / 1000.0F) + gasOffset; + doc["temperature"] = currentTemp + temperatureOffset; + doc["humidity"] = bme680->humidity + humidityOffset; + doc["pressure"] = (bme680->pressure / 100.0F) + pressureOffset; + doc["gas"] = (bme680->gas_resistance / 1000.0F) + gasOffset; if (temperatureUnit == TemperatureUnit_Fahrenheit) { - root["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; + doc["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; } } @@ -1955,67 +1919,67 @@ String GetSensor() { lastBME680read = millis(); const float currentTemp = bme680->temperature; - root["temperature"] = currentTemp + temperatureOffset; - root["humidity"] = bme680->humidity + humidityOffset; - root["pressure"] = (bme680->pressure / 100.0F) + pressureOffset; - root["gas"] = (bme680->gas_resistance / 1000.0F) + gasOffset; + doc["temperature"] = currentTemp + temperatureOffset; + doc["humidity"] = bme680->humidity + humidityOffset; + doc["pressure"] = (bme680->pressure / 100.0F) + pressureOffset; + doc["gas"] = (bme680->gas_resistance / 1000.0F) + gasOffset; if (temperatureUnit == TemperatureUnit_Fahrenheit) { - root["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; + doc["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; } } else { - root["humidity"] = "Error while reading"; - root["temperature"] = "Error while reading"; - root["pressure"] = "Error while reading"; - root["gas"] = "Error while reading"; + doc["humidity"] = "Error while reading"; + doc["temperature"] = "Error while reading"; + doc["pressure"] = "Error while reading"; + doc["gas"] = "Error while reading"; } } } else if (tempSensor == TempSensor_BMP280) { const float currentTemp = bmp280->readTemperature(); - root["temperature"] = currentTemp + temperatureOffset; - // root["humidity"] = bmp280->readHumidity() + humidityOffset; - root["humidity"] = "Not installed"; - root["pressure"] = (bmp280->readPressure() / 100.0F) + pressureOffset; - root["gas"] = "Not installed"; + doc["temperature"] = currentTemp + temperatureOffset; + // doc["humidity"] = bmp280->readHumidity() + humidityOffset; + doc["humidity"] = "Not installed"; + doc["pressure"] = (bmp280->readPressure() / 100.0F) + pressureOffset; + doc["gas"] = "Not installed"; if (temperatureUnit == TemperatureUnit_Fahrenheit) { - root["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; + doc["temperature"] = CelsiusToFahrenheit(currentTemp) + temperatureOffset; } } else if (tempSensor == TempSensor_SHT31) { const float currentTemp = sht31.readTemperature(); const float currentHumi = sht31.readHumidity(); - root["temperature"] = currentTemp + temperatureOffset; - root["humidity"] = roundf(currentHumi + humidityOffset); - root["pressure"] = "Not installed"; - root["gas"] = "Not installed"; + doc["temperature"] = currentTemp + temperatureOffset; + doc["humidity"] = roundf(currentHumi + humidityOffset); + doc["pressure"] = "Not installed"; + doc["gas"] = "Not installed"; } else { - root["humidity"] = "Not installed"; - root["temperature"] = "Not installed"; - root["pressure"] = "Not installed"; - root["gas"] = "Not installed"; + doc["humidity"] = "Not installed"; + doc["temperature"] = "Not installed"; + doc["pressure"] = "Not installed"; + doc["gas"] = "Not installed"; } if (VBAT_PIN > 0) { - root["battery"] = batteryLevel; + doc["battery"] = batteryLevel; } else { - root["battery"] = "Not installed"; + doc["battery"] = "Not installed"; } - root["hostname"] = hostname; + doc["hostname"] = hostname; String json; - root.printTo(json); + serializeJson(doc, json); // Log(F("Sensor readings"), F("Hum/Temp/Press/Gas:")); // Log(F("Sensor readings"), json); @@ -2024,87 +1988,83 @@ String GetSensor() String GetLuxSensor() { - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.createObject(); + JsonDocument doc; - root["lux"] = currentLux; - root["hostname"] = hostname; + doc["lux"] = currentLux; + doc["hostname"] = hostname; String json; - root.printTo(json); + serializeJson(doc, json); return json; } String GetBrightness() { - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.createObject(); + JsonDocument doc; - root["brightness_255"] = currentMatrixBrightness; - root["brightness"] = map(currentMatrixBrightness, 0, 255, 0, 100); - root["hostname"] = hostname; + doc["brightness_255"] = currentMatrixBrightness; + doc["brightness"] = map(currentMatrixBrightness, 0, 255, 0, 100); + doc["hostname"] = hostname; String json; - root.printTo(json); + serializeJson(doc, json); return json; } String GetMatrixInfo() { - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.createObject(); + JsonDocument doc; - root["pixelitVersion"] = VERSION; + doc["pixelitVersion"] = VERSION; //// Matrix Config - root["note"] = note; - root["hostname"] = hostname; - root["deviceID"] = deviceID; - root["buildSection"] = STR(BUILD_SECTION); - root["freeSketchSpace"] = ESP.getFreeSketchSpace(); - root["wifiRSSI"] = WiFi.RSSI(); - root["wifiQuality"] = GetRSSIasQuality(WiFi.RSSI()); - root["wifiSSID"] = WiFi.SSID(); - root["ipAddress"] = WiFi.localIP().toString(); - root["freeHeap"] = ESP.getFreeHeap(); - root["currentMatrixBrightness"] = currentMatrixBrightness; - root["wifiBSSID"] = WiFi.BSSIDstr(); + doc["note"] = note; + doc["hostname"] = hostname; + doc["deviceID"] = deviceID; + doc["buildSection"] = STR(BUILD_SECTION); + doc["freeSketchSpace"] = ESP.getFreeSketchSpace(); + doc["wifiRSSI"] = WiFi.RSSI(); + doc["wifiQuality"] = GetRSSIasQuality(WiFi.RSSI()); + doc["wifiSSID"] = WiFi.SSID(); + doc["ipAddress"] = WiFi.localIP().toString(); + doc["freeHeap"] = ESP.getFreeHeap(); + doc["currentMatrixBrightness"] = currentMatrixBrightness; + doc["wifiBSSID"] = WiFi.BSSIDstr(); #if defined(ESP8266) - root["sketchSize"] = ESP.getSketchSize(); - root["chipID"] = ESP.getChipId(); + doc["sketchSize"] = ESP.getSketchSize(); + doc["chipID"] = ESP.getChipId(); #elif defined(ESP32) - root["chipID"] = uint64ToString(ESP.getEfuseMac()); + doc["chipID"] = uint64ToString(ESP.getEfuseMac()); #endif - root["cpuFreqMHz"] = ESP.getCpuFreqMHz(); - root["sleepMode"] = sleepMode; - root["uptime"] = millis() / 1000; - root["resetReason"] = ResetReason(); - JsonObject &matrix = root.createNestedObject("matrixsize"); + doc["cpuFreqMHz"] = ESP.getCpuFreqMHz(); + doc["sleepMode"] = sleepMode; + doc["uptime"] = millis() / 1000; + doc["resetReason"] = ResetReason(); + JsonObject matrix = doc["matrixsize"].add(); matrix["cols"] = MATRIX_WIDTH; matrix["rows"] = MATRIX_HEIGHT; String json; - root.printTo(json); + serializeJson(doc, json); return json; } String GetButtons() { - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.createObject(); + JsonDocument doc; for (uint button = 0; button < 3; button++) { - root[btnAPINames[button]] = btnLastPublishState[button] ? "true" : "false"; + doc[btnAPINames[button]] = btnLastPublishState[button] ? "true" : "false"; } - root["hostname"] = hostname; + doc["hostname"] = hostname; String json; - root.printTo(json); + serializeJson(doc, json); return json; } @@ -2124,21 +2084,20 @@ String GetTelemetry() const String TempSensorNames[] = {"none", "BME280", "DHT", "BME680", "BMP280", "SHT31"}; const String LuxSensorNames[] = {"LDR", "BH1750", "Max44009"}; - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.createObject(); + JsonDocument doc; - root["uuid"] = sha1(GetChipID()); - root["version"] = VERSION; - root["type"] = isESP8266 ? "esp8266" : "esp32"; - root["buildSection"] = STR(BUILD_SECTION); + doc["uuid"] = sha1(GetChipID()); + doc["version"] = VERSION; + doc["type"] = isESP8266 ? "esp8266" : "esp32"; + doc["buildSection"] = STR(BUILD_SECTION); - JsonObject &matrix = root.createNestedObject("matrix"); + JsonObject matrix = doc["matrix"].add(); matrix["type"] = matrixType; matrix["name"] = MatrixTypeNames[matrixType - 1]; matrix["width"] = MATRIX_WIDTH; matrix["height"] = MATRIX_HEIGHT; - JsonArray &sensors = root.createNestedArray("sensors"); + JsonArray sensors = doc["sensors"].to(); sensors.add(LuxSensorNames[luxSensor]); if (tempSensor > 0) { @@ -2146,31 +2105,32 @@ String GetTelemetry() } String json; - root.printTo(json); + serializeJson(doc, json); + return json; } -void DrawText(String text, int bigFont, int colorRed, int colorGreen, int colorBlue, int posX, int posY) +void DrawText(String text, int bigFont, RGBColor color, int posX, int posY) { - DrawTextHelper(text, bigFont, false, false, false, false, colorRed, colorGreen, colorBlue, posX, posY); + DrawTextHelper(text, bigFont, false, false, false, false, color, posX, posY); } -void DrawTextCenter(String text, int bigFont, int colorRed, int colorGreen, int colorBlue, int posX, int posY) +void DrawTextCenter(String text, int bigFont, RGBColor color, int posX, int posY) { - DrawTextHelper(text, bigFont, true, false, false, false, colorRed, colorGreen, colorBlue, posX, posY); + DrawTextHelper(text, bigFont, true, false, false, false, color, posX, posY); } -void DrawTextScrolled(String text, int bigFont, bool centerText, bool fadeInRequired, int colorRed, int colorGreen, int colorBlue, int posX, int posY) +void DrawTextScrolled(String text, int bigFont, bool centerText, bool fadeInRequired, RGBColor color, int posX, int posY) { - DrawTextHelper(text, bigFont, centerText, true, false, fadeInRequired, colorRed, colorGreen, colorBlue, posX, posY); + DrawTextHelper(text, bigFont, centerText, true, false, fadeInRequired, color, posX, posY); } -void DrawAutoTextScrolled(String text, int bigFont, bool centerText, bool fadeInRequired, int colorRed, int colorGreen, int colorBlue, int posX, int posY) +void DrawAutoTextScrolled(String text, int bigFont, bool centerText, bool fadeInRequired, RGBColor color, int posX, int posY) { - DrawTextHelper(text, bigFont, centerText, false, true, fadeInRequired, colorRed, colorGreen, colorBlue, posX, posY); + DrawTextHelper(text, bigFont, centerText, false, true, fadeInRequired, color, posX, posY); } -void DrawTextHelper(String text, int bigFont, bool centerText, bool scrollText, bool autoScrollText, bool fadeInRequired, int colorRed, int colorGreen, int colorBlue, int posX, int posY) +void DrawTextHelper(String text, int bigFont, bool centerText, bool scrollText, bool autoScrollText, bool fadeInRequired, RGBColor color, int posX, int posY) { uint16_t xTextWidth, xAvailableTextSpace; int16_t boundsx1, boundsy1; @@ -2235,7 +2195,7 @@ void DrawTextHelper(String text, int bigFont, bool centerText, bool scrollText, matrix->setCursor(posX, posY); - matrix->setTextColor(matrix->Color(colorRed, colorGreen, colorBlue)); + matrix->setTextColor(color); if (scrollText || (autoScrollText && xTextWidth > xAvailableTextSpace)) // scroll text if text is larger than available pixels { @@ -2391,7 +2351,7 @@ void AnimateBMP(bool isShowRequired) } } -void DrawSingleBitmap(JsonObject &json) +void DrawSingleBitmap(JsonObject json) { int16_t h = json["size"]["height"].as(); int16_t w = json["size"]["width"].as(); @@ -2416,7 +2376,7 @@ void DrawSingleBitmap(JsonObject &json) // JsonArray in IntArray konvertieren // dies ist nötig für diverse kleine Logiken z.B. Scrolltext // bei Multibitmaps landet hier nur eine der Bitmaps - das ist aber egal, da dann eh nicht gescrollt wird - json["data"].as().copyTo(bmpArray); + copyArray(json["data"].as(), bmpArray); } void DrawClock(bool fromJSON) @@ -2517,10 +2477,10 @@ void DrawClock(bool fromJSON) if (clockFontIsLarge) // fade rather than vertical animate purely because DrawTextCenter doesnt have a Y argument... { - DrawTextCenter(String(time), clockFontChoice, clockColorR, clockColorG, clockColorB, 0, 1); + DrawTextCenter(String(time), clockFontChoice, clockColor, 0, 1); FadeOut(30); matrix->clear(); - DrawTextCenter(String(date), clockFontChoice, clockColorR, clockColorG, clockColorB, 0, 1); + DrawTextCenter(String(date), clockFontChoice, clockColor, 0, 1); FadeIn(30); } else @@ -2530,8 +2490,8 @@ void DrawClock(bool fromJSON) { counter++; matrix->clear(); - DrawText(String(time), false, clockColorR, clockColorG, clockColorB, xPosTime, (1 + counter)); - DrawText(String(date), false, clockColorR, clockColorG, clockColorB, 7, (-6 + counter)); + DrawText(String(time), false, clockColor, xPosTime, (1 + counter)); + DrawText(String(date), false, clockColor, 7, (-6 + counter)); matrix->drawLine(0, 7, 33, 7, 0); if (clockDrawWeekDays) { @@ -2545,11 +2505,11 @@ void DrawClock(bool fromJSON) else if (clockFontIsLarge) { - DrawTextCenter(String(time), clockFontChoice, clockColorR, clockColorG, clockColorB, 0, 1); + DrawTextCenter(String(time), clockFontChoice, clockColor, 0, 1); } else { - DrawText(String(time), false, clockColorR, clockColorG, clockColorB, xPosTime, 1); + DrawText(String(time), false, clockColor, xPosTime, 1); xPosTime = 3; } } @@ -2563,10 +2523,10 @@ void DrawClock(bool fromJSON) if (clockFontIsLarge) // fade rather than vertical animate purely because DrawTextCenter doesnt have a Y argument... { - DrawTextCenter(String(date), 2, clockColorR, clockColorG, clockColorB, 0, 1); + DrawTextCenter(String(date), 2, clockColor, 0, 1); FadeOut(30); matrix->clear(); - DrawTextCenter(String(time), 2, clockColorR, clockColorG, clockColorB, 0, 1); + DrawTextCenter(String(time), 2, clockColor, 0, 1); FadeIn(30); } else @@ -2576,8 +2536,8 @@ void DrawClock(bool fromJSON) { counter++; matrix->clear(); - DrawText(String(date), false, clockColorR, clockColorG, clockColorB, 7, (1 + counter)); - DrawText(String(time), false, clockColorR, clockColorG, clockColorB, xPosTime, (-6 + counter)); + DrawText(String(date), false, clockColor, 7, (1 + counter)); + DrawText(String(time), false, clockColor, xPosTime, (-6 + counter)); matrix->drawLine(0, 7, 33, 7, 0); if (clockDrawWeekDays) { @@ -2590,11 +2550,11 @@ void DrawClock(bool fromJSON) } else if (clockFontIsLarge) { - DrawTextCenter(String(date), clockFontChoice, clockColorR, clockColorG, clockColorB, 0, 1); + DrawTextCenter(String(date), clockFontChoice, clockColor, 0, 1); } else { - DrawText(String(date), false, clockColorR, clockColorG, clockColorB, 7, 1); + DrawText(String(date), false, clockColor, 7, 1); } } @@ -2629,11 +2589,11 @@ void DrawWeekDay() { if (i == weekDayNumber) { - matrix->drawLine(2 + i * 4, 7, i * 4 + 4, 7, matrix->Color(clockColorR, clockColorG, clockColorB)); + matrix->drawLine(2 + i * 4, 7, i * 4 + 4, 7, clockColor); } else { - matrix->drawLine(2 + i * 4, 7, i * 4 + 4, 7, 21162); + matrix->drawLine(2 + i * 4, 7, i * 4 + 4, 7, RGBColor(211, 162, 62)); } } } @@ -3144,7 +3104,7 @@ void ColoredBarWipe() } } -void ZigZagWipe(uint8_t r, uint8_t g, uint8_t b) +void ZigZagWipe(RGBColor color) { for (uint16_t row = 0; row <= 7; row += 2) { @@ -3153,14 +3113,14 @@ void ZigZagWipe(uint8_t r, uint8_t g, uint8_t b) if (row == 0 || row == 4) { matrix->fillRect(0, row, col - 1, 2, matrix->Color(0, 0, 0)); - matrix->drawFastVLine(col - 1, row, 2, matrix->Color(r, g, b)); - matrix->drawFastVLine(col, row, 2, matrix->Color(r, g, b)); + matrix->drawFastVLine(col - 1, row, 2, color); + matrix->drawFastVLine(col, row, 2, color); } else { matrix->fillRect(32 - col, row, col, 2, matrix->Color(0, 0, 0)); - matrix->drawFastVLine(32 - col, row, 2, matrix->Color(r, g, b)); - matrix->drawFastVLine(32 - col - 1, row, 2, matrix->Color(r, g, b)); + matrix->drawFastVLine(32 - col, row, 2, color); + matrix->drawFastVLine(32 - col - 1, row, 2, color); } matrix->show(); delay(5); @@ -3168,13 +3128,13 @@ void ZigZagWipe(uint8_t r, uint8_t g, uint8_t b) matrix->fillRect(0, row, 32, 2, matrix->Color(0, 0, 0)); if (row == 0 || row == 4) { - matrix->drawFastVLine(30, row + 1, 2, matrix->Color(r, g, b)); - matrix->drawFastVLine(31, row + 1, 2, matrix->Color(r, g, b)); + matrix->drawFastVLine(30, row + 1, 2, color); + matrix->drawFastVLine(31, row + 1, 2, color); } else { - matrix->drawFastVLine(0, row + 1, 2, matrix->Color(r, g, b)); - matrix->drawFastVLine(1, row + 1, 2, matrix->Color(r, g, b)); + matrix->drawFastVLine(0, row + 1, 2, color); + matrix->drawFastVLine(1, row + 1, 2, color); } matrix->show(); delay(5); @@ -3184,7 +3144,7 @@ void ZigZagWipe(uint8_t r, uint8_t g, uint8_t b) matrix->show(); } -void BitmapWipe(JsonArray &data, int16_t w) +void BitmapWipe(JsonArray data, int16_t w) { for (int16_t x = -w + 1; x <= 31; x++) { @@ -3203,13 +3163,13 @@ void BitmapWipe(JsonArray &data, int16_t w) } } -void ColorFlash(int red, int green, int blue) +void ColorFlash(RGBColor color) { for (uint16_t row = 0; row < 8; row++) { for (uint16_t column = 0; column < 32; column++) { - matrix->drawPixel(column, row, matrix->Color(red, green, blue)); + matrix->drawPixel(column, row, color); } } matrix->show(); @@ -3235,39 +3195,38 @@ uint ColorWheel(byte wheelPos, int pos) void ShowBootAnimation() { - DrawTextHelper("P", false, false, false, false, false, 255, 51, 255, (MATRIX_WIDTH / 2) - 12, 1); + DrawTextHelper("P", false, false, false, false, false, RGBColor(255, 51, 255), (MATRIX_WIDTH / 2) - 12, 1); matrix->show(); delay(200); - DrawTextHelper("I", false, false, false, false, false, 0, 255, 42, (MATRIX_WIDTH / 2) - 8, 1); + DrawTextHelper("I", false, false, false, false, false, RGBColor(0, 255, 42), (MATRIX_WIDTH / 2) - 8, 1); matrix->show(); delay(200); - DrawTextHelper("X", false, false, false, false, false, 255, 25, 25, (MATRIX_WIDTH / 2) - 6, 1); + DrawTextHelper("X", false, false, false, false, false, RGBColor(255, 25, 25), (MATRIX_WIDTH / 2) - 6, 1); matrix->show(); delay(200); - DrawTextHelper("E", false, false, false, false, false, 25, 255, 255, (MATRIX_WIDTH / 2) - 2, 1); + DrawTextHelper("E", false, false, false, false, false, RGBColor(25, 255, 255), (MATRIX_WIDTH / 2) - 2, 1); matrix->show(); delay(200); - DrawTextHelper("L", false, false, false, false, false, 255, 221, 51, (MATRIX_WIDTH / 2) + 2, 1); + DrawTextHelper("L", false, false, false, false, false, RGBColor(255, 221, 51), (MATRIX_WIDTH / 2) + 2, 1); matrix->show(); delay(500); - DrawTextHelper("I", false, false, false, false, false, 255, 255, 255, (MATRIX_WIDTH / 2) + 6, 1); - DrawTextHelper("T", false, false, false, false, false, 255, 255, 255, (MATRIX_WIDTH / 2) + 8, 1); + DrawTextHelper("I", false, false, false, false, false, RGBColor(255, 255, 255), (MATRIX_WIDTH / 2) + 6, 1); + DrawTextHelper("T", false, false, false, false, false, RGBColor(255, 255, 255), (MATRIX_WIDTH / 2) + 8, 1); matrix->show(); delay(1000); } void ShowBatteryScreen() { - const size_t capacity = JSON_ARRAY_SIZE(64) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 350; - DynamicJsonBuffer jsonBuffer(capacity); + JsonDocument doc; const char *json = "{\"bitmap\":{\"data\":[0,0,65535,65535,65535,0,0,0,0,0,65535,2016,65535,0,0,0,0,65535,2016,2016,2016,65535,0,0,0,65535,2016,2016,2016,65535,0,0,0,65535,2016,2016,2016,65535,0,0,0,65535,2016,2016,2016,65535,0,0,0,65535,2016,2016,2016,65535,0,0,0,65535,65535,65535,65535,65535,0,0],\"position\":{\"x\":0,\"y\":0},\"size\":{\"width\":8,\"height\":8}}}"; - JsonObject &root = jsonBuffer.parseObject(json); - if (root.success()) + DeserializationError error = deserializeJson(doc, json); + if (!error) { Serial.println("parsed json"); } @@ -3277,8 +3236,8 @@ void ShowBatteryScreen() } getBatteryVoltage(); matrix->clear(); - DrawSingleBitmap(root["bitmap"]); - DrawTextHelper(String(batteryLevel, 0) + "%", false, true, false, false, false, 255, 255, 255, 9, 1); + DrawSingleBitmap(doc["bitmap"]); + DrawTextHelper(String(batteryLevel, 0) + "%", false, true, false, false, false, RGBColor(), 9, 1); matrix->show(); delay(1000); } @@ -3848,14 +3807,12 @@ void displayUpdateScreen() { Log(F("UpdateScreen"), F("Display UpdateScreen...")); - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.createObject(); + JsonDocument doc; - BuildUpdateScreenJSON(root); - - if (root.success()) + BuildUpdateScreenJSON(doc); + if (!doc.isNull()) { - CreateFrames(root, CHECKUPDATESCREEN_DURATION); + CreateFrames(doc, CHECKUPDATESCREEN_DURATION); } else { @@ -3880,11 +3837,11 @@ void checkUpdate() if (statusCode == 200) { - DynamicJsonBuffer jsonBuffer; - JsonObject &root = jsonBuffer.parseObject(response); - if (root.containsKey("version")) + JsonDocument doc; + deserializeJson(doc, response); + if (doc["version"].is()) { - lastReleaseVersion = root["version"].as(); + lastReleaseVersion = doc["version"].as(); int result = compareVersions(lastReleaseVersion.c_str(), VERSION); @@ -4043,7 +4000,7 @@ void loop() } else if (performWipe == 3) { - ZigZagWipe(clockColorR, clockColorG, clockColorB); + ZigZagWipe(clockColor); } clockAktiv = true; clockCounterClock = 0; @@ -4176,8 +4133,7 @@ void SendMatrixInfo() { for (uint i = 0; i < sizeof websocketConnection / sizeof websocketConnection[0]; i++) { - String payload = "{\"sysinfo\":" + matrixInfo + "}"; - webSocket.sendTXT(i, payload); + SendWsText(i, "{\"sysinfo\":" + matrixInfo + "}"); } } } @@ -4211,8 +4167,7 @@ void SendLDR(bool force) { for (unsigned int i = 0; i < sizeof websocketConnection / sizeof websocketConnection[0]; i++) { - String payload = "{\"sensor\":" + luxSensor + "}"; - webSocket.sendTXT(i, payload); + SendWsText(i, "{\"sensor\":" + luxSensor + "}"); } } @@ -4259,8 +4214,7 @@ void SendSensor(bool force) { for (uint i = 0; i < sizeof websocketConnection / sizeof websocketConnection[0]; i++) { - String payload = "{\"sensor\":" + Sensor + "}"; - webSocket.sendTXT(i, payload); + SendWsText(i, "{\"sensor\":" + Sensor + "}"); } } @@ -4273,8 +4227,8 @@ void SendConfig() { for (uint i = 0; i < sizeof websocketConnection / sizeof websocketConnection[0]; i++) { - String payload = "{\"config\":" + GetConfig() + "}"; - webSocket.sendTXT(i, payload); + String config = GetConfig(); + SendWsText(i, "{\"config\":" + config + "}"); } } } @@ -4335,38 +4289,6 @@ void sendNTPpacket(String &address) udp.endPacket(); } -// decode hex string into R G B decimals -void HexToRgb(String hex, uint8_t &red, uint8_t &green, uint8_t &blue) -{ - const char *hexString = (hex[0] == '#') ? hex.c_str() + 1 : hex.c_str(); - long number = strtol(hexString, nullptr, 16); - red = (number >> 16) & 0xFF; - green = (number >> 8) & 0xFF; - blue = number & 0xFF; -} - -// convert R G B decimal values to hex string -void RgbToHex(uint8_t red, uint8_t green, uint8_t blue, String &hex) -{ - String redHex = String(red, HEX); - if (redHex.length() < 2) - { - redHex = "0" + redHex; - } - String greenHex = String(green, HEX); - if (greenHex.length() < 2) - { - greenHex = "0" + greenHex; - } - String blueHex = String(blue, HEX); - if (blueHex.length() < 2) - { - blueHex = "0" + blueHex; - } - hex = "#" + redHex + greenHex + blueHex; - hex.toUpperCase(); -} - void Log(String function, String message) {