Merge branch 'main' into seg-groups

This commit is contained in:
Blaz Kristan 2023-05-15 17:06:38 +02:00
commit 4a567ab97c
18 changed files with 735 additions and 604 deletions

View File

@ -17,7 +17,7 @@ default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB ; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB
# Build everything # Build everything
; default_envs = esp32dev, esp8285_4CH_MagicHome, codm-controller-0.6-rev2, codm-controller-0.6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips ; default_envs = esp32dev, esp8285_4CH_MagicHome, codm-controller-0_6-rev2, codm-controller-0_6, esp32s2_saola, d1_mini_5CH_Shojo_PCB, d1_mini, sp501e, nodemcuv2, esp32_eth, anavi_miracle_controller, esp07, esp01_1m_full, m5atom, h803wf, d1_mini_ota, heltec_wifi_kit_8, esp8285_H801, d1_mini_debug, wemos_shield_esp32, elekstube_ips
# Single binaries (uncomment your board) # Single binaries (uncomment your board)
; default_envs = elekstube_ips ; default_envs = elekstube_ips
@ -727,10 +727,10 @@ lib_deps = ${esp8266.lib_deps}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# codm pixel controller board configurations # codm pixel controller board configurations
# codm-controller-0.6 can also be used for the TYWE3S controller # codm-controller-0_6 can also be used for the TYWE3S controller
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
[env:codm-controller-0.6] [env:codm-controller-0_6]
board = esp_wroom_02 board = esp_wroom_02
platform = ${common.platform_wled_default} platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages} platform_packages = ${common.platform_packages}
@ -739,7 +739,7 @@ build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} build_flags = ${common.build_flags_esp8266}
lib_deps = ${esp8266.lib_deps} lib_deps = ${esp8266.lib_deps}
[env:codm-controller-0.6-rev2] [env:codm-controller-0_6-rev2]
board = esp_wroom_02 board = esp_wroom_02
platform = ${common.platform_wled_default} platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages} platform_packages = ${common.platform_packages}

View File

@ -26,6 +26,15 @@
#endif #endif
#endif #endif
//the default ratio for the voltage divider
#ifndef USERMOD_BATTERY_VOLTAGE_MULTIPLIER
#ifdef ARDUINO_ARCH_ESP32
#define USERMOD_BATTERY_VOLTAGE_MULTIPLIER 2.0f
#else //ESP8266 boards
#define USERMOD_BATTERY_VOLTAGE_MULTIPLIER 4.2f
#endif
#endif
#ifndef USERMOD_BATTERY_MAX_VOLTAGE #ifndef USERMOD_BATTERY_MAX_VOLTAGE
#define USERMOD_BATTERY_MAX_VOLTAGE 4.2f #define USERMOD_BATTERY_MAX_VOLTAGE 4.2f
#endif #endif

View File

@ -29,6 +29,10 @@ class UsermodBattery : public Usermod
float rawValue = 0.0f; float rawValue = 0.0f;
// calculated voltage // calculated voltage
float voltage = maxBatteryVoltage; float voltage = maxBatteryVoltage;
// between 0 and 1, to control strength of voltage smoothing filter
float alpha = 0.05f;
// multiplier for the voltage divider that is in place between ADC pin and battery, default will be 2 but might be adapted to readout voltages over ~5v ESP32 or ~6.6v ESP8266
float voltageMultiplier = USERMOD_BATTERY_VOLTAGE_MULTIPLIER;
// mapped battery level based on voltage // mapped battery level based on voltage
int8_t batteryLevel = 100; int8_t batteryLevel = 100;
// offset or calibration value to fine tune the calculated voltage // offset or calibration value to fine tune the calculated voltage
@ -110,6 +114,17 @@ class UsermodBattery : public Usermod
} }
} }
float readVoltage()
{
#ifdef ARDUINO_ARCH_ESP32
// use calibrated millivolts analogread on esp32 (150 mV ~ 2450 mV default attentuation) and divide by 1000 to get from milivolts to volts and multiply by voltage multiplier and apply calibration value
return (analogReadMilliVolts(batteryPin) / 1000.0f) * voltageMultiplier + calibration;
#else
// use analog read on esp8266 ( 0V ~ 1V no attenuation options) and divide by ADC precision 1023 and multiply by voltage multiplier and apply calibration value
return (analogRead(batteryPin) / 1023.0f) * voltageMultiplier + calibration;
#endif
}
public: public:
//Functions called by WLED //Functions called by WLED
@ -126,6 +141,7 @@ class UsermodBattery : public Usermod
if (pinManager.allocatePin(batteryPin, false, PinOwner::UM_Battery)) { if (pinManager.allocatePin(batteryPin, false, PinOwner::UM_Battery)) {
DEBUG_PRINTLN(F("Battery pin allocation succeeded.")); DEBUG_PRINTLN(F("Battery pin allocation succeeded."));
success = true; success = true;
voltage = readVoltage();
} }
if (!success) { if (!success) {
@ -135,8 +151,8 @@ class UsermodBattery : public Usermod
pinMode(batteryPin, INPUT); pinMode(batteryPin, INPUT);
} }
#else //ESP8266 boards have only one analog input pin A0 #else //ESP8266 boards have only one analog input pin A0
pinMode(batteryPin, INPUT); pinMode(batteryPin, INPUT);
voltage = readVoltage();
#endif #endif
nextReadTime = millis() + readingInterval; nextReadTime = millis() + readingInterval;
@ -176,22 +192,12 @@ class UsermodBattery : public Usermod
initializing = false; initializing = false;
#ifdef ARDUINO_ARCH_ESP32 rawValue = readVoltage();
// use calibrated millivolts analogread on esp32 (150 mV ~ 2450 mV) // filter with exponential smoothing because ADC in esp32 is fluctuating too much for a good single readout
rawValue = analogReadMilliVolts(batteryPin); voltage = voltage + alpha * (rawValue - voltage);
// calculate the voltage
voltage = (rawValue / 1000.0f) + calibration;
// usually a voltage divider (50%) is used on ESP32, so we need to multiply by 2
voltage *= 2.0f;
#else
// read battery raw input
rawValue = analogRead(batteryPin);
// calculate the voltage // check if voltage is within specified voltage range, allow 10% over/under voltage - removed cause this just makes it hard for people to troubleshoot as the voltage in the web gui will say invalid instead of displaying a voltage
voltage = ((rawValue / getAdcPrecision()) * maxBatteryVoltage) + calibration; //voltage = ((voltage < minBatteryVoltage * 0.85f) || (voltage > maxBatteryVoltage * 1.1f)) ? -1.0f : voltage;
#endif
// check if voltage is within specified voltage range, allow 10% over/under voltage
voltage = ((voltage < minBatteryVoltage * 0.85f) || (voltage > maxBatteryVoltage * 1.1f)) ? -1.0f : voltage;
// translate battery voltage into percentage // translate battery voltage into percentage
/* /*
@ -363,6 +369,7 @@ class UsermodBattery : public Usermod
battery[F("max-voltage")] = maxBatteryVoltage; battery[F("max-voltage")] = maxBatteryVoltage;
battery[F("capacity")] = totalBatteryCapacity; battery[F("capacity")] = totalBatteryCapacity;
battery[F("calibration")] = calibration; battery[F("calibration")] = calibration;
battery[F("voltage-multiplier")] = voltageMultiplier;
battery[FPSTR(_readInterval)] = readingInterval; battery[FPSTR(_readInterval)] = readingInterval;
JsonObject ao = battery.createNestedObject(F("auto-off")); // auto off section JsonObject ao = battery.createNestedObject(F("auto-off")); // auto off section
@ -375,6 +382,9 @@ class UsermodBattery : public Usermod
lp[FPSTR(_threshold)] = lowPowerIndicatorThreshold; lp[FPSTR(_threshold)] = lowPowerIndicatorThreshold;
lp[FPSTR(_duration)] = lowPowerIndicatorDuration; lp[FPSTR(_duration)] = lowPowerIndicatorDuration;
// read voltage in case calibration or voltage multiplier changed to see immediate effect
voltage = readVoltage();
DEBUG_PRINTLN(F("Battery config saved.")); DEBUG_PRINTLN(F("Battery config saved."));
} }
@ -439,6 +449,7 @@ class UsermodBattery : public Usermod
setMaxBatteryVoltage(battery[F("max-voltage")] | maxBatteryVoltage); setMaxBatteryVoltage(battery[F("max-voltage")] | maxBatteryVoltage);
setTotalBatteryCapacity(battery[F("capacity")] | totalBatteryCapacity); setTotalBatteryCapacity(battery[F("capacity")] | totalBatteryCapacity);
setCalibration(battery[F("calibration")] | calibration); setCalibration(battery[F("calibration")] | calibration);
setVoltageMultiplier(battery[F("voltage-multiplier")] | voltageMultiplier);
setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval); setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval);
JsonObject ao = battery[F("auto-off")]; JsonObject ao = battery[F("auto-off")];
@ -595,21 +606,7 @@ class UsermodBattery : public Usermod
totalBatteryCapacity = capacity; totalBatteryCapacity = capacity;
} }
/*
* Get the choosen adc precision
* esp8266 = 10bit resolution = 1024.0f
* esp32 = 12bit resolution = 4095.0f
*/
float getAdcPrecision()
{
#ifdef ARDUINO_ARCH_ESP32
// esp32
return 4096.0f;
#else
// esp8266
return 1024.0f;
#endif
}
/* /*
* Get the calculated voltage * Get the calculated voltage
@ -647,6 +644,23 @@ class UsermodBattery : public Usermod
calibration = offset; calibration = offset;
} }
/*
* Set the voltage multiplier value
* A multiplier that may need adjusting for different voltage divider setups
*/
void setVoltageMultiplier(float multiplier)
{
voltageMultiplier = multiplier;
}
/*
* Get the voltage multiplier value
* A multiplier that may need adjusting for different voltage divider setups
*/
float getVoltageMultiplier()
{
return voltageMultiplier;
}
/* /*
* Get auto-off feature enabled status * Get auto-off feature enabled status

View File

@ -1,13 +1,12 @@
; Options ; Options
; ------- ; -------
; USERMOD_DALLASTEMPERATURE - define this to have this user mod included wled00\usermods_list.cpp ; USERMOD_DALLASTEMPERATURE - define this to have this user mod included wled00\usermods_list.cpp
; USERMOD_DALLASTEMPERATURE_CELSIUS - define this to report temperatures in degrees celsius, otherwise fahrenheit will be reported
; USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds ; USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds
; USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT - the number of milliseconds after boot to take first measurement, defaults to 20 seconds
; ;
[env:d1_mini_usermod_dallas_temperature_C] [env:d1_mini_usermod_dallas_temperature_C]
extends = env:d1_mini extends = env:d1_mini
build_flags = ${common.build_flags_esp8266} -D USERMOD_DALLASTEMPERATURE -D USERMOD_DALLASTEMPERATURE_CELSIUS build_flags = ${common.build_flags_esp8266} -D USERMOD_DALLASTEMPERATURE
lib_deps = ${env.lib_deps} lib_deps = ${env.lib_deps}
milesburton/DallasTemperature@^3.9.0 paulstoffregen/OneWire@~2.3.7
OneWire@~2.3.5 # you may want to use following with ESP32
; https://github.com/blazoncek/OneWire.git # fixes Sensor error on ESP32

View File

@ -7,6 +7,8 @@ May be expanded with support for different sensor types in the future.
If temperature sensor is not detected during boot, this usermod will be disabled. If temperature sensor is not detected during boot, this usermod will be disabled.
Maintained by @blazoncek
## Installation ## Installation
Copy the example `platformio_override.ini` to the root directory. This file should be placed in the same directory as `platformio.ini`. Copy the example `platformio_override.ini` to the root directory. This file should be placed in the same directory as `platformio.ini`.
@ -14,7 +16,7 @@ Copy the example `platformio_override.ini` to the root directory. This file sho
### Define Your Options ### Define Your Options
* `USERMOD_DALLASTEMPERATURE` - enables this user mod wled00/usermods_list.cpp * `USERMOD_DALLASTEMPERATURE` - enables this user mod wled00/usermods_list.cpp
* `USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT` - number of milliseconds after boot to take first measurement, defaults to 20000 ms * `USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL` - number of milliseconds between measurements, defaults to 60000 ms (60s)
All parameters can be configured at runtime via the Usermods settings page, including pin, temperature in degrees Celsius or Farenheit and measurement interval. All parameters can be configured at runtime via the Usermods settings page, including pin, temperature in degrees Celsius or Farenheit and measurement interval.
@ -27,7 +29,6 @@ All parameters can be configured at runtime via the Usermods settings page, incl
If you are using `platformio_override.ini`, you should be able to refresh the task list and see your custom task, for example `env:d1_mini_usermod_dallas_temperature_C`. If you are using `platformio_override.ini`, you should be able to refresh the task list and see your custom task, for example `env:d1_mini_usermod_dallas_temperature_C`.
If you are not using `platformio_override.ini`, you might have to uncomment `OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: If you are not using `platformio_override.ini`, you might have to uncomment `OneWire@~2.3.5 under` `[common]` section in `platformio.ini`:
```ini ```ini
@ -43,8 +44,9 @@ default_envs = d1_mini
lib_deps = lib_deps =
... ...
#For Dallas sensor uncomment following line #For Dallas sensor uncomment following line
OneWire@~2.3.5 OneWire@~2.3.7
... # ... or you may want to use following with ESP32
; https://github.com/blazoncek/OneWire.git # fixes Sensor error on ESP32...
``` ```
## Change Log ## Change Log
@ -56,3 +58,6 @@ lib_deps =
* Report the number of seconds until the first read in the info screen instead of sensor error * Report the number of seconds until the first read in the info screen instead of sensor error
2021-04 2021-04
* Adaptation for runtime configuration. * Adaptation for runtime configuration.
2023-05
* Rewrite to conform to newer recommendations.
* Recommended @blazoncek fork of OneWire for ESP32 to avoid Sensor error

View File

@ -57,7 +57,47 @@ class UsermodTemperature : public Usermod {
static const char _parasitePin[]; static const char _parasitePin[];
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013 //Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float readDallas() { float readDallas();
void requestTemperatures();
void readTemperature();
bool findSensor();
#ifndef WLED_DISABLE_MQTT
void publishHomeAssistantAutodiscovery();
#endif
public:
/*
* API calls te enable data exchange between WLED modules
*/
inline float getTemperatureC() { return temperature; }
inline float getTemperatureF() { return temperature * 1.8f + 32.0f; }
float getTemperature();
const char *getTemperatureUnit();
uint16_t getId() { return USERMOD_ID_TEMPERATURE; }
void setup();
void loop();
//void connected();
#ifndef WLED_DISABLE_MQTT
void onMqttConnect(bool sessionPresent);
#endif
//void onUpdateBegin(bool init);
//bool handleButton(uint8_t b);
//void handleOverlayDraw();
void addToJsonInfo(JsonObject& root);
//void addToJsonState(JsonObject &root);
//void readFromJsonState(JsonObject &root);
void addToConfig(JsonObject &root);
bool readFromConfig(JsonObject &root);
void appendConfigData();
};
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float UsermodTemperature::readDallas() {
byte data[9]; byte data[9];
int16_t result; // raw data from sensor int16_t result; // raw data from sensor
float retVal = -127.0f; float retVal = -127.0f;
@ -92,7 +132,7 @@ class UsermodTemperature : public Usermod {
return data[0]==0xFF ? -127.0f : retVal; return data[0]==0xFF ? -127.0f : retVal;
} }
void requestTemperatures() { void UsermodTemperature::requestTemperatures() {
DEBUG_PRINTLN(F("Requesting temperature.")); DEBUG_PRINTLN(F("Requesting temperature."));
oneWire->reset(); oneWire->reset();
oneWire->skip(); // skip ROM oneWire->skip(); // skip ROM
@ -102,7 +142,7 @@ class UsermodTemperature : public Usermod {
waitingForConversion = true; waitingForConversion = true;
} }
void readTemperature() { void UsermodTemperature::readTemperature() {
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET) if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
temperature = readDallas(); temperature = readDallas();
lastMeasurement = millis(); lastMeasurement = millis();
@ -112,7 +152,7 @@ class UsermodTemperature : public Usermod {
DEBUG_PRINTLN(temperature); DEBUG_PRINTLN(temperature);
} }
bool findSensor() { bool UsermodTemperature::findSensor() {
DEBUG_PRINTLN(F("Searching for sensor...")); DEBUG_PRINTLN(F("Searching for sensor..."));
uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0}; uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0};
// find out if we have DS18xxx sensor attached // find out if we have DS18xxx sensor attached
@ -139,7 +179,7 @@ class UsermodTemperature : public Usermod {
} }
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
void publishHomeAssistantAutodiscovery() { void UsermodTemperature::publishHomeAssistantAutodiscovery() {
if (!WLED_MQTT_CONNECTED) return; if (!WLED_MQTT_CONNECTED) return;
char json_str[1024], buf[128]; char json_str[1024], buf[128];
@ -162,9 +202,7 @@ class UsermodTemperature : public Usermod {
} }
#endif #endif
public: void UsermodTemperature::setup() {
void setup() {
int retries = 10; int retries = 10;
sensorFound = 0; sensorFound = 0;
temperature = -127.0f; // default to -127, DS18B20 only goes down to -50C temperature = -127.0f; // default to -127, DS18B20 only goes down to -50C
@ -196,7 +234,7 @@ class UsermodTemperature : public Usermod {
initDone = true; initDone = true;
} }
void loop() { void UsermodTemperature::loop() {
if (!enabled || !sensorFound || strip.isUpdating()) return; if (!enabled || !sensorFound || strip.isUpdating()) return;
static uint8_t errorCount = 0; static uint8_t errorCount = 0;
@ -248,13 +286,13 @@ class UsermodTemperature : public Usermod {
* connected() is called every time the WiFi is (re)connected * connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces * Use it to initialize network interfaces
*/ */
//void connected() {} //void UsermodTemperature::connected() {}
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
/** /**
* subscribe to MQTT topic if needed * subscribe to MQTT topic if needed
*/ */
void onMqttConnect(bool sessionPresent) { void UsermodTemperature::onMqttConnect(bool sessionPresent) {
//(re)subscribe to required topics //(re)subscribe to required topics
//char subuf[64]; //char subuf[64];
if (mqttDeviceTopic[0] != 0) { if (mqttDeviceTopic[0] != 0) {
@ -263,22 +301,12 @@ class UsermodTemperature : public Usermod {
} }
#endif #endif
/*
* API calls te enable data exchange between WLED modules
*/
inline float getTemperatureC() {
return (float)temperature;
}
inline float getTemperatureF() {
return (float)temperature * 1.8f + 32;
}
/* /*
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI. * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor * Below it is shown how this could be used for e.g. a light sensor
*/ */
void addToJsonInfo(JsonObject& root) { void UsermodTemperature::addToJsonInfo(JsonObject& root) {
// dont add temperature to info if we are disabled // dont add temperature to info if we are disabled
if (!enabled) return; if (!enabled) return;
@ -293,21 +321,21 @@ class UsermodTemperature : public Usermod {
return; return;
} }
temp.add(degC ? getTemperatureC() : getTemperatureF()); temp.add(getTemperature());
temp.add(degC ? F("°C") : F("°F")); temp.add(getTemperatureUnit());
JsonObject sensor = root[F("sensor")]; JsonObject sensor = root[F("sensor")];
if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
temp = sensor.createNestedArray(F("temp")); temp = sensor.createNestedArray(F("temperature"));
temp.add(degC ? temperature : (float)temperature * 1.8f + 32); temp.add(getTemperature());
temp.add(degC ? F("°C") : F("°F")); temp.add(getTemperatureUnit());
} }
/** /**
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients * Values in the state object may be modified by connected clients
*/ */
//void addToJsonState(JsonObject &root) //void UsermodTemperature::addToJsonState(JsonObject &root)
//{ //{
//} //}
@ -316,14 +344,14 @@ class UsermodTemperature : public Usermod {
* Values in the state object may be modified by connected clients * Values in the state object may be modified by connected clients
* Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used. * Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used.
*/ */
//void readFromJsonState(JsonObject &root) { //void UsermodTemperature::readFromJsonState(JsonObject &root) {
// if (!initDone) return; // prevent crash on boot applyPreset() // if (!initDone) return; // prevent crash on boot applyPreset()
//} //}
/** /**
* addToConfig() (called from set.cpp) stores persistent properties to cfg.json * addToConfig() (called from set.cpp) stores persistent properties to cfg.json
*/ */
void addToConfig(JsonObject &root) { void UsermodTemperature::addToConfig(JsonObject &root) {
// we add JSON object: {"Temperature": {"pin": 0, "degC": true}} // we add JSON object: {"Temperature": {"pin": 0, "degC": true}}
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
top[FPSTR(_enabled)] = enabled; top[FPSTR(_enabled)] = enabled;
@ -340,7 +368,7 @@ class UsermodTemperature : public Usermod {
* *
* The function should return true if configuration was successfully loaded or false if there was no configuration. * The function should return true if configuration was successfully loaded or false if there was no configuration.
*/ */
bool readFromConfig(JsonObject &root) { bool UsermodTemperature::readFromConfig(JsonObject &root) {
// we look for JSON object: {"Temperature": {"pin": 0, "degC": true}} // we look for JSON object: {"Temperature": {"pin": 0, "degC": true}}
int8_t newTemperaturePin = temperaturePin; int8_t newTemperaturePin = temperaturePin;
DEBUG_PRINT(FPSTR(_name)); DEBUG_PRINT(FPSTR(_name));
@ -381,19 +409,20 @@ class UsermodTemperature : public Usermod {
return !top[FPSTR(_parasitePin)].isNull(); return !top[FPSTR(_parasitePin)].isNull();
} }
void appendConfigData() void UsermodTemperature::appendConfigData() {
{
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str()); oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str());
oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str()); oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
} }
uint16_t getId() float UsermodTemperature::getTemperature() {
{ return degC ? getTemperatureC() : getTemperatureF();
return USERMOD_ID_TEMPERATURE; }
const char *UsermodTemperature::getTemperatureUnit() {
return degC ? "°C" : "°F";
} }
};
// strings to reduce flash memory usage (used more than twice) // strings to reduce flash memory usage (used more than twice)
const char UsermodTemperature::_name[] PROGMEM = "Temperature"; const char UsermodTemperature::_name[] PROGMEM = "Temperature";

View File

@ -1,31 +0,0 @@
#include "wled.h"
/*
* Register your v2 usermods here!
*/
/*
* Add/uncomment your usermod filename here (and once more below)
* || || ||
* \/ \/ \/
*/
//#include "usermod_v2_example.h"
#ifdef USERMOD_DALLASTEMPERATURE
#include "../usermods/Temperature/usermod_temperature.h"
#endif
//#include "usermod_v2_empty.h"
void registerUsermods()
{
/*
* Add your usermod class name here
* || || ||
* \/ \/ \/
*/
//usermods.add(new MyExampleUsermod());
#ifdef USERMOD_DALLASTEMPERATURE
usermods.add(new UsermodTemperature());
#endif
//usermods.add(new UsermodRenameMe());
}

View File

@ -22,7 +22,7 @@ class ShtUsermod : public Usermod
bool haMqttDiscoveryDone = false; // Remembers if we already published the HA discovery topics bool haMqttDiscoveryDone = false; // Remembers if we already published the HA discovery topics
// SHT vars // SHT vars
SHT *shtTempHumidSensor; // Instance of SHT lib SHT *shtTempHumidSensor = nullptr; // Instance of SHT lib
byte shtType = 0; // SHT sensor type to be used. Default: SHT30 byte shtType = 0; // SHT sensor type to be used. Default: SHT30
byte unitOfTemp = 0; // Temperature unit to be used. Default: Celsius (0 = Celsius, 1 = Fahrenheit) byte unitOfTemp = 0; // Temperature unit to be used. Default: Celsius (0 = Celsius, 1 = Fahrenheit)
bool shtInitDone = false; // Remembers if SHT sensor has been initialised bool shtInitDone = false; // Remembers if SHT sensor has been initialised
@ -37,7 +37,7 @@ class ShtUsermod : public Usermod
void initShtTempHumiditySensor(); void initShtTempHumiditySensor();
void cleanupShtTempHumiditySensor(); void cleanupShtTempHumiditySensor();
void cleanup(); void cleanup();
bool isShtReady(); inline bool isShtReady() { return shtInitDone; } // Checks if the SHT sensor has been initialised.
void publishTemperatureAndHumidityViaMqtt(); void publishTemperatureAndHumidityViaMqtt();
void publishHomeAssistantAutodiscovery(); void publishHomeAssistantAutodiscovery();
@ -113,8 +113,11 @@ void ShtUsermod::initShtTempHumiditySensor()
*/ */
void ShtUsermod::cleanupShtTempHumiditySensor() void ShtUsermod::cleanupShtTempHumiditySensor()
{ {
if (isShtReady()) shtTempHumidSensor->reset(); if (isShtReady()) {
shtTempHumidSensor->reset();
delete shtTempHumidSensor; delete shtTempHumidSensor;
shtTempHumidSensor = nullptr;
}
shtInitDone = false; shtInitDone = false;
} }
@ -139,16 +142,6 @@ void ShtUsermod::cleanup()
enabled = false; enabled = false;
} }
/**
* Checks if the SHT sensor has been initialised.
*
* @return bool
*/
bool ShtUsermod::isShtReady()
{
return shtInitDone;
}
/** /**
* Publish temperature and humidity to WLED device topic. * Publish temperature and humidity to WLED device topic.
* *
@ -463,7 +456,19 @@ void ShtUsermod::addToJsonInfo(JsonObject& root)
jsonHumidity.add(F(" RH")); jsonHumidity.add(F(" RH"));
jsonTemp.add(getTemperature()); jsonTemp.add(getTemperature());
jsonTemp.add(unitOfTemp ? "°F" : "°C"); jsonTemp.add(getUnitString());
// sensor object
JsonObject sensor = root[F("sensor")];
if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
jsonTemp = sensor.createNestedArray(F("temp"));
jsonTemp.add(getTemperature());
jsonTemp.add(getUnitString());
jsonHumidity = sensor.createNestedArray(F("humidity"));
jsonHumidity.add(getHumidity());
jsonHumidity.add(F(" RH"));
} }
/** /**

View File

@ -7388,6 +7388,7 @@ uint16_t mode_2Ddistortionwaves() {
} }
static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@!,Scale;;;2"; static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@!,Scale;;;2";
//Soap //Soap
//@Stepko //@Stepko
//Idea from https://www.youtube.com/watch?v=DiHBgITrZck&ab_channel=StefanPetrick //Idea from https://www.youtube.com/watch?v=DiHBgITrZck&ab_channel=StefanPetrick
@ -7405,8 +7406,10 @@ uint16_t mode_2Dsoap() {
uint32_t *noise32_x = reinterpret_cast<uint32_t*>(SEGENV.data + dataSize); uint32_t *noise32_x = reinterpret_cast<uint32_t*>(SEGENV.data + dataSize);
uint32_t *noise32_y = reinterpret_cast<uint32_t*>(SEGENV.data + dataSize + sizeof(uint32_t)); uint32_t *noise32_y = reinterpret_cast<uint32_t*>(SEGENV.data + dataSize + sizeof(uint32_t));
uint32_t *noise32_z = reinterpret_cast<uint32_t*>(SEGENV.data + dataSize + sizeof(uint32_t)*2); uint32_t *noise32_z = reinterpret_cast<uint32_t*>(SEGENV.data + dataSize + sizeof(uint32_t)*2);
uint32_t scale32_x = 160000U/cols; const uint32_t scale32_x = 160000U/cols;
uint32_t scale32_y = 160000U/rows; const uint32_t scale32_y = 160000U/rows;
const uint32_t mov = MIN(cols,rows)*(SEGMENT.speed+2)/2;
const uint8_t smoothness = MIN(250,SEGMENT.intensity); // limit as >250 produces very little changes
// init // init
if (SEGENV.call == 0) { if (SEGENV.call == 0) {
@ -7414,28 +7417,28 @@ uint16_t mode_2Dsoap() {
*noise32_x = random16(); *noise32_x = random16();
*noise32_y = random16(); *noise32_y = random16();
*noise32_z = random16(); *noise32_z = random16();
for (int i = 0; i < cols; i++) { } else {
int32_t ioffset = scale32_x * (i - cols / 2);
for (int j = 0; j < rows; j++) {
int32_t joffset = scale32_y * (j - rows / 2);
uint8_t data = inoise16(*noise32_x + ioffset, *noise32_y + joffset, *noise32_z) >> 8;
noise3d[XY(i,j)] = scale8(noise3d[XY(i,j)], SEGMENT.intensity) + scale8(data, 255 - SEGMENT.intensity);
SEGMENT.setPixelColorXY(i, j, ColorFromPalette(SEGPALETTE,~noise3d[XY(i,j)]*3));
}
}
}
uint32_t mov = MAX(cols,rows)*(SEGMENT.speed+1)/2;
*noise32_x += mov; *noise32_x += mov;
*noise32_y += mov; *noise32_y += mov;
*noise32_z += mov; *noise32_z += mov;
}
for (int i = 0; i < cols; i++) { for (int i = 0; i < cols; i++) {
int32_t ioffset = scale32_x * (i - cols / 2); int32_t ioffset = scale32_x * (i - cols / 2);
for (int j = 0; j < rows; j++) { for (int j = 0; j < rows; j++) {
int32_t joffset = scale32_y * (j - rows / 2); int32_t joffset = scale32_y * (j - rows / 2);
uint8_t data = inoise16(*noise32_x + ioffset, *noise32_y + joffset, *noise32_z) >> 8; uint8_t data = inoise16(*noise32_x + ioffset, *noise32_y + joffset, *noise32_z) >> 8;
noise3d[XY(i,j)] = scale8(noise3d[XY(i,j)], SEGMENT.intensity) + scale8(data, 256 - SEGMENT.intensity); noise3d[XY(i,j)] = scale8(noise3d[XY(i,j)], smoothness) + scale8(data, 255 - smoothness);
}
}
// init also if dimensions changed
if (SEGENV.call == 0 || SEGMENT.aux0 != cols || SEGMENT.aux1 != rows) {
SEGMENT.aux0 = cols;
SEGMENT.aux1 = rows;
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
SEGMENT.setPixelColorXY(i, j, ColorFromPalette(SEGPALETTE,~noise3d[XY(i,j)]*3));
}
} }
} }
@ -7497,6 +7500,85 @@ uint16_t mode_2Dsoap() {
} }
static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness;;!;2"; static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness;;!;2";
//Idea from https://www.youtube.com/watch?v=HsA-6KIbgto&ab_channel=GreatScott%21
//Octopus (https://editor.soulmatelights.com/gallery/671-octopus)
//Stepko and Sutaburosu
// adapted for WLED by @blazoncek
uint16_t mode_2Doctopus() {
if (!strip.isMatrix) return mode_static(); // not a 2D set-up
const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight();
const uint8_t mapp = 180 / MAX(cols,rows);
typedef struct {
uint8_t angle;
uint8_t radius;
} map_t;
const size_t dataSize = SEGMENT.width() * SEGMENT.height() * sizeof(map_t); // prevent reallocation if mirrored or grouped
if (!SEGENV.allocateData(dataSize + 2)) return mode_static(); //allocation failed
map_t *rMap = reinterpret_cast<map_t*>(SEGENV.data);
uint8_t *offsX = reinterpret_cast<uint8_t*>(SEGENV.data + dataSize);
uint8_t *offsY = reinterpret_cast<uint8_t*>(SEGENV.data + dataSize + 1);
// re-init if SEGMENT dimensions or offset changed
if (SEGENV.call == 0 || SEGENV.aux0 != cols || SEGENV.aux1 != rows || SEGMENT.custom1 != *offsX || SEGMENT.custom2 != *offsY) {
SEGENV.step = 0; // t
SEGENV.aux0 = cols;
SEGENV.aux1 = rows;
*offsX = SEGMENT.custom1;
*offsY = SEGMENT.custom2;
const uint8_t C_X = cols / 2 + (SEGMENT.custom1 - 128)*cols/255;
const uint8_t C_Y = rows / 2 + (SEGMENT.custom2 - 128)*rows/255;
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
rMap[XY(x, y)].angle = 40.7436f * atan2f(y - C_Y, x - C_X); // avoid 128*atan2()/PI
rMap[XY(x, y)].radius = hypotf(x - C_X, y - C_Y) * mapp; //thanks Sutaburosu
}
}
}
SEGENV.step += SEGMENT.speed / 32 + 1; // 1-4 range
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
byte angle = rMap[XY(x,y)].angle;
byte radius = rMap[XY(x,y)].radius;
//CRGB c = CHSV(SEGENV.step / 2 - radius, 255, sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step) + radius - SEGENV.step * 2 + angle * (SEGMENT.custom3/3+1)));
uint16_t intensity = sin8(sin8((angle * 4 - radius) / 4 + SEGENV.step/2) + radius - SEGENV.step + angle * (SEGMENT.custom3/4+1));
intensity = map(intensity*intensity, 0, 65535, 0, 255); // add a bit of non-linearity for cleaner display
CRGB c = ColorFromPalette(SEGPALETTE, SEGENV.step / 2 - radius, intensity);
SEGMENT.setPixelColorXY(x, y, c);
}
}
return FRAMETIME;
}
static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offset Y,Legs;;!;2;";
//Waving Cell
//@Stepko (https://editor.soulmatelights.com/gallery/1704-wavingcells)
// adapted for WLED by @blazoncek
uint16_t mode_2Dwavingcell() {
if (!strip.isMatrix) return mode_static(); // not a 2D set-up
const uint16_t cols = SEGMENT.virtualWidth();
const uint16_t rows = SEGMENT.virtualHeight();
uint32_t t = millis()/(257-SEGMENT.speed);
uint8_t aX = SEGMENT.custom1/16 + 9;
uint8_t aY = SEGMENT.custom2/16 + 1;
uint8_t aZ = SEGMENT.custom3 + 1;
for (int x = 0; x < cols; x++) for (int y = 0; y <rows; y++)
SEGMENT.setPixelColorXY(x, y, ColorFromPalette(SEGPALETTE, ((sin8((x*aX)+sin8((y+t)*aY))+cos8(y*aZ))+1)+t));
return FRAMETIME;
}
static const char _data_FX_MODE_2DWAVINGCELL[] PROGMEM = "Waving Cell@!,,Amplitude 1,Amplitude 2,Amplitude 3;;!;2";
#endif // WLED_DISABLE_2D #endif // WLED_DISABLE_2D
@ -7731,6 +7813,8 @@ void WS2812FX::setupEffectData() {
addEffect(FX_MODE_2DDNASPIRAL, &mode_2DDNASpiral, _data_FX_MODE_2DDNASPIRAL); addEffect(FX_MODE_2DDNASPIRAL, &mode_2DDNASpiral, _data_FX_MODE_2DDNASPIRAL);
addEffect(FX_MODE_2DBLACKHOLE, &mode_2DBlackHole, _data_FX_MODE_2DBLACKHOLE); addEffect(FX_MODE_2DBLACKHOLE, &mode_2DBlackHole, _data_FX_MODE_2DBLACKHOLE);
addEffect(FX_MODE_2DSOAP, &mode_2Dsoap, _data_FX_MODE_2DSOAP); addEffect(FX_MODE_2DSOAP, &mode_2Dsoap, _data_FX_MODE_2DSOAP);
addEffect(FX_MODE_2DOCTOPUS, &mode_2Doctopus, _data_FX_MODE_2DOCTOPUS);
addEffect(FX_MODE_2DWAVINGCELL, &mode_2Dwavingcell, _data_FX_MODE_2DWAVINGCELL);
addEffect(FX_MODE_2DAKEMI, &mode_2DAkemi, _data_FX_MODE_2DAKEMI); // audio addEffect(FX_MODE_2DAKEMI, &mode_2DAkemi, _data_FX_MODE_2DAKEMI); // audio
#endif // WLED_DISABLE_2D #endif // WLED_DISABLE_2D

View File

@ -256,6 +256,8 @@
#define FX_MODE_2DDRIFTROSE 123 //gap fill #define FX_MODE_2DDRIFTROSE 123 //gap fill
#define FX_MODE_2DDISTORTIONWAVES 124 //gap fill #define FX_MODE_2DDISTORTIONWAVES 124 //gap fill
#define FX_MODE_2DSOAP 125 //gap fill #define FX_MODE_2DSOAP 125 //gap fill
#define FX_MODE_2DOCTOPUS 126 //gap fill
#define FX_MODE_2DWAVINGCELL 127 //gap fill
// WLED-SR effects (SR compatible IDs !!!) // WLED-SR effects (SR compatible IDs !!!)
#define FX_MODE_PIXELS 128 #define FX_MODE_PIXELS 128

View File

@ -623,7 +623,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
uint16_t len = length(); uint16_t len = length();
uint8_t _bri_t = currentBri(on ? opacity : 0); uint8_t _bri_t = currentBri(on ? opacity : 0);
if (!_bri_t && !transitional) return; if (!_bri_t && !transitional && fadeTransition) return; // if _bri_t == 0 && segment is not transitionig && transitions are enabled then save a few CPU cycles
if (_bri_t < 255) { if (_bri_t < 255) {
byte r = scale8(R(col), _bri_t); byte r = scale8(R(col), _bri_t);
byte g = scale8(G(col), _bri_t); byte g = scale8(G(col), _bri_t);

View File

@ -265,7 +265,7 @@
#define BTN_TYPE_ANALOG_INVERTED 8 #define BTN_TYPE_ANALOG_INVERTED 8
//Ethernet board types //Ethernet board types
#define WLED_NUM_ETH_TYPES 10 #define WLED_NUM_ETH_TYPES 11
#define WLED_ETH_NONE 0 #define WLED_ETH_NONE 0
#define WLED_ETH_WT32_ETH01 1 #define WLED_ETH_WT32_ETH01 1
@ -274,7 +274,10 @@
#define WLED_ETH_QUINLED 4 #define WLED_ETH_QUINLED 4
#define WLED_ETH_TWILIGHTLORD 5 #define WLED_ETH_TWILIGHTLORD 5
#define WLED_ETH_ESP32DEUX 6 #define WLED_ETH_ESP32DEUX 6
#define WLED_ETH_ESP32ETHKITVE 7
#define WLED_ETH_QUINLED_OCTA 8
#define WLED_ETH_ABCWLEDV43ETH 9 #define WLED_ETH_ABCWLEDV43ETH 9
#define WLED_ETH_SERG74 10
//Hue error codes //Hue error codes
#define HUE_ERROR_INACTIVE 0 #define HUE_ERROR_INACTIVE 0

View File

@ -192,6 +192,7 @@
<option value="7">KIT-VE</option> <option value="7">KIT-VE</option>
<option value="8">QuinLED-Dig-Octa</option> <option value="8">QuinLED-Dig-Octa</option>
<option value="4">QuinLED-ESP32</option> <option value="4">QuinLED-ESP32</option>
<option value="10">Serg74-ETH32</option>
<option value="5">TwilightLord-ESP32</option> <option value="5">TwilightLord-ESP32</option>
<option value="3">WESP32</option> <option value="3">WESP32</option>
<option value="1">WT32-ETH01</option> <option value="1">WT32-ETH01</option>

View File

@ -27,9 +27,10 @@
// There are no consecutive spaces longer than this in the file, so if more space is required, findSpace() can return false immediately // There are no consecutive spaces longer than this in the file, so if more space is required, findSpace() can return false immediately
// Actual space may be lower // Actual space may be lower
uint16_t knownLargestSpace = UINT16_MAX; constexpr size_t MAX_SPACE = UINT16_MAX * 2U; // smallest supported config has 128Kb flash size
static volatile size_t knownLargestSpace = MAX_SPACE;
File f; static File f; // don't export to other cpp files
//wrapper to find out how long closing takes //wrapper to find out how long closing takes
void closeFile() { void closeFile() {
@ -44,7 +45,7 @@ void closeFile() {
//find() that reads and buffers data from file stream in 256-byte blocks. //find() that reads and buffers data from file stream in 256-byte blocks.
//Significantly faster, f.find(key) can take SECONDS for multi-kB files //Significantly faster, f.find(key) can take SECONDS for multi-kB files
bool bufferedFind(const char *target, bool fromStart = true) { static bool bufferedFind(const char *target, bool fromStart = true) {
#ifdef WLED_DEBUG_FS #ifdef WLED_DEBUG_FS
DEBUGFS_PRINT("Find "); DEBUGFS_PRINT("Find ");
DEBUGFS_PRINTLN(target); DEBUGFS_PRINTLN(target);
@ -59,8 +60,8 @@ bool bufferedFind(const char *target, bool fromStart = true) {
if (fromStart) f.seek(0); if (fromStart) f.seek(0);
while (f.position() < f.size() -1) { while (f.position() < f.size() -1) {
uint16_t bufsize = f.read(buf, FS_BUFSIZE); size_t bufsize = f.read(buf, FS_BUFSIZE); // better to use size_t instead if uint16_t
uint16_t count = 0; size_t count = 0;
while (count < bufsize) { while (count < bufsize) {
if(buf[count] != target[index]) if(buf[count] != target[index])
index = 0; // reset index if any char does not match index = 0; // reset index if any char does not match
@ -80,7 +81,7 @@ bool bufferedFind(const char *target, bool fromStart = true) {
} }
//find empty spots in file stream in 256-byte blocks. //find empty spots in file stream in 256-byte blocks.
bool bufferedFindSpace(uint16_t targetLen, bool fromStart = true) { static bool bufferedFindSpace(size_t targetLen, bool fromStart = true) {
#ifdef WLED_DEBUG_FS #ifdef WLED_DEBUG_FS
DEBUGFS_PRINTF("Find %d spaces\n", targetLen); DEBUGFS_PRINTF("Find %d spaces\n", targetLen);
@ -95,20 +96,20 @@ bool bufferedFindSpace(uint16_t targetLen, bool fromStart = true) {
if (!f || !f.size()) return false; if (!f || !f.size()) return false;
uint16_t index = 0; size_t index = 0; // better to use size_t instead if uint16_t
byte buf[FS_BUFSIZE]; byte buf[FS_BUFSIZE];
if (fromStart) f.seek(0); if (fromStart) f.seek(0);
while (f.position() < f.size() -1) { while (f.position() < f.size() -1) {
uint16_t bufsize = f.read(buf, FS_BUFSIZE); size_t bufsize = f.read(buf, FS_BUFSIZE);
uint16_t count = 0; size_t count = 0;
while (count < bufsize) { while (count < bufsize) {
if(buf[count] == ' ') { if(buf[count] == ' ') {
if(++index >= targetLen) { // return true if space long enough if(++index >= targetLen) { // return true if space long enough
if (fromStart) { if (fromStart) {
f.seek((f.position() - bufsize) + count +1 - targetLen); f.seek((f.position() - bufsize) + count +1 - targetLen);
knownLargestSpace = UINT16_MAX; //there may be larger spaces after, so we don't know knownLargestSpace = MAX_SPACE; //there may be larger spaces after, so we don't know
} }
DEBUGFS_PRINTF("Found at pos %d, took %d ms", f.position(), millis() - s); DEBUGFS_PRINTF("Found at pos %d, took %d ms", f.position(), millis() - s);
return true; return true;
@ -116,7 +117,7 @@ bool bufferedFindSpace(uint16_t targetLen, bool fromStart = true) {
} else { } else {
if (!fromStart) return false; if (!fromStart) return false;
if (index) { if (index) {
if (knownLargestSpace < index || knownLargestSpace == UINT16_MAX) knownLargestSpace = index; if (knownLargestSpace < index || (knownLargestSpace == MAX_SPACE)) knownLargestSpace = index;
index = 0; // reset index if not space index = 0; // reset index if not space
} }
} }
@ -129,7 +130,7 @@ bool bufferedFindSpace(uint16_t targetLen, bool fromStart = true) {
} }
//find the closing bracket corresponding to the opening bracket at the file pos when calling this function //find the closing bracket corresponding to the opening bracket at the file pos when calling this function
bool bufferedFindObjectEnd() { static bool bufferedFindObjectEnd() {
#ifdef WLED_DEBUG_FS #ifdef WLED_DEBUG_FS
DEBUGFS_PRINTLN(F("Find obj end")); DEBUGFS_PRINTLN(F("Find obj end"));
uint32_t s = millis(); uint32_t s = millis();
@ -142,8 +143,8 @@ bool bufferedFindObjectEnd() {
byte buf[FS_BUFSIZE]; byte buf[FS_BUFSIZE];
while (f.position() < f.size() -1) { while (f.position() < f.size() -1) {
uint16_t bufsize = f.read(buf, FS_BUFSIZE); size_t bufsize = f.read(buf, FS_BUFSIZE); // better to use size_t instead of uint16_t
uint16_t count = 0; size_t count = 0;
while (count < bufsize) { while (count < bufsize) {
if (buf[count] == '{') objDepth++; if (buf[count] == '{') objDepth++;
@ -161,13 +162,13 @@ bool bufferedFindObjectEnd() {
} }
//fills n bytes from current file pos with ' ' characters //fills n bytes from current file pos with ' ' characters
void writeSpace(uint16_t l) static void writeSpace(size_t l)
{ {
byte buf[FS_BUFSIZE]; byte buf[FS_BUFSIZE];
memset(buf, ' ', FS_BUFSIZE); memset(buf, ' ', FS_BUFSIZE);
while (l > 0) { while (l > 0) {
uint16_t block = (l>FS_BUFSIZE) ? FS_BUFSIZE : l; size_t block = (l>FS_BUFSIZE) ? FS_BUFSIZE : l;
f.write(buf, block); f.write(buf, block);
l -= block; l -= block;
} }
@ -270,7 +271,7 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content)
s = millis(); s = millis();
#endif #endif
uint32_t pos = 0; size_t pos = 0;
f = WLED_FS.open(file, "r+"); f = WLED_FS.open(file, "r+");
if (!f && !WLED_FS.exists(file)) f = WLED_FS.open(file, "w+"); if (!f && !WLED_FS.exists(file)) f = WLED_FS.open(file, "w+");
if (!f) { if (!f) {
@ -287,7 +288,7 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content)
pos = f.position(); pos = f.position();
//measure out end of old object //measure out end of old object
bufferedFindObjectEnd(); bufferedFindObjectEnd();
uint32_t pos2 = f.position(); size_t pos2 = f.position();
uint32_t oldLen = pos2 - pos; uint32_t oldLen = pos2 - pos;
DEBUGFS_PRINTF("Old obj len %d\n", oldLen); DEBUGFS_PRINTF("Old obj len %d\n", oldLen);
@ -298,7 +299,7 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content)
//3. The new content is larger than the old, but smaller than old + trailing spaces, overwrite with new //3. The new content is larger than the old, but smaller than old + trailing spaces, overwrite with new
//4. The new content is larger than old + trailing spaces, delete old and append //4. The new content is larger than old + trailing spaces, delete old and append
uint32_t contentLen = 0; size_t contentLen = 0;
if (!content->isNull()) contentLen = measureJson(*content); if (!content->isNull()) contentLen = measureJson(*content);
if (contentLen && contentLen <= oldLen) { //replace and fill diff with spaces if (contentLen && contentLen <= oldLen) { //replace and fill diff with spaces
@ -375,7 +376,7 @@ void updateFSInfo() {
//Un-comment any file types you need //Un-comment any file types you need
String getContentType(AsyncWebServerRequest* request, String filename){ static String getContentType(AsyncWebServerRequest* request, String filename){
if(request->hasArg("download")) return "application/octet-stream"; if(request->hasArg("download")) return "application/octet-stream";
else if(filename.endsWith(".htm")) return "text/html"; else if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html"; else if(filename.endsWith(".html")) return "text/html";
@ -394,7 +395,7 @@ String getContentType(AsyncWebServerRequest* request, String filename){
} }
bool handleFileRead(AsyncWebServerRequest* request, String path){ bool handleFileRead(AsyncWebServerRequest* request, String path){
DEBUG_PRINTLN("FileRead: " + path); DEBUG_PRINTLN("WS FileRead: " + path);
if(path.endsWith("/")) path += "index.htm"; if(path.endsWith("/")) path += "index.htm";
if(path.indexOf("sec") > -1) return false; if(path.indexOf("sec") > -1) return false;
String contentType = getContentType(request, path); String contentType = getContentType(request, path);

View File

@ -8,7 +8,7 @@
// Autogenerated from wled00/data/style.css, do not edit!! // Autogenerated from wled00/data/style.css, do not edit!!
const uint16_t PAGE_settingsCss_length = 847; const uint16_t PAGE_settingsCss_length = 847;
const uint8_t PAGE_settingsCss[] PROGMEM = { const uint8_t PAGE_settingsCss[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x55, 0xc1, 0x8e, 0x9b, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xad, 0x55, 0xc1, 0x8e, 0x9b, 0x30,
0x10, 0xfd, 0x15, 0xaa, 0x68, 0xa5, 0xad, 0x14, 0x10, 0x10, 0xc8, 0xa6, 0x46, 0x95, 0xaa, 0xde, 0x10, 0xfd, 0x15, 0xaa, 0x68, 0xa5, 0xad, 0x14, 0x10, 0x10, 0xc8, 0xa6, 0x46, 0x95, 0xaa, 0xde,
0x7b, 0xab, 0xaa, 0x4a, 0xd5, 0x1e, 0x0c, 0x1e, 0x82, 0x15, 0x63, 0x23, 0xdb, 0x74, 0x49, 0x11, 0x7b, 0xab, 0xaa, 0x4a, 0xd5, 0x1e, 0x0c, 0x1e, 0x82, 0x15, 0x63, 0x23, 0xdb, 0x74, 0x49, 0x11,
0xff, 0x5e, 0xdb, 0xc0, 0x42, 0xb2, 0x68, 0x7b, 0xa9, 0xa2, 0x44, 0xc4, 0x63, 0xc6, 0x6f, 0xde, 0xff, 0x5e, 0xdb, 0xc0, 0x42, 0xb2, 0x68, 0x7b, 0xa9, 0xa2, 0x44, 0xc4, 0x63, 0xc6, 0x6f, 0xde,
@ -67,7 +67,7 @@ const uint8_t PAGE_settingsCss[] PROGMEM = {
// Autogenerated from wled00/data/settings.htm, do not edit!! // Autogenerated from wled00/data/settings.htm, do not edit!!
const uint16_t PAGE_settings_length = 992; const uint16_t PAGE_settings_length = 992;
const uint8_t PAGE_settings[] PROGMEM = { const uint8_t PAGE_settings[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x56, 0x6d, 0x6f, 0xdb, 0x36, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xad, 0x56, 0x6d, 0x6f, 0xdb, 0x36,
0x10, 0xfe, 0xee, 0x5f, 0xc1, 0xb0, 0x58, 0x23, 0xa1, 0xb2, 0xec, 0x38, 0xc3, 0xb0, 0xc9, 0x96, 0x10, 0xfe, 0xee, 0x5f, 0xc1, 0xb0, 0x58, 0x23, 0xa1, 0xb2, 0xec, 0x38, 0xc3, 0xb0, 0xc9, 0x96,
0x8b, 0x35, 0x2f, 0x9b, 0x87, 0x04, 0x0d, 0x90, 0xa4, 0xdd, 0x80, 0x7d, 0xa1, 0xc9, 0x93, 0xcc, 0x8b, 0x35, 0x2f, 0x9b, 0x87, 0x04, 0x0d, 0x90, 0xa4, 0xdd, 0x80, 0x7d, 0xa1, 0xc9, 0x93, 0xcc,
0x46, 0x22, 0x05, 0xf2, 0xe4, 0xc4, 0x73, 0xf3, 0xdf, 0x77, 0x94, 0x9d, 0xb7, 0x26, 0x18, 0x86, 0x46, 0x22, 0x05, 0xf2, 0xe4, 0xc4, 0x73, 0xf3, 0xdf, 0x77, 0x94, 0x9d, 0xb7, 0x26, 0x18, 0x86,
@ -133,149 +133,150 @@ const uint8_t PAGE_settings[] PROGMEM = {
// Autogenerated from wled00/data/settings_wifi.htm, do not edit!! // Autogenerated from wled00/data/settings_wifi.htm, do not edit!!
const uint16_t PAGE_settings_wifi_length = 2138; const uint16_t PAGE_settings_wifi_length = 2145;
const uint8_t PAGE_settings_wifi[] PROGMEM = { const uint8_t PAGE_settings_wifi[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x58, 0x7b, 0x6f, 0xdb, 0x38, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xb5, 0x58, 0x6b, 0x73, 0xdb, 0xba,
0x12, 0xff, 0xdf, 0x9f, 0x82, 0xe1, 0x1d, 0x02, 0x09, 0x51, 0xe4, 0x38, 0xde, 0xf6, 0x7a, 0x89, 0x11, 0xfd, 0xae, 0x5f, 0x01, 0xa3, 0x1d, 0x0f, 0x39, 0xa6, 0x29, 0xc9, 0x4a, 0x72, 0x53, 0x5b,
0xe5, 0x5e, 0x1e, 0xde, 0x26, 0x77, 0x69, 0xea, 0x83, 0x83, 0x06, 0x87, 0x5e, 0xb1, 0xab, 0x48, 0xd4, 0xad, 0x1f, 0xba, 0xb1, 0x5b, 0xc7, 0x51, 0x47, 0x9e, 0x78, 0x3a, 0x69, 0xe6, 0x5e, 0x9a,
0x63, 0x9b, 0x8d, 0x44, 0xea, 0x44, 0xca, 0x4e, 0x90, 0xfa, 0xbb, 0xdf, 0x0c, 0x29, 0x3f, 0x13, 0x5c, 0x49, 0x88, 0x49, 0x80, 0x25, 0x40, 0xc9, 0x1e, 0x47, 0xff, 0xbd, 0xbb, 0x00, 0xf5, 0xb4,
0x77, 0x17, 0x45, 0x50, 0xb4, 0x15, 0xc9, 0xe1, 0x3c, 0x7f, 0xf3, 0xa0, 0x3b, 0x3b, 0xe7, 0x9f, 0x9d, 0x76, 0x32, 0xee, 0x64, 0x92, 0x90, 0xc4, 0x62, 0x77, 0x71, 0xf6, 0xec, 0x03, 0xea, 0xee,
0xce, 0x6e, 0xfe, 0xd3, 0xef, 0xb1, 0xb1, 0xc9, 0xb3, 0x6e, 0x87, 0xfe, 0x65, 0x59, 0x2c, 0x47, 0x9c, 0x7d, 0x3a, 0xbd, 0xfe, 0xe7, 0xa0, 0xcf, 0x26, 0x26, 0xcf, 0x7a, 0x5d, 0xfa, 0x97, 0x65,
0x11, 0x07, 0xc9, 0x71, 0x0d, 0x71, 0xda, 0xed, 0xe4, 0x60, 0x62, 0x96, 0x8c, 0xe3, 0x52, 0x83, 0xb1, 0x1c, 0x47, 0x1c, 0x24, 0xc7, 0x77, 0x88, 0xd3, 0x5e, 0x37, 0x07, 0x13, 0xb3, 0x64, 0x12,
0x89, 0x78, 0x65, 0x86, 0xfb, 0xef, 0x78, 0xbd, 0xdb, 0x90, 0x71, 0x0e, 0x11, 0x9f, 0x08, 0x98, 0x97, 0x1a, 0x4c, 0xc4, 0x2b, 0x33, 0xda, 0x7f, 0xcf, 0xeb, 0xaf, 0x0d, 0x19, 0xe7, 0x10, 0xf1,
0x16, 0xaa, 0x34, 0x9c, 0x25, 0x4a, 0x1a, 0x90, 0x48, 0x36, 0x15, 0xa9, 0x19, 0x47, 0x6f, 0x0e, 0xa9, 0x80, 0x59, 0xa1, 0x4a, 0xc3, 0x59, 0xa2, 0xa4, 0x01, 0x89, 0x62, 0x33, 0x91, 0x9a, 0x49,
0x0e, 0x16, 0xa4, 0x1b, 0x47, 0x29, 0x4c, 0x44, 0x02, 0xfb, 0x76, 0x11, 0x08, 0x29, 0x8c, 0x88, 0xf4, 0xb6, 0xd5, 0x5a, 0x8a, 0x6e, 0x2d, 0xa5, 0x30, 0x15, 0x09, 0xec, 0xdb, 0x97, 0x40, 0x48,
0xb3, 0x7d, 0x9d, 0xc4, 0x19, 0x44, 0xad, 0x20, 0x8f, 0x1f, 0x44, 0x5e, 0xe5, 0x8b, 0x75, 0xa5, 0x61, 0x44, 0x9c, 0xed, 0xeb, 0x24, 0xce, 0x20, 0x6a, 0x07, 0x79, 0x7c, 0x2f, 0xf2, 0x2a, 0x5f,
0xa1, 0xb4, 0x8b, 0xf8, 0x0e, 0xd7, 0x52, 0xf1, 0x67, 0x92, 0xbb, 0x1d, 0x23, 0x4c, 0x06, 0xdd, 0xbe, 0x57, 0x1a, 0x4a, 0xfb, 0x12, 0xdf, 0xe2, 0xbb, 0x54, 0xfc, 0x89, 0xe5, 0x5e, 0xd7, 0x08,
0x5b, 0xf1, 0xab, 0x60, 0x03, 0x30, 0x46, 0xc8, 0x91, 0xee, 0x34, 0xdd, 0x66, 0x47, 0x27, 0xa5, 0x93, 0x41, 0xef, 0x46, 0xfc, 0x26, 0xd8, 0x10, 0x8c, 0x11, 0x72, 0xac, 0xbb, 0x4d, 0xf7, 0xb1,
0x28, 0x4c, 0xb7, 0x31, 0x89, 0x4b, 0x96, 0xa9, 0x44, 0x14, 0x41, 0x1a, 0xa5, 0x2a, 0xa9, 0x72, 0xab, 0x93, 0x52, 0x14, 0xa6, 0xd7, 0x98, 0xc6, 0x25, 0xcb, 0x54, 0x22, 0x8a, 0x20, 0x8d, 0x52,
0x54, 0x28, 0xc0, 0x8d, 0x68, 0xa7, 0x15, 0x20, 0x7b, 0x79, 0xa5, 0x54, 0xa1, 0xa3, 0x83, 0xa0, 0x95, 0x54, 0x39, 0x3a, 0x14, 0xe0, 0x87, 0x68, 0xa7, 0x1d, 0xa0, 0x7a, 0x79, 0xa9, 0x54, 0xa1,
0x28, 0x61, 0x80, 0xcb, 0xc1, 0xe0, 0xf2, 0x3c, 0xe2, 0xfc, 0x78, 0x58, 0xc9, 0xc4, 0x08, 0x25, 0xa3, 0x56, 0x50, 0x94, 0x30, 0xc4, 0xd7, 0xe1, 0xf0, 0xe2, 0x2c, 0xe2, 0xfc, 0x68, 0x54, 0xc9,
0xd9, 0xe8, 0x32, 0xf5, 0xc0, 0x7f, 0x2a, 0xc1, 0x54, 0xa5, 0x64, 0x69, 0x38, 0x02, 0xd3, 0xcb, 0xc4, 0x08, 0x25, 0xd9, 0xf8, 0x22, 0xf5, 0xc0, 0x7f, 0x2c, 0xc1, 0x54, 0xa5, 0x64, 0x69, 0x38,
0x80, 0xb8, 0x9c, 0x3e, 0xda, 0xa3, 0xd9, 0x82, 0x34, 0xe9, 0xad, 0x51, 0x26, 0x25, 0xc4, 0x06, 0x06, 0xd3, 0xcf, 0x80, 0xb4, 0x9c, 0x3c, 0xd8, 0xa5, 0xf9, 0x52, 0x34, 0xe9, 0x6f, 0x48, 0x26,
0x6a, 0xe2, 0x35, 0xc2, 0x0b, 0xcf, 0x7f, 0x9a, 0x0a, 0x99, 0xaa, 0x69, 0xa8, 0x0a, 0x90, 0x1e, 0x25, 0xc4, 0x06, 0x6a, 0xe1, 0x0d, 0xc1, 0x73, 0xcf, 0x7f, 0x9c, 0x09, 0x99, 0xaa, 0x59, 0xa8,
0x1f, 0x1b, 0x53, 0xe8, 0xa3, 0x66, 0xf3, 0x5e, 0xaa, 0x70, 0x9a, 0x01, 0x49, 0x69, 0x0e, 0xf1, 0x0a, 0x90, 0x1e, 0x9f, 0x18, 0x53, 0xe8, 0xc3, 0x66, 0xf3, 0x4e, 0xaa, 0x70, 0x96, 0x01, 0x59,
0x76, 0x55, 0x82, 0x6e, 0xea, 0xda, 0xb4, 0xe6, 0x5f, 0xa6, 0x62, 0x28, 0xf6, 0xe7, 0x4b, 0xbe, 0x69, 0x8e, 0x70, 0x77, 0x55, 0x82, 0x6e, 0xea, 0xfa, 0x68, 0xcd, 0x3f, 0xcd, 0xc4, 0x48, 0xec,
0xc2, 0xf0, 0x74, 0x93, 0xe1, 0xe2, 0x12, 0x0f, 0xf8, 0x6f, 0x1a, 0xb2, 0xe1, 0x2a, 0xf5, 0x35, 0x2f, 0x5e, 0xf9, 0x9a, 0xc2, 0x93, 0x6d, 0x85, 0xcb, 0x4d, 0x3c, 0xe0, 0xbf, 0x6b, 0xc8, 0x46,
0x52, 0x63, 0x68, 0xb4, 0x61, 0x10, 0x79, 0xe8, 0x8a, 0xf7, 0x56, 0x3e, 0x8a, 0xe7, 0x7b, 0xd6, 0xeb, 0xd2, 0x57, 0x28, 0x8d, 0xa1, 0xd1, 0x86, 0x41, 0xe4, 0x21, 0x14, 0xbf, 0x5a, 0xfb, 0x68,
0x53, 0x47, 0x9c, 0xfb, 0x7b, 0xbc, 0xf9, 0x4d, 0x2b, 0xd9, 0x94, 0x60, 0x78, 0x60, 0x22, 0xf2, 0x9e, 0xef, 0x59, 0xa4, 0x0e, 0x39, 0xf7, 0xf7, 0x78, 0xf3, 0x9b, 0x56, 0xb2, 0x29, 0xc1, 0xf0,
0x02, 0x27, 0x77, 0x71, 0xff, 0xd8, 0x84, 0xa9, 0xd0, 0x14, 0x95, 0x34, 0xda, 0x39, 0x08, 0x4c, 0xc0, 0x44, 0x84, 0x02, 0x27, 0xb8, 0xb8, 0x7f, 0x64, 0xc2, 0x54, 0x68, 0x8a, 0x4a, 0x1a, 0xed,
0x28, 0xa4, 0x84, 0xf2, 0xe2, 0xe6, 0xe3, 0x55, 0xc4, 0xc9, 0x83, 0x12, 0xc5, 0x86, 0x61, 0xc8, 0xb4, 0x02, 0x13, 0x0a, 0x29, 0xa1, 0x3c, 0xbf, 0xfe, 0x78, 0x19, 0x71, 0x42, 0x50, 0xa2, 0xd9,
0x83, 0x21, 0x98, 0x64, 0x8c, 0x76, 0x87, 0x66, 0x8c, 0x2a, 0x41, 0xd4, 0x85, 0x90, 0x58, 0x7a, 0x30, 0x0c, 0x79, 0x30, 0x02, 0x93, 0x4c, 0xf0, 0xdc, 0xa1, 0x99, 0xa0, 0x4b, 0x10, 0xf5, 0x20,
0xfe, 0x72, 0xe7, 0xd3, 0xdd, 0x37, 0x48, 0x4c, 0x18, 0x6b, 0x2d, 0x46, 0xd2, 0x7b, 0x9a, 0x05, 0x24, 0x95, 0x9e, 0xbf, 0xfa, 0xf2, 0xe9, 0xf6, 0x1b, 0x24, 0x26, 0x8c, 0xb5, 0x16, 0x63, 0xe9,
0x4f, 0x28, 0x6f, 0xaa, 0xca, 0x7b, 0x7d, 0xf4, 0xe5, 0xeb, 0x2c, 0xc0, 0xbb, 0xf3, 0x75, 0xa8, 0x3d, 0xce, 0x83, 0x47, 0xb4, 0x37, 0x53, 0xe5, 0x9d, 0x3e, 0xfc, 0xf2, 0x75, 0x1e, 0xe0, 0xde,
0x31, 0xe4, 0x9e, 0x07, 0x81, 0xf1, 0xa3, 0xae, 0x09, 0x4b, 0xbc, 0xb1, 0x0f, 0xf6, 0x3f, 0x3f, 0xc5, 0x7b, 0xa8, 0x31, 0xe4, 0x9e, 0x07, 0x81, 0xf1, 0xa3, 0x9e, 0x09, 0x4b, 0xdc, 0xb1, 0x0f,
0x2c, 0x21, 0xad, 0x12, 0x98, 0x1f, 0x7a, 0x80, 0xb4, 0x39, 0x38, 0x81, 0x78, 0x9e, 0x46, 0x51, 0xf6, 0x3f, 0x3f, 0x2c, 0x21, 0xad, 0x12, 0x58, 0x2c, 0x7a, 0x80, 0xb2, 0x39, 0x38, 0x83, 0xb8,
0x64, 0xec, 0x87, 0xff, 0xfd, 0x3b, 0x84, 0x45, 0xa5, 0xc7, 0x9e, 0xf1, 0x91, 0x77, 0xf0, 0xe5, 0x9e, 0x46, 0x51, 0x64, 0xec, 0x83, 0xff, 0xfd, 0x3b, 0x84, 0x45, 0xa5, 0x27, 0x9e, 0xf1, 0x51,
0xeb, 0x8a, 0x2a, 0x4f, 0x62, 0xe8, 0x1d, 0x20, 0x29, 0x84, 0x19, 0xc8, 0x91, 0x19, 0xef, 0xee, 0x77, 0xf0, 0xe5, 0xeb, 0x9a, 0x2b, 0x8f, 0x62, 0xe4, 0xb5, 0x50, 0x14, 0xc2, 0x0c, 0xe4, 0xd8,
0x2e, 0xd0, 0xd1, 0x69, 0x1d, 0xf8, 0x75, 0x54, 0x17, 0x7b, 0x7b, 0x7b, 0xc1, 0x44, 0x89, 0x94, 0x4c, 0x76, 0x77, 0x97, 0xec, 0xe8, 0xb6, 0x5b, 0x7e, 0x1d, 0xd5, 0xe5, 0xb7, 0xbd, 0xbd, 0x60,
0xa1, 0x9f, 0x6f, 0x44, 0x0e, 0xaa, 0x32, 0xde, 0x75, 0xd0, 0x82, 0xb6, 0x7f, 0xbc, 0x02, 0xaa, 0xaa, 0x44, 0xca, 0x10, 0xe7, 0x6b, 0x91, 0x83, 0xaa, 0x8c, 0x77, 0x15, 0xb4, 0xa1, 0xe3, 0x1f,
0xe3, 0x0c, 0x0c, 0x93, 0xce, 0x79, 0x67, 0x03, 0x74, 0x1d, 0xca, 0x90, 0xfe, 0x13, 0xed, 0x9a, 0xad, 0x91, 0xea, 0x28, 0x03, 0xc3, 0xa4, 0x03, 0xef, 0x74, 0x88, 0xd0, 0xa1, 0x0d, 0xe9, 0x3f,
0x08, 0xd1, 0xc2, 0x31, 0x32, 0x68, 0xbf, 0xf5, 0x29, 0x32, 0x3a, 0x31, 0xa6, 0x14, 0x77, 0x95, 0xd2, 0x57, 0x13, 0x21, 0x5b, 0x38, 0x46, 0x06, 0xcf, 0x6f, 0x31, 0x45, 0x45, 0xc7, 0xc6, 0x94,
0x01, 0x8f, 0x8b, 0x14, 0x03, 0x47, 0x57, 0x82, 0xcd, 0x13, 0x4a, 0x82, 0x6d, 0x67, 0x4a, 0x62, 0xe2, 0xb6, 0x32, 0xe0, 0x71, 0x91, 0x62, 0xe0, 0x68, 0x4b, 0xb0, 0xbd, 0x42, 0x49, 0xf0, 0xd2,
0xce, 0xca, 0x11, 0x9d, 0xdf, 0x78, 0x3e, 0x12, 0xac, 0x82, 0x5a, 0x86, 0x93, 0x38, 0xab, 0xe0, 0x9a, 0x92, 0x98, 0xb3, 0x72, 0x4c, 0xeb, 0xd7, 0x9e, 0x8f, 0x02, 0xeb, 0xa4, 0x96, 0xe1, 0x34,
0x78, 0xa8, 0x4a, 0x8f, 0x34, 0x00, 0xd4, 0x0f, 0x3a, 0x26, 0x4c, 0xc6, 0x22, 0x4b, 0x4b, 0x90, 0xce, 0x2a, 0x38, 0x1a, 0xa9, 0xd2, 0x23, 0x0f, 0x00, 0xfd, 0x83, 0xae, 0x09, 0x93, 0x89, 0xc8,
0xb5, 0xdd, 0xc7, 0xb0, 0xb7, 0xe7, 0xa3, 0x83, 0x21, 0x57, 0x13, 0x38, 0xa3, 0x33, 0x6f, 0x49, 0xd2, 0x12, 0x64, 0x7d, 0xee, 0x23, 0xd8, 0xdb, 0xf3, 0x11, 0x60, 0xc8, 0xd5, 0x14, 0x4e, 0x69,
0xf3, 0x05, 0xbe, 0xfa, 0x0b, 0x06, 0x0a, 0x19, 0xa8, 0xce, 0xdc, 0x5f, 0xc7, 0x0a, 0xef, 0xd5, 0xcd, 0x5b, 0xc9, 0x7c, 0x81, 0xaf, 0xfe, 0x52, 0x81, 0x42, 0x05, 0xaa, 0xbb, 0xc0, 0xeb, 0x48,
0xb0, 0x12, 0xd6, 0x38, 0x55, 0x10, 0xda, 0xc8, 0xea, 0x0d, 0x35, 0xad, 0x1e, 0x3c, 0x80, 0x2f, 0xe1, 0xbe, 0x9a, 0x56, 0xc2, 0x1e, 0x4e, 0x15, 0xc4, 0x36, 0x3a, 0xf5, 0x96, 0x9b, 0xd6, 0x0f,
0xea, 0xab, 0x8b, 0x4b, 0x20, 0x56, 0x40, 0xf4, 0xfb, 0x5f, 0x9f, 0x16, 0x27, 0x33, 0xe6, 0xd5, 0x1e, 0xc0, 0x17, 0xf5, 0xd5, 0xc5, 0x25, 0x10, 0x6b, 0x24, 0xfa, 0xe3, 0xcf, 0x8f, 0xcb, 0x95,
0x2b, 0x8a, 0xf4, 0x8c, 0xa5, 0xa7, 0xb9, 0xff, 0xfb, 0xf2, 0x22, 0x86, 0xab, 0xb6, 0x6a, 0x77, 0x39, 0xf3, 0xea, 0x37, 0x8a, 0xf4, 0x9c, 0xa5, 0x27, 0xb9, 0xff, 0xc7, 0x6a, 0x23, 0x86, 0xab,
0x77, 0x53, 0x88, 0x73, 0x2d, 0x90, 0x1f, 0x17, 0x9f, 0xe4, 0xb1, 0xb8, 0xc0, 0x04, 0x49, 0x9d, 0x3e, 0xd5, 0xee, 0xee, 0xb6, 0x11, 0x07, 0x2d, 0x10, 0x8e, 0xcb, 0x47, 0x42, 0x2c, 0x2e, 0x30,
0x61, 0xc2, 0x9f, 0x39, 0x85, 0xd5, 0xba, 0xc2, 0xea, 0x65, 0x85, 0xf9, 0xce, 0x19, 0x66, 0x5d, 0x41, 0x52, 0x77, 0x30, 0xe1, 0xcf, 0x9d, 0xc3, 0x6a, 0xd3, 0x61, 0xf5, 0xbc, 0xc3, 0x7c, 0xe7,
0xa0, 0x56, 0x11, 0xff, 0x09, 0xf1, 0x53, 0xb2, 0x1a, 0xa5, 0x16, 0xf6, 0xeb, 0x22, 0x94, 0x1f, 0x14, 0xb3, 0x2e, 0x50, 0xeb, 0x8c, 0xff, 0x84, 0xfc, 0x29, 0x59, 0xcd, 0x52, 0x4b, 0xfb, 0x4d,
0x48, 0x74, 0x66, 0x91, 0xc5, 0x09, 0xdc, 0x0a, 0x43, 0xd0, 0x9b, 0xad, 0x26, 0x50, 0xeb, 0x79, 0x13, 0xca, 0x0f, 0x24, 0x82, 0x59, 0x64, 0x71, 0x02, 0x37, 0xc2, 0x10, 0xf5, 0xe6, 0xeb, 0x09,
0x02, 0xf1, 0xd9, 0x4a, 0xae, 0x62, 0x1c, 0x9f, 0x5c, 0xb4, 0xd6, 0x50, 0xb4, 0x03, 0xdf, 0xbf, 0xd4, 0x7e, 0x9a, 0x40, 0x7c, 0xbe, 0x96, 0xab, 0x18, 0xc7, 0x47, 0x17, 0xad, 0x0d, 0x16, 0xed,
0x5b, 0x75, 0x76, 0x10, 0xb0, 0x56, 0xbd, 0x1a, 0xa1, 0xc7, 0x4b, 0x70, 0x09, 0x59, 0x54, 0x0e, 0xc0, 0xf7, 0xef, 0xd6, 0x9d, 0x1d, 0x24, 0xac, 0x75, 0xaf, 0x66, 0xe8, 0xd1, 0x8a, 0x5c, 0x42,
0x5b, 0xe6, 0xb1, 0xc0, 0xc2, 0x69, 0xe0, 0x81, 0x72, 0x39, 0x44, 0xbf, 0x11, 0x1f, 0xfc, 0x72, 0x16, 0x95, 0xe3, 0x96, 0x79, 0x28, 0xb0, 0x70, 0x1a, 0xb8, 0xa7, 0x5c, 0x0e, 0x11, 0x37, 0xd2,
0x05, 0xd5, 0x7d, 0xaf, 0x5b, 0x8c, 0xd5, 0xd8, 0x85, 0x95, 0x07, 0xed, 0x43, 0x72, 0x9b, 0x95, 0x83, 0x4f, 0xae, 0xa0, 0xba, 0xe7, 0xcd, 0x13, 0x63, 0x35, 0x76, 0x61, 0xe5, 0x41, 0xe7, 0x80,
0x11, 0xad, 0xe0, 0x29, 0x80, 0x4d, 0xb3, 0x16, 0x3a, 0x67, 0x2a, 0x4e, 0xff, 0x39, 0xa0, 0x74, 0x60, 0xb3, 0x36, 0xa2, 0x35, 0x3e, 0x05, 0xb0, 0x7d, 0xac, 0xa5, 0xcf, 0x99, 0x8a, 0xd3, 0xbf,
0xc4, 0x02, 0xe1, 0xd4, 0x97, 0x0e, 0xee, 0xb6, 0x26, 0xa3, 0x4a, 0x72, 0x33, 0x58, 0x65, 0xc2, 0x0d, 0x29, 0x1d, 0xb1, 0x40, 0x38, 0xf7, 0xa5, 0xa3, 0xbb, 0xad, 0xc9, 0xe8, 0x92, 0xdc, 0x0e,
0x29, 0x23, 0x37, 0xf7, 0x49, 0x71, 0xf4, 0x3b, 0x69, 0xde, 0xfc, 0x16, 0x4f, 0xe2, 0x39, 0x83, 0x56, 0x99, 0x70, 0xca, 0xc8, 0xed, 0xef, 0xe4, 0x38, 0xe2, 0x4e, 0x9e, 0x37, 0xbf, 0xc5, 0xd3,
0x67, 0x84, 0xb1, 0x7e, 0x94, 0xc8, 0x02, 0xf3, 0x3a, 0x0d, 0xef, 0x54, 0xfa, 0xb8, 0x16, 0x03, 0x78, 0xa1, 0xe0, 0x89, 0x60, 0xac, 0x1f, 0x24, 0xaa, 0xc0, 0xbc, 0x4e, 0xc3, 0x5b, 0x95, 0x3e,
0x49, 0xf4, 0x71, 0x9a, 0xf6, 0x26, 0x58, 0x88, 0xaf, 0x84, 0xc6, 0x9e, 0x04, 0xa5, 0xc7, 0x49, 0x6c, 0xc4, 0x40, 0x92, 0x7c, 0x9c, 0xa6, 0xfd, 0x29, 0x16, 0xe2, 0x4b, 0xa1, 0xb1, 0x27, 0x41,
0x4d, 0x1e, 0x78, 0x58, 0x32, 0x9e, 0x3e, 0x80, 0xf9, 0xec, 0xf9, 0xb3, 0x97, 0xe9, 0xa0, 0x2c, 0xe9, 0x71, 0x72, 0x93, 0x07, 0x1e, 0x96, 0x8c, 0xc7, 0x0f, 0x60, 0x3e, 0x7b, 0xfe, 0xfc, 0x79,
0x55, 0x89, 0xea, 0x21, 0x1d, 0xa1, 0x45, 0x65, 0x08, 0x79, 0x35, 0xf2, 0x78, 0x8f, 0xf6, 0x59, 0x39, 0x28, 0x4b, 0x55, 0xa2, 0x7b, 0x28, 0x47, 0x6c, 0x51, 0x19, 0x52, 0x5e, 0x8d, 0x3d, 0xde,
0x6d, 0x2f, 0x16, 0x3d, 0x36, 0x14, 0x19, 0x58, 0x33, 0xb0, 0x83, 0x61, 0xb1, 0xe2, 0x57, 0xf5, 0xa7, 0xef, 0xac, 0x3e, 0x2f, 0x16, 0x3d, 0x36, 0x12, 0x19, 0xd8, 0x63, 0x60, 0x07, 0xc3, 0x62,
0xbe, 0x1a, 0x52, 0x93, 0x1c, 0x8a, 0x51, 0x55, 0xc6, 0xd6, 0x41, 0xce, 0x0c, 0x36, 0x8c, 0x05, 0xc5, 0x2f, 0xeb, 0xef, 0x6a, 0x44, 0x4d, 0x72, 0x24, 0xc6, 0x55, 0x19, 0x5b, 0x80, 0xdc, 0x31,
0xd5, 0xfa, 0xff, 0xca, 0x4b, 0x99, 0xa8, 0xbc, 0x40, 0x3f, 0x01, 0x2b, 0xe2, 0x11, 0xb0, 0x34, 0xd8, 0x28, 0x16, 0x54, 0xeb, 0xff, 0x25, 0x2f, 0x64, 0xa2, 0xf2, 0x02, 0x71, 0x02, 0x56, 0xc4,
0x36, 0xf1, 0x0e, 0x56, 0xec, 0x15, 0x9f, 0x0e, 0x10, 0x07, 0x9c, 0x04, 0x1c, 0xf1, 0x28, 0xaa, 0x63, 0x60, 0x69, 0x6c, 0xe2, 0x1d, 0xac, 0xd8, 0x6b, 0x98, 0x0e, 0x91, 0x07, 0x9c, 0x0c, 0x1c,
0x4b, 0x3d, 0x16, 0x6b, 0xcb, 0x2f, 0x2c, 0x4a, 0x65, 0x54, 0xa2, 0xb2, 0xdd, 0x5d, 0xcf, 0x76, 0xf2, 0x28, 0xaa, 0x4b, 0x3d, 0x16, 0x6b, 0xab, 0x2f, 0x2c, 0x4a, 0x65, 0x54, 0xa2, 0xb2, 0xdd,
0xb6, 0x83, 0xc0, 0xb3, 0x85, 0x3c, 0x22, 0x8a, 0x6c, 0x60, 0x54, 0x89, 0x5c, 0xa9, 0x73, 0x5d, 0x5d, 0xcf, 0x76, 0xb6, 0x56, 0xe0, 0xd9, 0x42, 0x1e, 0x91, 0x44, 0x36, 0x34, 0xaa, 0x44, 0xad,
0x1a, 0xc8, 0xc9, 0xf0, 0xe4, 0xb2, 0xe0, 0x3e, 0x96, 0xc3, 0x9a, 0x0c, 0xef, 0xe7, 0x05, 0x2a, 0xd4, 0xb9, 0x2e, 0x0c, 0xe4, 0x74, 0xf0, 0xe4, 0xa2, 0xe0, 0x3e, 0x96, 0xc3, 0x5a, 0x0c, 0xf7,
0xfc, 0x2b, 0xf2, 0x67, 0x1f, 0x55, 0x0a, 0x21, 0xeb, 0x67, 0x10, 0x6b, 0x60, 0xe8, 0x08, 0x84, 0xe7, 0x05, 0x3a, 0xfc, 0x1b, 0xea, 0x67, 0x1f, 0x55, 0x0a, 0x21, 0x1b, 0x64, 0x10, 0x6b, 0x60,
0xf7, 0xed, 0x55, 0xef, 0x9c, 0x5d, 0xf6, 0x51, 0xa5, 0x60, 0x8d, 0xa3, 0x5e, 0xe7, 0x18, 0x58, 0x08, 0x04, 0xd2, 0xfb, 0xe6, 0xb2, 0x7f, 0xc6, 0x2e, 0x06, 0xe8, 0x52, 0xb0, 0xa1, 0x51, 0x6f,
0x6e, 0xbe, 0x4f, 0x54, 0x16, 0x01, 0x3f, 0x68, 0x2e, 0x8b, 0xa6, 0xa6, 0xb1, 0x29, 0xbc, 0x2f, 0x6a, 0x0c, 0xac, 0x36, 0xdf, 0x27, 0x29, 0xcb, 0x80, 0x1f, 0x34, 0x97, 0x65, 0x53, 0xd3, 0xd8,
0xa2, 0x16, 0x0f, 0x76, 0x5a, 0xfe, 0xac, 0xd1, 0x69, 0xd6, 0x8d, 0xbb, 0xa3, 0xcd, 0x23, 0xf6, 0x14, 0x7e, 0x2d, 0xa2, 0x36, 0x0f, 0x76, 0xda, 0xfe, 0xbc, 0xd1, 0x6d, 0xd6, 0x8d, 0xbb, 0xab,
0xf1, 0x7f, 0x88, 0x9c, 0x9a, 0x3d, 0xab, 0xca, 0x0c, 0x61, 0x42, 0x5b, 0x61, 0xa2, 0x31, 0x0b, 0xcd, 0x03, 0xf6, 0xf1, 0xbf, 0x8a, 0x9c, 0x9a, 0x3d, 0xab, 0xca, 0x0c, 0x69, 0x42, 0x9f, 0xc2,
0x8f, 0x91, 0xd0, 0x12, 0x74, 0x9a, 0x6e, 0x64, 0xa1, 0xa8, 0x63, 0x30, 0x48, 0x32, 0xa6, 0x11, 0x44, 0x63, 0x16, 0x1e, 0xa1, 0xa0, 0x15, 0xe8, 0x36, 0xdd, 0xc8, 0x42, 0x51, 0xc7, 0x60, 0x90,
0x56, 0xbf, 0x6e, 0x07, 0x0b, 0x55, 0xde, 0x60, 0x04, 0x77, 0xfa, 0xfa, 0x4d, 0x73, 0xe6, 0x00, 0x65, 0x4c, 0x23, 0xac, 0x7e, 0xbd, 0x2e, 0x16, 0xaa, 0xbc, 0xc1, 0x88, 0xee, 0xf4, 0xf4, 0xbb,
0x3f, 0x18, 0x72, 0x86, 0x03, 0xca, 0x58, 0xe1, 0x49, 0xa1, 0x34, 0x4d, 0x12, 0xa9, 0x98, 0xb0, 0xe6, 0xcc, 0x11, 0x7e, 0x38, 0xe2, 0x0c, 0x07, 0x94, 0x89, 0xc2, 0x95, 0x42, 0x69, 0x9a, 0x24,
0x24, 0xc3, 0x3e, 0x84, 0x69, 0xa2, 0xd0, 0x1d, 0xd3, 0xf5, 0xbd, 0x31, 0x64, 0xc5, 0x29, 0xef, 0x52, 0x31, 0x65, 0x49, 0x86, 0x7d, 0x08, 0xd3, 0x44, 0x21, 0x1c, 0xb3, 0xcd, 0x6f, 0x13, 0xc8,
0x36, 0x3a, 0x88, 0x36, 0x83, 0xd1, 0x70, 0x09, 0xe5, 0x16, 0x1c, 0xa5, 0x26, 0x99, 0x48, 0xee, 0x8a, 0x13, 0xde, 0x6b, 0x74, 0x91, 0x6d, 0x06, 0xa3, 0xe1, 0x12, 0xca, 0xbd, 0x70, 0xb4, 0x9a,
0x23, 0x7e, 0x41, 0x62, 0xdf, 0x77, 0x9a, 0xee, 0x00, 0x55, 0x43, 0x16, 0xdd, 0x97, 0xef, 0x34, 0x64, 0x22, 0xb9, 0x8b, 0xf8, 0x39, 0x99, 0xfd, 0xb5, 0xdb, 0x74, 0x0b, 0xe8, 0x1a, 0xaa, 0xe8,
0x16, 0x97, 0x4e, 0xe9, 0xd2, 0x69, 0x9c, 0xdc, 0x2f, 0xef, 0xad, 0xdd, 0xd0, 0xd5, 0x5d, 0x2e, 0x3d, 0xbf, 0xa7, 0xb1, 0xdc, 0x74, 0x42, 0x9b, 0x4e, 0xe2, 0xe4, 0x6e, 0xb5, 0x6f, 0x63, 0x87,
0x50, 0xc7, 0x41, 0x3c, 0x01, 0xb6, 0xcb, 0xce, 0x14, 0x56, 0x8b, 0xc4, 0x2c, 0x89, 0xc7, 0x25, 0xae, 0x6e, 0x73, 0x81, 0x3e, 0x0e, 0xe3, 0x29, 0xb0, 0x5d, 0x76, 0xaa, 0xb0, 0x5a, 0x24, 0x66,
0xea, 0xe5, 0x24, 0x8d, 0x0f, 0xdd, 0x30, 0x84, 0xce, 0xad, 0x0a, 0x74, 0xcc, 0x21, 0x6e, 0xb5, 0x25, 0x3c, 0x29, 0xd1, 0x2f, 0x67, 0x69, 0x72, 0xe0, 0x86, 0x21, 0x04, 0xb7, 0x2a, 0x10, 0x98,
0xbb, 0xf5, 0x0d, 0x66, 0x14, 0x83, 0x07, 0x44, 0x35, 0x41, 0xb2, 0x2e, 0x58, 0x48, 0xd3, 0x5e, 0x03, 0xfc, 0xd4, 0xe9, 0xd5, 0x3b, 0x98, 0x51, 0x0c, 0xee, 0x91, 0xd5, 0x44, 0xc9, 0xba, 0x60,
0x88, 0x6b, 0xac, 0x6b, 0x48, 0x7e, 0xb3, 0x1d, 0x7f, 0x69, 0xdf, 0x35, 0xa9, 0x4a, 0x05, 0x60, 0xa1, 0x4c, 0x67, 0x69, 0xae, 0xb1, 0xe9, 0x21, 0xe1, 0x66, 0x3b, 0xfe, 0xea, 0x7c, 0x57, 0xe4,
0x45, 0x55, 0x94, 0x7e, 0xed, 0x98, 0x59, 0xef, 0x32, 0xcf, 0x16, 0x07, 0x06, 0x08, 0xa8, 0x47, 0x2a, 0x15, 0x80, 0x35, 0x57, 0xd1, 0xfa, 0x95, 0x53, 0x66, 0xd1, 0x65, 0x9e, 0x2d, 0x0e, 0x0c,
0x12, 0x29, 0x95, 0x21, 0xf4, 0x93, 0x06, 0xfe, 0x11, 0x91, 0x77, 0x6c, 0x5d, 0x62, 0x2b, 0x35, 0x90, 0x50, 0x0f, 0x64, 0x52, 0x2a, 0x43, 0xec, 0x27, 0x0f, 0xfc, 0x43, 0x12, 0xef, 0xda, 0xba,
0x89, 0xd5, 0x15, 0x69, 0x3e, 0xe1, 0xd1, 0xe7, 0xa2, 0x00, 0x45, 0xbc, 0x7d, 0xc8, 0xad, 0x9c, 0xc4, 0xd6, 0x6a, 0x12, 0xab, 0x2b, 0xd2, 0x62, 0xc2, 0xa3, 0xc7, 0x65, 0x01, 0x8a, 0x78, 0xe7,
0xb9, 0x98, 0x02, 0x43, 0x82, 0x1f, 0xe9, 0x73, 0x6e, 0xf3, 0x93, 0x25, 0xa7, 0xfe, 0x1a, 0xa7, 0x80, 0x5b, 0x3b, 0x0b, 0x33, 0x05, 0x86, 0x04, 0x1f, 0xd2, 0xa7, 0xda, 0x16, 0x2b, 0x2b, 0x4d,
0xb7, 0x6d, 0xc7, 0x69, 0x60, 0x30, 0x6f, 0x12, 0x44, 0x34, 0xc3, 0x46, 0x46, 0x6e, 0x8d, 0x0d, 0x83, 0x0d, 0x4d, 0xef, 0x3a, 0x4e, 0xd3, 0xd0, 0x60, 0xde, 0x24, 0xc8, 0x68, 0x86, 0x8d, 0x8c,
0x3b, 0x08, 0xed, 0x1f, 0x86, 0x50, 0x61, 0xe7, 0x17, 0x67, 0xfd, 0x35, 0x65, 0x6b, 0x76, 0x97, 0x60, 0x8d, 0x0d, 0x6b, 0x85, 0xf6, 0x0f, 0x43, 0xaa, 0xb0, 0xb3, 0xf3, 0xd3, 0xc1, 0x86, 0xb3,
0x07, 0xbc, 0x96, 0x24, 0xab, 0xfc, 0x0e, 0x4a, 0x3e, 0xc7, 0x07, 0x42, 0x2b, 0x17, 0x32, 0xe2, 0xb5, 0xba, 0x8b, 0x16, 0xaf, 0x2d, 0xc9, 0x2a, 0xbf, 0x85, 0x92, 0x2f, 0xf8, 0x81, 0xd4, 0xca,
0x07, 0x56, 0x5c, 0xc4, 0x0f, 0xdf, 0xbc, 0xe1, 0xac, 0x84, 0xff, 0x55, 0x02, 0x67, 0x93, 0x2e, 0x85, 0x8c, 0x78, 0xcb, 0x9a, 0x8b, 0xf8, 0xc1, 0xdb, 0xb7, 0x9c, 0x95, 0xf0, 0xef, 0x4a, 0xe0,
0x0b, 0xd9, 0x06, 0x9f, 0xd6, 0x2b, 0xf1, 0x39, 0x7c, 0x25, 0x3e, 0xed, 0x9f, 0xe2, 0xb3, 0xe2, 0x6c, 0xd2, 0x63, 0x21, 0xdb, 0xd2, 0xd3, 0x7e, 0x25, 0x3d, 0x07, 0xaf, 0xa4, 0xa7, 0xf3, 0x53,
0xca, 0x11, 0x4e, 0xba, 0xd3, 0xf8, 0xf1, 0xa8, 0xb1, 0xe2, 0x34, 0xc7, 0xfb, 0xc3, 0x4f, 0xfb, 0x7a, 0xd6, 0xa0, 0x1c, 0xe3, 0xa4, 0x3b, 0x8b, 0x1f, 0x0e, 0x1b, 0x6b, 0xa0, 0x39, 0xdd, 0x1f,
0xac, 0xb1, 0xce, 0xe7, 0x95, 0x7c, 0xf6, 0xe1, 0x95, 0x7c, 0xf6, 0xe1, 0xe7, 0x7d, 0xd6, 0xa8, 0x7e, 0x1a, 0xb3, 0xc6, 0xa6, 0x9e, 0x57, 0xc2, 0xec, 0xc3, 0x2b, 0x61, 0xf6, 0xe1, 0xe7, 0x31,
0x9d, 0x86, 0x99, 0x8d, 0x79, 0x88, 0x54, 0xfa, 0xfe, 0xe8, 0x99, 0xdf, 0x06, 0x7f, 0xc2, 0x6f, 0x6b, 0xd4, 0xa0, 0x61, 0x66, 0x63, 0x1e, 0xa2, 0x94, 0xbe, 0x3b, 0x7c, 0x82, 0xdb, 0xf0, 0x7f,
0x8d, 0x1f, 0x2a, 0x5a, 0xf3, 0x69, 0xbd, 0x12, 0x9f, 0xc3, 0x57, 0xe2, 0xd3, 0xfe, 0x39, 0x3e, 0xc0, 0xad, 0xf1, 0x43, 0x47, 0x6b, 0x3d, 0xed, 0x57, 0xd2, 0x73, 0xf0, 0x4a, 0x7a, 0x3a, 0x3f,
0xe4, 0xa0, 0xfc, 0xfc, 0x7a, 0xc0, 0xb0, 0x41, 0xe3, 0xab, 0x48, 0xcf, 0x53, 0xd7, 0x15, 0x1a, 0xa7, 0x87, 0x00, 0xca, 0xcf, 0xae, 0x86, 0x0c, 0x1b, 0x34, 0xde, 0x8a, 0xf4, 0x22, 0x75, 0x5d,
0xca, 0x5a, 0xa9, 0x18, 0x11, 0xb8, 0xc4, 0xad, 0x9b, 0x4e, 0x2d, 0xbb, 0xb1, 0x56, 0x6e, 0xea, 0xa1, 0xa1, 0xac, 0x95, 0x8a, 0x91, 0x80, 0x4b, 0xdc, 0xba, 0xe9, 0xd4, 0xb6, 0x1b, 0x1b, 0xe5,
0xda, 0xf0, 0xf1, 0x59, 0x95, 0x61, 0xb6, 0xa5, 0x66, 0x74, 0xff, 0x2c, 0x13, 0xd8, 0xfb, 0xb0, 0xa6, 0xae, 0x0d, 0x1f, 0x9f, 0x54, 0x19, 0x66, 0x5b, 0x6a, 0x46, 0xfb, 0x4f, 0x33, 0x81, 0xbd,
0x44, 0x1c, 0xb1, 0x8e, 0x2e, 0x62, 0xb9, 0xd0, 0x52, 0x14, 0xd8, 0x07, 0xae, 0x97, 0x45, 0x0d, 0x0f, 0x4b, 0xc4, 0x21, 0xeb, 0xea, 0x22, 0x96, 0x4b, 0x2f, 0x45, 0x81, 0x7d, 0xe0, 0x6a, 0x55,
0x52, 0xec, 0x44, 0x48, 0x60, 0x15, 0xac, 0xcb, 0xad, 0x6d, 0xf5, 0xc0, 0x4e, 0x92, 0x84, 0x14, 0xd4, 0x20, 0xc5, 0x4e, 0x84, 0x02, 0xd6, 0xc1, 0xba, 0xdc, 0xda, 0x56, 0x0f, 0xec, 0x38, 0x49,
0xed, 0x2b, 0x21, 0x8d, 0xad, 0xb4, 0x8d, 0x93, 0x3e, 0xa3, 0xf2, 0xf8, 0xa2, 0xee, 0x27, 0xfd, 0xc8, 0xd1, 0x81, 0x12, 0xd2, 0xd8, 0x4a, 0xdb, 0x38, 0x1e, 0x30, 0x2a, 0x8f, 0xcf, 0xfa, 0x7e,
0xad, 0xf5, 0xd1, 0x29, 0x7c, 0xf2, 0xbc, 0x2c, 0xda, 0x74, 0xbb, 0x10, 0x29, 0xca, 0xea, 0x5b, 0x3c, 0x78, 0xb1, 0x3e, 0x3a, 0x87, 0x8f, 0x9f, 0x96, 0x45, 0x9b, 0x6e, 0xe7, 0x22, 0x45, 0x5b,
0xaa, 0x23, 0xb6, 0x76, 0x3d, 0x19, 0x43, 0x72, 0x7f, 0xa7, 0x1e, 0x16, 0x2c, 0x2e, 0x5c, 0x01, 0x03, 0x2b, 0x75, 0xc8, 0x36, 0xb6, 0x27, 0x13, 0x48, 0xee, 0x6e, 0xd5, 0xfd, 0x52, 0xc5, 0xb9,
0x24, 0x45, 0xe6, 0xc5, 0xf2, 0xb9, 0x32, 0xf4, 0x84, 0xf4, 0x7f, 0x54, 0x5d, 0x6b, 0x66, 0x7d, 0x2b, 0x80, 0xe4, 0xc8, 0xa2, 0x58, 0x3e, 0x75, 0x86, 0xae, 0x90, 0xfe, 0x8f, 0xaa, 0x6b, 0xad,
0x17, 0xa9, 0x95, 0xea, 0x8a, 0x4c, 0x0d, 0x0e, 0x0c, 0x18, 0x45, 0x2f, 0x7c, 0x7a, 0x17, 0xbc, 0x6c, 0xe0, 0x22, 0xb5, 0x56, 0x5d, 0x51, 0xa9, 0xc1, 0x81, 0x01, 0xa3, 0xe8, 0x85, 0x8f, 0xef,
0x6d, 0xcf, 0xfc, 0xef, 0xd8, 0x33, 0x98, 0x7d, 0x93, 0x47, 0xbc, 0x67, 0x45, 0xa0, 0x04, 0x0c, 0x83, 0x77, 0x9d, 0xb9, 0xff, 0x1d, 0x7b, 0x06, 0xb3, 0x77, 0xf2, 0x88, 0xf7, 0xad, 0x09, 0xb4,
0x74, 0xc8, 0xde, 0xd9, 0x5f, 0x18, 0x62, 0x74, 0x61, 0xa9, 0xe7, 0x6a, 0xad, 0x78, 0x8c, 0xd9, 0x80, 0x81, 0x0e, 0xd9, 0x7b, 0xfb, 0x0b, 0x43, 0x8c, 0x10, 0x96, 0x7a, 0xe1, 0xd6, 0x1a, 0x62,
0x56, 0x46, 0x0f, 0x1a, 0x09, 0xd9, 0xd1, 0x3a, 0x88, 0x4e, 0xce, 0xb6, 0x80, 0xe8, 0x61, 0x8e, 0xcc, 0xb6, 0x32, 0xba, 0xd0, 0x48, 0xc8, 0x0e, 0x37, 0x49, 0x74, 0x7c, 0xfa, 0x02, 0x89, 0xee,
0xa2, 0xd6, 0x1c, 0x45, 0xad, 0xf6, 0x06, 0x88, 0xd0, 0x74, 0x32, 0x50, 0x53, 0x60, 0xed, 0xc3, 0x17, 0x2c, 0x6a, 0x2f, 0x58, 0xd4, 0xee, 0x6c, 0x91, 0x08, 0x8f, 0x4e, 0x07, 0xd4, 0x14, 0x58,
0x60, 0xce, 0x13, 0x1b, 0x7c, 0xc7, 0x3d, 0x01, 0x98, 0x9b, 0x76, 0x11, 0x8a, 0x14, 0xea, 0x79, 0x7b, 0x31, 0x58, 0xe8, 0xc4, 0x06, 0xdf, 0x75, 0x57, 0x00, 0xe6, 0xa6, 0x5d, 0xa4, 0x22, 0x85,
0xa4, 0xe9, 0x20, 0x1e, 0xd2, 0x3c, 0x74, 0xa7, 0x14, 0x06, 0xd4, 0xd1, 0x6e, 0xde, 0x69, 0xf1, 0x7a, 0x11, 0x69, 0x5a, 0x88, 0x47, 0x34, 0x0f, 0xdd, 0x2a, 0x85, 0x01, 0x75, 0xb2, 0xdb, 0x7b,
0xee, 0xb9, 0xd0, 0x2b, 0xe0, 0xd8, 0x20, 0x6b, 0xd4, 0x74, 0x18, 0xbd, 0x93, 0x0c, 0x4b, 0xa6, 0xda, 0xbc, 0x77, 0x26, 0xf4, 0x1a, 0x39, 0xb6, 0xc4, 0x1a, 0xb5, 0x1c, 0x46, 0xef, 0x38, 0xc3,
0xde, 0xc6, 0x08, 0x7b, 0xd5, 0x35, 0x4c, 0x50, 0x9a, 0x47, 0x2d, 0xb4, 0x04, 0x1c, 0x11, 0x73, 0x92, 0xa9, 0x5f, 0x52, 0x84, 0xbd, 0xea, 0x0a, 0xa6, 0x68, 0xcd, 0xa3, 0x16, 0x5a, 0x02, 0x8e,
0x1c, 0x69, 0x21, 0xf5, 0x17, 0x37, 0x68, 0x5a, 0xb2, 0x26, 0xcc, 0x0d, 0x7b, 0x19, 0xae, 0x84, 0x88, 0x39, 0x8e, 0xb4, 0x90, 0xfa, 0xcb, 0x1d, 0x34, 0x2d, 0xd9, 0x23, 0x2c, 0x0e, 0xf6, 0x3c,
0x56, 0x74, 0xb3, 0x98, 0xc0, 0x06, 0x54, 0x7b, 0x0f, 0x05, 0x94, 0x82, 0x7e, 0x9e, 0x40, 0xd0, 0x5d, 0x89, 0xad, 0x08, 0xb3, 0x98, 0xc2, 0x16, 0x55, 0xfb, 0xf7, 0x05, 0x94, 0x82, 0x7e, 0x9e,
0x5b, 0x80, 0x9e, 0xbb, 0x87, 0x89, 0xf3, 0xbd, 0xce, 0x00, 0x8a, 0x3f, 0x40, 0xd4, 0xed, 0xc0, 0x40, 0xd2, 0x5b, 0x82, 0x9e, 0xb9, 0x8b, 0x89, 0xc3, 0x5e, 0x67, 0x00, 0xc5, 0x7f, 0x61, 0xd4,
0x85, 0xae, 0x23, 0xba, 0x8d, 0x33, 0x94, 0x4b, 0x93, 0x12, 0x9b, 0xe2, 0x8b, 0x60, 0xe1, 0xb5, 0xcd, 0xd0, 0x85, 0xae, 0x2b, 0x7a, 0x8d, 0x53, 0xb4, 0x4b, 0x93, 0x12, 0x9b, 0xe1, 0x8d, 0x60,
0x89, 0xc0, 0x98, 0x0b, 0xad, 0x2b, 0xd0, 0xa1, 0x0d, 0xf2, 0xb9, 0x1b, 0x0a, 0x40, 0x5a, 0x49, 0x89, 0xda, 0x54, 0x60, 0xcc, 0x85, 0xd6, 0x15, 0xe8, 0xd0, 0x06, 0xf9, 0xcc, 0x0d, 0x05, 0x20,
0x62, 0xe8, 0x84, 0x09, 0xcd, 0xa8, 0xbb, 0xd3, 0x70, 0x92, 0xa8, 0x12, 0xcd, 0x35, 0xd9, 0x63, 0xad, 0x25, 0x31, 0x72, 0xc6, 0x84, 0x66, 0xd4, 0xdd, 0x69, 0x38, 0x49, 0x54, 0x89, 0xc7, 0x35,
0xc0, 0x84, 0xa4, 0x5f, 0x51, 0x34, 0x68, 0x56, 0xa8, 0x29, 0xfa, 0x82, 0x06, 0xf0, 0x2a, 0xb7, 0xd9, 0x43, 0xc0, 0x84, 0xa4, 0x5f, 0x51, 0x34, 0x68, 0x56, 0xa8, 0x19, 0x62, 0x41, 0x03, 0x78,
0xd6, 0x87, 0x9d, 0xa6, 0xb0, 0x43, 0x9a, 0x1b, 0xf1, 0x70, 0x9e, 0x4b, 0xb9, 0xb3, 0x8a, 0x9e, 0x95, 0xdb, 0xd3, 0x87, 0xdd, 0xa6, 0xb0, 0x43, 0x9a, 0x1b, 0xf1, 0x70, 0x9e, 0x4b, 0xb9, 0x3b,
0x64, 0x54, 0x58, 0x6f, 0x50, 0x63, 0x37, 0xe1, 0xac, 0x05, 0xba, 0x77, 0x73, 0xf1, 0x52, 0xa4, 0x15, 0x5d, 0xc9, 0xa8, 0xb0, 0x5e, 0xa3, 0xc7, 0x6e, 0xc2, 0xd9, 0x08, 0x74, 0xff, 0xfa, 0xfc,
0xaf, 0x95, 0x84, 0xc6, 0xb6, 0x60, 0xfc, 0x1d, 0xa3, 0x75, 0x7a, 0xb6, 0xe3, 0x26, 0xe1, 0xcf, 0xb9, 0x48, 0x5f, 0x29, 0x09, 0x8d, 0x97, 0x82, 0xf1, 0x17, 0x8c, 0xd6, 0xc9, 0xe9, 0x8e, 0x9b,
0xbf, 0xb4, 0x69, 0x0c, 0x33, 0xa5, 0xca, 0x70, 0xd0, 0xc7, 0x99, 0x8c, 0xa6, 0x77, 0xac, 0xe8, 0x84, 0x3f, 0xbf, 0xe9, 0xd0, 0x18, 0x66, 0x4a, 0x95, 0xe1, 0xa0, 0x8f, 0x33, 0x19, 0x4d, 0xef,
0x68, 0xce, 0xe6, 0xfd, 0x06, 0x5b, 0x86, 0xbb, 0x37, 0xe8, 0xb7, 0x0f, 0xf7, 0xfb, 0x9f, 0x7a, 0x58, 0xd1, 0xf1, 0x38, 0xdb, 0xfb, 0x1b, 0x6c, 0x15, 0xee, 0xfe, 0x70, 0xd0, 0x39, 0xd8, 0x1f,
0xdb, 0x84, 0xbc, 0xad, 0x69, 0xce, 0xa1, 0x7a, 0xd8, 0x8a, 0x9b, 0xbf, 0xf1, 0xee, 0xbf, 0x2e, 0x7c, 0xea, 0xbf, 0x64, 0xe4, 0x5d, 0x2d, 0x73, 0x06, 0xd5, 0xfd, 0x8b, 0xbc, 0xf9, 0x85, 0xf7,
0x6f, 0xf6, 0x3f, 0x6f, 0xe5, 0xf2, 0x8e, 0x77, 0xff, 0x5d, 0x09, 0x89, 0x8a, 0xee, 0x9f, 0x8b, 0xfe, 0x7e, 0x71, 0xbd, 0xff, 0xf9, 0x45, 0x2d, 0xef, 0x79, 0xef, 0x1f, 0x95, 0x90, 0xe8, 0xe8,
0xd1, 0xfe, 0xa7, 0xc4, 0xc4, 0x5b, 0x99, 0xfd, 0xb2, 0xa4, 0xb5, 0x92, 0xb7, 0xf1, 0x7c, 0xc3, 0xfe, 0x99, 0x18, 0xef, 0x7f, 0x4a, 0x4c, 0xfc, 0xa2, 0xb2, 0x37, 0x2b, 0x59, 0x6b, 0xf9, 0x45,
0xbb, 0x37, 0x53, 0x91, 0x89, 0xd1, 0xd8, 0x5c, 0x61, 0x05, 0xd8, 0x20, 0x6e, 0x3c, 0x47, 0xee, 0x52, 0x23, 0x3e, 0x43, 0x28, 0xc7, 0xbf, 0xbc, 0xd9, 0x47, 0xf4, 0x9e, 0x91, 0x5b, 0x28, 0x7c,
0xed, 0x0f, 0xd9, 0x61, 0x8e, 0xdc, 0xde, 0xa0, 0x2f, 0x30, 0x12, 0x07, 0xad, 0x25, 0xd1, 0x1c, 0xcb, 0x7b, 0xd7, 0x33, 0x91, 0x89, 0xf1, 0xc4, 0x5c, 0x62, 0xa9, 0xf8, 0xb1, 0x56, 0x64, 0xf8,
0xcc, 0x6e, 0x88, 0xa0, 0xbf, 0xf5, 0x58, 0x5b, 0x76, 0xff, 0x60, 0xf0, 0xde, 0x3e, 0x43, 0x37, 0xcd, 0xf3, 0x02, 0x8d, 0x55, 0x32, 0xdd, 0x5c, 0x23, 0x68, 0x68, 0xb4, 0xd5, 0x5e, 0x49, 0xad,
0xfe, 0xdc, 0x10, 0xdd, 0xa4, 0x17, 0x02, 0xfe, 0x47, 0xaf, 0x08, 0x7a, 0x52, 0xd0, 0x6f, 0xa3, 0xb3, 0xde, 0xfe, 0xad, 0xc7, 0xdf, 0xf2, 0xff, 0x3e, 0x6c, 0x37, 0xe9, 0x26, 0x41, 0x79, 0x47,
0xff, 0x07, 0x10, 0x30, 0x1d, 0xec, 0x2b, 0x15, 0x00, 0x00 0xd7, 0x0d, 0xba, 0x7b, 0xd0, 0x8f, 0xa8, 0xff, 0x01, 0x31, 0x18, 0xad, 0x59, 0x54, 0x15, 0x00,
0x00
}; };
// Autogenerated from wled00/data/settings_leds.htm, do not edit!! // Autogenerated from wled00/data/settings_leds.htm, do not edit!!
const uint16_t PAGE_settings_leds_length = 7593; const uint16_t PAGE_settings_leds_length = 7593;
const uint8_t PAGE_settings_leds[] PROGMEM = { const uint8_t PAGE_settings_leds[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xdd, 0x3c, 0xdb, 0x76, 0xe2, 0x48, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xdd, 0x3c, 0xdb, 0x76, 0xe2, 0x48,
0x92, 0xef, 0x7c, 0x45, 0x5a, 0xdd, 0xed, 0x92, 0x1a, 0x19, 0x24, 0x2e, 0x6e, 0x0c, 0x08, 0xaf, 0x92, 0xef, 0x7c, 0x45, 0x5a, 0xdd, 0xed, 0x92, 0x1a, 0x19, 0x24, 0x2e, 0x6e, 0x0c, 0x08, 0xaf,
0xa1, 0x2e, 0xed, 0x19, 0xbb, 0xed, 0x03, 0xae, 0xaa, 0x99, 0x53, 0x5d, 0xa7, 0x4b, 0x48, 0x09, 0xa1, 0x2e, 0xed, 0x19, 0xbb, 0xed, 0x03, 0xae, 0xaa, 0x99, 0x53, 0x5d, 0xa7, 0x4b, 0x48, 0x09,
0xa8, 0x2c, 0x24, 0x46, 0x12, 0xbe, 0xac, 0xed, 0xfd, 0xa6, 0xfd, 0x86, 0xfd, 0xb2, 0x8d, 0xc8, 0xa8, 0x2c, 0x24, 0x46, 0x12, 0xbe, 0xac, 0xed, 0xfd, 0xa6, 0xfd, 0x86, 0xfd, 0xb2, 0x8d, 0xc8,
@ -756,7 +757,7 @@ const uint8_t PAGE_settings_leds[] PROGMEM = {
// Autogenerated from wled00/data/settings_dmx.htm, do not edit!! // Autogenerated from wled00/data/settings_dmx.htm, do not edit!!
const uint16_t PAGE_settings_dmx_length = 1612; const uint16_t PAGE_settings_dmx_length = 1612;
const uint8_t PAGE_settings_dmx[] PROGMEM = { const uint8_t PAGE_settings_dmx[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x95, 0x57, 0xdb, 0x72, 0xdb, 0x36, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x95, 0x57, 0xdb, 0x72, 0xdb, 0x36,
0x10, 0x7d, 0xd7, 0x57, 0x20, 0x78, 0x88, 0xc9, 0x31, 0x43, 0x4a, 0x4e, 0x95, 0x36, 0x32, 0x49, 0x10, 0x7d, 0xd7, 0x57, 0x20, 0x78, 0x88, 0xc9, 0x31, 0x43, 0x4a, 0x4e, 0x95, 0x36, 0x32, 0x49,
0x37, 0x56, 0x5c, 0xdb, 0x1d, 0xdb, 0xf5, 0x44, 0x49, 0xd3, 0x4e, 0xd3, 0xe9, 0x40, 0xe4, 0x4a, 0x37, 0x56, 0x5c, 0xdb, 0x1d, 0xdb, 0xf5, 0x44, 0x49, 0xd3, 0x4e, 0xd3, 0xe9, 0x40, 0xe4, 0x4a,
0x44, 0x4c, 0x02, 0x2c, 0x00, 0x4a, 0x76, 0x2e, 0xff, 0xde, 0x05, 0x48, 0x5d, 0xec, 0xd8, 0x69, 0x44, 0x4c, 0x02, 0x2c, 0x00, 0x4a, 0x76, 0x2e, 0xff, 0xde, 0x05, 0x48, 0x5d, 0xec, 0xd8, 0x69,
@ -863,7 +864,7 @@ const uint8_t PAGE_settings_dmx[] PROGMEM = {
// Autogenerated from wled00/data/settings_ui.htm, do not edit!! // Autogenerated from wled00/data/settings_ui.htm, do not edit!!
const uint16_t PAGE_settings_ui_length = 3181; const uint16_t PAGE_settings_ui_length = 3181;
const uint8_t PAGE_settings_ui[] PROGMEM = { const uint8_t PAGE_settings_ui[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x59, 0x6d, 0x77, 0xda, 0x38, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xad, 0x59, 0x6d, 0x77, 0xda, 0x38,
0x16, 0xfe, 0xce, 0xaf, 0x50, 0xd5, 0x39, 0x19, 0x38, 0x71, 0x81, 0xb4, 0xb3, 0x67, 0x5b, 0xc0, 0x16, 0xfe, 0xce, 0xaf, 0x50, 0xd5, 0x39, 0x19, 0x38, 0x71, 0x81, 0xb4, 0xb3, 0x67, 0x5b, 0xc0,
0x64, 0x9b, 0x34, 0xd3, 0x66, 0x4e, 0x3a, 0xed, 0x96, 0x74, 0x3b, 0x73, 0xba, 0x3d, 0x19, 0x63, 0x64, 0x9b, 0x34, 0xd3, 0x66, 0x4e, 0x3a, 0xed, 0x96, 0x74, 0x3b, 0x73, 0xba, 0x3d, 0x19, 0x63,
0x0b, 0x50, 0x63, 0x5b, 0x1e, 0x4b, 0x0e, 0xc9, 0x52, 0xfe, 0xfb, 0x3e, 0x57, 0xb2, 0xc1, 0x90, 0x0b, 0x50, 0x63, 0x5b, 0x1e, 0x4b, 0x0e, 0xc9, 0x52, 0xfe, 0xfb, 0x3e, 0x57, 0xb2, 0xc1, 0x90,
@ -1068,7 +1069,7 @@ const uint8_t PAGE_settings_ui[] PROGMEM = {
// Autogenerated from wled00/data/settings_sync.htm, do not edit!! // Autogenerated from wled00/data/settings_sync.htm, do not edit!!
const uint16_t PAGE_settings_sync_length = 3318; const uint16_t PAGE_settings_sync_length = 3318;
const uint8_t PAGE_settings_sync[] PROGMEM = { const uint8_t PAGE_settings_sync[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x1a, 0x6b, 0x53, 0xdb, 0xb8, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xad, 0x1a, 0x6b, 0x53, 0xdb, 0xb8,
0xf6, 0xbb, 0x7f, 0x85, 0xf0, 0xce, 0x74, 0x93, 0x25, 0xe4, 0x01, 0x84, 0x52, 0x88, 0xdd, 0x0b, 0xf6, 0xbb, 0x7f, 0x85, 0xf0, 0xce, 0x74, 0x93, 0x25, 0xe4, 0x01, 0x84, 0x52, 0x88, 0xdd, 0x0b,
0x84, 0x42, 0xee, 0x2d, 0x34, 0x4d, 0xe8, 0xb6, 0x3b, 0x73, 0x67, 0x76, 0x14, 0x5b, 0x49, 0x04, 0x84, 0x42, 0xee, 0x2d, 0x34, 0x4d, 0xe8, 0xb6, 0x3b, 0x73, 0x67, 0x76, 0x14, 0x5b, 0x49, 0x04,
0xb6, 0xe5, 0xb5, 0x64, 0x1e, 0xd3, 0xed, 0x7f, 0xbf, 0xe7, 0x48, 0xb6, 0x93, 0x98, 0xbc, 0x7a, 0xb6, 0xe5, 0xb5, 0x64, 0x1e, 0xd3, 0xed, 0x7f, 0xbf, 0xe7, 0x48, 0xb6, 0x93, 0x98, 0xbc, 0x7a,
@ -1282,7 +1283,7 @@ const uint8_t PAGE_settings_sync[] PROGMEM = {
// Autogenerated from wled00/data/settings_time.htm, do not edit!! // Autogenerated from wled00/data/settings_time.htm, do not edit!!
const uint16_t PAGE_settings_time_length = 3313; const uint16_t PAGE_settings_time_length = 3313;
const uint8_t PAGE_settings_time[] PROGMEM = { const uint8_t PAGE_settings_time[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xd5, 0x1a, 0x6b, 0x57, 0xdb, 0x38, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xd5, 0x1a, 0x6b, 0x57, 0xdb, 0x38,
0xf6, 0x7b, 0x7e, 0x85, 0x50, 0x7b, 0x98, 0x78, 0x70, 0x9e, 0x90, 0x16, 0x92, 0xd8, 0xdd, 0x10, 0xf6, 0x7b, 0x7e, 0x85, 0x50, 0x7b, 0x98, 0x78, 0x70, 0x9e, 0x90, 0x16, 0x92, 0xd8, 0xdd, 0x10,
0xd2, 0x42, 0x4b, 0x02, 0x67, 0x92, 0x0e, 0xbb, 0xd3, 0xf6, 0x4c, 0x15, 0x5b, 0x49, 0x0c, 0x8e, 0xd2, 0x42, 0x4b, 0x02, 0x67, 0x92, 0x0e, 0xbb, 0xd3, 0xf6, 0x4c, 0x15, 0x5b, 0x49, 0x0c, 0x8e,
0xe4, 0xb5, 0x65, 0x02, 0x4b, 0xf9, 0xef, 0x7b, 0x25, 0x39, 0xce, 0xd3, 0xd0, 0x76, 0x66, 0x3f, 0xe4, 0xb5, 0x65, 0x02, 0x4b, 0xf9, 0xef, 0x7b, 0x25, 0x39, 0xce, 0xd3, 0xd0, 0x76, 0x66, 0x3f,
@ -1496,7 +1497,7 @@ const uint8_t PAGE_settings_time[] PROGMEM = {
// Autogenerated from wled00/data/settings_sec.htm, do not edit!! // Autogenerated from wled00/data/settings_sec.htm, do not edit!!
const uint16_t PAGE_settings_sec_length = 2407; const uint16_t PAGE_settings_sec_length = 2407;
const uint8_t PAGE_settings_sec[] PROGMEM = { const uint8_t PAGE_settings_sec[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xa5, 0x58, 0x6d, 0x53, 0xdb, 0x48, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xa5, 0x58, 0x6d, 0x53, 0xdb, 0x48,
0x12, 0xfe, 0xee, 0x5f, 0x31, 0x9e, 0x54, 0xb1, 0xd6, 0x45, 0x58, 0x40, 0x72, 0x5b, 0x09, 0x58, 0x12, 0xfe, 0xee, 0x5f, 0x31, 0x9e, 0x54, 0xb1, 0xd6, 0x45, 0x58, 0x40, 0x72, 0x5b, 0x09, 0x58,
0xce, 0x41, 0x20, 0x1b, 0xae, 0x20, 0x50, 0xd8, 0x6c, 0xee, 0x2a, 0x97, 0x4a, 0x8d, 0xa5, 0xb1, 0xce, 0x41, 0x20, 0x1b, 0xae, 0x20, 0x50, 0xd8, 0x6c, 0xee, 0x2a, 0x97, 0x4a, 0x8d, 0xa5, 0xb1,
0x35, 0xb1, 0xac, 0xd1, 0xce, 0x8c, 0x70, 0x7c, 0xd9, 0xfd, 0xef, 0xf7, 0xf4, 0x48, 0x32, 0x86, 0x35, 0xb1, 0xac, 0xd1, 0xce, 0x8c, 0x70, 0x7c, 0xd9, 0xfd, 0xef, 0xf7, 0xf4, 0x48, 0x32, 0x86,
@ -1653,7 +1654,7 @@ const uint8_t PAGE_settings_sec[] PROGMEM = {
// Autogenerated from wled00/data/settings_um.htm, do not edit!! // Autogenerated from wled00/data/settings_um.htm, do not edit!!
const uint16_t PAGE_settings_um_length = 2786; const uint16_t PAGE_settings_um_length = 2786;
const uint8_t PAGE_settings_um[] PROGMEM = { const uint8_t PAGE_settings_um[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xcd, 0x59, 0x6d, 0x73, 0xdb, 0x36, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xcd, 0x59, 0x6d, 0x73, 0xdb, 0x36,
0x12, 0xfe, 0xee, 0x5f, 0x41, 0x23, 0x1e, 0x9b, 0x1c, 0xd1, 0x94, 0x9c, 0xb4, 0x33, 0xa9, 0x24, 0x12, 0xfe, 0xee, 0x5f, 0x41, 0x23, 0x1e, 0x9b, 0x1c, 0xd1, 0x94, 0x9c, 0xb4, 0x33, 0xa9, 0x24,
0xd2, 0x97, 0x38, 0x69, 0xa3, 0xcb, 0x8b, 0x3d, 0xe3, 0xb4, 0x9d, 0x1b, 0xc7, 0x17, 0x53, 0x22, 0xd2, 0x97, 0x38, 0x69, 0xa3, 0xcb, 0x8b, 0x3d, 0xe3, 0xb4, 0x9d, 0x1b, 0xc7, 0x17, 0x53, 0x22,
0x24, 0x21, 0xa6, 0x00, 0x16, 0x04, 0xfd, 0x72, 0xb2, 0xfe, 0xfb, 0x3d, 0x0b, 0xbe, 0x88, 0x72, 0x24, 0x21, 0xa6, 0x00, 0x16, 0x04, 0xfd, 0x72, 0xb2, 0xfe, 0xfb, 0x3d, 0x0b, 0xbe, 0x88, 0x72,
@ -1834,7 +1835,7 @@ const uint8_t PAGE_settings_um[] PROGMEM = {
// Autogenerated from wled00/data/settings_2D.htm, do not edit!! // Autogenerated from wled00/data/settings_2D.htm, do not edit!!
const uint16_t PAGE_settings_2D_length = 3172; const uint16_t PAGE_settings_2D_length = 3172;
const uint8_t PAGE_settings_2D[] PROGMEM = { const uint8_t PAGE_settings_2D[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xc5, 0x5a, 0x5b, 0x77, 0xdb, 0x36, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xc5, 0x5a, 0x5b, 0x77, 0xdb, 0x36,
0x12, 0x7e, 0xd7, 0xaf, 0x80, 0xd1, 0xae, 0x4b, 0x5a, 0xd4, 0xcd, 0x4d, 0x7a, 0x5a, 0x49, 0x94, 0x12, 0x7e, 0xd7, 0xaf, 0x80, 0xd1, 0xae, 0x4b, 0x5a, 0xd4, 0xcd, 0x4d, 0x7a, 0x5a, 0x49, 0x94,
0x36, 0x8e, 0xd3, 0xd8, 0x7b, 0xec, 0x44, 0xc7, 0x72, 0xed, 0xe4, 0xb4, 0x3d, 0x0d, 0x4d, 0x42, 0x36, 0x8e, 0xd3, 0xd8, 0x7b, 0xec, 0x44, 0xc7, 0x72, 0xed, 0xe4, 0xb4, 0x3d, 0x0d, 0x4d, 0x42,
0x12, 0x12, 0x0a, 0x60, 0x09, 0x48, 0xb6, 0xeb, 0xf8, 0xbf, 0xef, 0x0c, 0xc0, 0x9b, 0x68, 0xd9, 0x12, 0x12, 0x0a, 0x60, 0x09, 0x48, 0xb6, 0xeb, 0xf8, 0xbf, 0xef, 0x0c, 0xc0, 0x9b, 0x68, 0xd9,
@ -2039,7 +2040,7 @@ const uint8_t PAGE_settings_2D[] PROGMEM = {
// Autogenerated from wled00/data/settings_pin.htm, do not edit!! // Autogenerated from wled00/data/settings_pin.htm, do not edit!!
const uint16_t PAGE_settings_pin_length = 471; const uint16_t PAGE_settings_pin_length = 471;
const uint8_t PAGE_settings_pin[] PROGMEM = { const uint8_t PAGE_settings_pin[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x5d, 0x52, 0x4d, 0x6f, 0x13, 0x31, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x5d, 0x52, 0x4d, 0x6f, 0x13, 0x31,
0x10, 0xbd, 0xef, 0xaf, 0x30, 0x73, 0x69, 0x82, 0x92, 0x6c, 0xa8, 0xa8, 0x04, 0xaa, 0xbd, 0x42, 0x10, 0xbd, 0xef, 0xaf, 0x30, 0x73, 0x69, 0x82, 0x92, 0x6c, 0xa8, 0xa8, 0x04, 0xaa, 0xbd, 0x42,
0x81, 0x1e, 0xb8, 0x94, 0x48, 0xe5, 0x52, 0x55, 0x55, 0xe5, 0xd8, 0xb3, 0x89, 0x55, 0x7f, 0x2c, 0x81, 0x1e, 0xb8, 0x94, 0x48, 0xe5, 0x52, 0x55, 0x55, 0xe5, 0xd8, 0xb3, 0x89, 0x55, 0x7f, 0x2c,
0xb6, 0x37, 0x21, 0x54, 0xfc, 0x77, 0xc6, 0xbb, 0xa1, 0xa0, 0x5c, 0xd6, 0x7e, 0x33, 0xe3, 0x37, 0xb6, 0x37, 0x21, 0x54, 0xfc, 0x77, 0xc6, 0xbb, 0xa1, 0xa0, 0x5c, 0xd6, 0x7e, 0x33, 0xe3, 0x37,

View File

@ -115,6 +115,15 @@ const ethernet_settings ethernetBoards[] = {
ETH_CLOCK_GPIO17_OUT // eth_clk_mode ETH_CLOCK_GPIO17_OUT // eth_clk_mode
}, },
// Serg74-ESP32 Ethernet Shield
{
1, // eth_address,
5, // eth_power,
23, // eth_mdc,
18, // eth_mdio,
ETH_PHY_LAN8720, // eth_type,
ETH_CLOCK_GPIO17_OUT // eth_clk_mode
}
}; };
#endif #endif

View File

@ -189,7 +189,7 @@ void realtimeLock(uint32_t timeoutMs, byte md)
void exitRealtime() { void exitRealtime() {
if (!realtimeMode) return; if (!realtimeMode) return;
if (realtimeOverride == REALTIME_OVERRIDE_ONCE) realtimeOverride = REALTIME_OVERRIDE_NONE; if (realtimeOverride == REALTIME_OVERRIDE_ONCE) realtimeOverride = REALTIME_OVERRIDE_NONE;
strip.setBrightness(scaledBri(bri)); strip.setBrightness(scaledBri(bri), true);
realtimeTimeout = 0; // cancel realtime mode immediately realtimeTimeout = 0; // cancel realtime mode immediately
realtimeMode = REALTIME_MODE_INACTIVE; // inform UI immediately realtimeMode = REALTIME_MODE_INACTIVE; // inform UI immediately
realtimeIP[0] = 0; realtimeIP[0] = 0;

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2304280 #define VERSION 2305090
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG