diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index dfe0770..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1,2 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
diff --git a/.github/workflows/push-to-blledflasher.yml b/.github/workflows/push-to-blledflasher.yml
new file mode 100644
index 0000000..3a5a944
--- /dev/null
+++ b/.github/workflows/push-to-blledflasher.yml
@@ -0,0 +1,68 @@
+name: Push Firmware to BLLED-Flasher
+
+on:
+ release:
+ types: [published, edited]
+
+jobs:
+ push-firmware:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout BLLEDController-NG
+ uses: actions/checkout@v3
+
+ - name: Download .bin from current release
+ uses: actions/github-script@v6
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const fs = require('fs');
+ const owner = context.repo.owner;
+ const repo = context.repo.repo;
+ const release = context.payload.release;
+ const tag = release.tag_name;
+
+ const assets = release.assets.filter(a => a.name.endsWith('.bin'));
+ if (assets.length === 0) {
+ core.setFailed("No .bin files found in release");
+ return;
+ }
+
+ fs.mkdirSync('firmware', { recursive: true });
+
+ for (const asset of assets) {
+ const dl = await github.rest.repos.getReleaseAsset({
+ owner,
+ repo,
+ asset_id: asset.id,
+ headers: { Accept: 'application/octet-stream' }
+ });
+
+ fs.writeFileSync(`firmware/${asset.name}`, Buffer.from(dl.data));
+ console.log(`β
Downloaded: ${asset.name}`);
+ }
+
+ - name: Clone BLLED-Flasher repo
+ run: |
+ git clone https://x-access-token:${{ secrets.BLLED_FLASHER_TOKEN }}@github.com/softwarecrash/BLLED-Flasher.git flasher
+ cp firmware/*.bin flasher/firmware/
+
+ - name: Generate firmware.json + manifests
+ run: |
+ cd flasher
+ node generateRelease.js
+
+ - name: Commit and Push to BLLED-Flasher
+ run: |
+ cd flasher
+ git config user.name "BLLED Release Bot"
+ git config user.email "actions@github.com"
+ git fetch origin
+ git add firmware/
+ if git diff --cached --quiet; then
+ echo "β
Keine Γnderungen β kein Push."
+ else
+ git commit -m "π¦ Add firmware from release ${{ github.event.release.tag_name }}"
+ git push
+ fi
diff --git a/.gitignore b/.gitignore
index c503085..11a8876 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,4 @@ BLLEDController.code-workspace
src/www/www.h
.DS_Store
**/.DS_Store
-docs/firmware
\ No newline at end of file
+.github
diff --git a/README.md b/README.md
index dc23cd0..de5922f 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
The BL Led Controller is an ESP8266 / ESP32 based device that connects to your Bambulab X1,X1C,P1P Or P1S and controls the LED strip based on the state of the printer.
### Flashing and Setup
-1. go to https://dutchdevelop.github.io/blledsetup/
+1. go to the [Web Flasher](https://softwarecrash.github.io/BLLED-Flasher/)
2. connect your ESP32
3. Select the Firmware build you want
4. Click on Flash
diff --git a/docs/.nojekyll b/docs/.nojekyll
deleted file mode 100644
index c0a9e35..0000000
--- a/docs/.nojekyll
+++ /dev/null
@@ -1 +0,0 @@
-Sun May 18 11:18:13 UTC 2025
diff --git a/docs/blled.svg b/docs/blled.svg
deleted file mode 100644
index 05b1a9a..0000000
--- a/docs/blled.svg
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
diff --git a/docs/favicon.ico b/docs/favicon.ico
deleted file mode 100644
index a69a720..0000000
Binary files a/docs/favicon.ico and /dev/null differ
diff --git a/docs/firmware/BLLEDController_V1.0.0.nightly.170525.bin b/docs/firmware/BLLEDController_V1.0.0.nightly.170525.bin
deleted file mode 100644
index 810d0e2..0000000
Binary files a/docs/firmware/BLLEDController_V1.0.0.nightly.170525.bin and /dev/null differ
diff --git a/docs/firmware/BLLEDController_V1.0.0.nightly.170525.json b/docs/firmware/BLLEDController_V1.0.0.nightly.170525.json
deleted file mode 100644
index b310cfa..0000000
--- a/docs/firmware/BLLEDController_V1.0.0.nightly.170525.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "BLLEDController_V1.0.0.nightly.170525",
- "version": "1.0.0.nightly.170525",
- "builds": [
- {
- "chipFamily": "ESP32",
- "parts": [
- {
- "path": "BLLEDController_V1.0.0.nightly.170525.bin",
- "offset": 0
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/docs/firmware/BLLEDController_V1.0.0.nightly.180525.1.bin b/docs/firmware/BLLEDController_V1.0.0.nightly.180525.1.bin
deleted file mode 100644
index e841a96..0000000
Binary files a/docs/firmware/BLLEDController_V1.0.0.nightly.180525.1.bin and /dev/null differ
diff --git a/docs/firmware/BLLEDController_V1.0.0.nightly.180525.1.json b/docs/firmware/BLLEDController_V1.0.0.nightly.180525.1.json
deleted file mode 100644
index a898f97..0000000
--- a/docs/firmware/BLLEDController_V1.0.0.nightly.180525.1.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "BLLEDController_V1.0.0.nightly.180525.1",
- "version": "1.0.0.nightly.180525.1",
- "builds": [
- {
- "chipFamily": "ESP32",
- "parts": [
- {
- "path": "BLLEDController_V1.0.0.nightly.180525.1.bin",
- "offset": 0
- }
- ]
- }
- ]
-}
\ No newline at end of file
diff --git a/docs/firmware/firmware.json b/docs/firmware/firmware.json
deleted file mode 100644
index 8ed1294..0000000
--- a/docs/firmware/firmware.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
- {
- "version": "1.0.0.nightly.170525",
- "prerelease": true,
- "file": "BLLEDController_V1.0.0.nightly.170525.bin"
- },
- {
- "version": "1.0.0.nightly.180525.1",
- "prerelease": true,
- "file": "BLLEDController_V1.0.0.nightly.180525.1.bin"
- }
-]
\ No newline at end of file
diff --git a/docs/firmware/last_update.txt b/docs/firmware/last_update.txt
deleted file mode 100644
index fc521ca..0000000
--- a/docs/firmware/last_update.txt
+++ /dev/null
@@ -1 +0,0 @@
-Updated at Sun May 18 16:16:20 UTC 2025
diff --git a/docs/firmware/readme.md b/docs/firmware/readme.md
deleted file mode 100644
index e69de29..0000000
diff --git a/docs/generateRelease.js b/docs/generateRelease.js
deleted file mode 100644
index 6e36a29..0000000
--- a/docs/generateRelease.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-
-const firmwareDir = path.resolve(__dirname, 'firmware');
-const binFiles = fs.readdirSync(firmwareDir).filter(f => f.endsWith('.bin'));
-
-if (binFiles.length === 0) {
- console.log('β No .bin files found in firmware folder.');
- process.exit(1);
-}
-
-const firmwareList = [];
-
-for (const file of binFiles) {
- const versionMatch = file.match(/_V?([\w.\-]+)\.bin$/);
- const version = versionMatch ? versionMatch[1] : 'unknown';
- const isPre = file.toLowerCase().includes('nightly') || file.toLowerCase().includes('beta');
-
- // π Add entry to firmware.json
- firmwareList.push({
- version,
- prerelease: isPre,
- file
- });
-
- // π Create ESP Web Tools Manifest (merged .bin format)
- const manifest = {
- name: file.replace(/\.bin$/, ''),
- version,
- builds: [
- {
- chipFamily: "ESP32",
- parts: [
- {
- path: file,
- offset: 0
- }
- ]
- }
- ]
- };
-
- const manifestPath = path.join(firmwareDir, file.replace(/\.bin$/, '.json'));
- fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
- console.log(`β
Created manifest: ${manifestPath}`);
-}
-
-// π Write firmware.json (for dropdown use in UI)
-const firmwareJsonPath = path.join(firmwareDir, 'firmware.json');
-fs.writeFileSync(firmwareJsonPath, JSON.stringify(firmwareList, null, 2));
-console.log(`β
Created firmware list: ${firmwareJsonPath}`);
diff --git a/docs/index.html b/docs/index.html
deleted file mode 100644
index 090b53e..0000000
--- a/docs/index.html
+++ /dev/null
@@ -1,154 +0,0 @@
-
-
-
-
-
-
- BLLEDController-NG WebFlasher
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/particleCanvas.js b/docs/particleCanvas.js
deleted file mode 100644
index 03dd4a9..0000000
--- a/docs/particleCanvas.js
+++ /dev/null
@@ -1,94 +0,0 @@
- const canvas = document.getElementById('particleCanvas');
- const ctx = canvas.getContext('2d');
- canvas.width = window.innerWidth;
- canvas.height = window.innerHeight;
-
- let particlesArray = [];
- const numberOfParticles = 100;
-
- class Particle {
- constructor(x, y, directionX, directionY, size, color) {
- this.x = x;
- this.y = y;
- this.directionX = directionX;
- this.directionY = directionY;
- this.size = size;
- this.color = color;
- }
- draw() {
- ctx.beginPath();
- ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
- ctx.fillStyle = this.color;
- ctx.fill();
- }
-
-
- update() {
- if (this.x + this.size > canvas.width || this.x - this.size < 0) {
- this.directionX = -this.directionX;
- }
-
- if (this.y + this.size > canvas.height || this.y - this.size < 0) {
- this.directionY = -this.directionY;
- }
-
- this.x += this.directionX;
- this.y += this.directionY;
-
- this.draw();
- }
- }
-
- function init() {
- particlesArray = [];
- for (let i = 0; i < numberOfParticles; i++) {
- let size = Math.random() * 5 + 1;
- let x = Math.random() * (canvas.width - size * 2) + size;
- let y = Math.random() * (canvas.height - size * 2) + size;
- let directionX = (Math.random() * 0.5) - 0.25;
- let directionY = (Math.random() * 0.5) - 0.25;
- let color = 'rgba(255, 255, 255, 0.8)';
-
- particlesArray.push(new Particle(x, y, directionX, directionY, size, color));
- }
- }
-
- function connect() {
- let opacityValue = 1;
- for (let a = 0; a < particlesArray.length; a++) {
- for (let b = a; b < particlesArray.length; b++) {
- let distance = ((particlesArray[a].x - particlesArray[b].x) * (particlesArray[a].x - particlesArray[b].x))
- + ((particlesArray[a].y - particlesArray[b].y) * (particlesArray[a].y - particlesArray[b].y));
-
- if (distance < (canvas.width / 7) * (canvas.height / 7)) {
- opacityValue = 1 - (distance / 20000);
- ctx.strokeStyle = 'rgba(255, 255, 255,' + opacityValue + ')';
- ctx.lineWidth = 1;
- ctx.beginPath();
- ctx.moveTo(particlesArray[a].x, particlesArray[a].y);
- ctx.lineTo(particlesArray[b].x, particlesArray[b].y);
- ctx.stroke();
- }
- }
- }
- }
-
- function animate() {
- ctx.clearRect(0, 0, canvas.width, canvas.height);
-
- for (let i = 0; i < particlesArray.length; i++) {
- particlesArray[i].update();
- }
-
- connect();
- requestAnimationFrame(animate);
- }
-
- window.addEventListener('resize', () => {
- canvas.width = window.innerWidth;
- canvas.height = window.innerHeight;
- init();
- });
-
- init();
- animate();
\ No newline at end of file
diff --git a/docs/script.js b/docs/script.js
deleted file mode 100644
index 32f2152..0000000
--- a/docs/script.js
+++ /dev/null
@@ -1,39 +0,0 @@
-document.addEventListener("DOMContentLoaded", async () => {
- const firmwareSelect = document.getElementById("firmwareSelect");
- const flashButton = document.getElementById("flashButton");
- const basePath = window.location.pathname.replace(/\/[^/]*$/, '');
- const manifestBase = window.location.origin + basePath + "/firmware/";
-
- try {
- const response = await fetch("firmware/firmware.json");
- const firmwares = await response.json();
-
- if (!Array.isArray(firmwares)) throw new Error("Invalid JSON structure");
-
- // Sortiere nach neuester Version oben (optional)
- firmwares.sort((a, b) => b.version.localeCompare(a.version, undefined, { numeric: true, sensitivity: 'base' }));
-
- for (const fw of firmwares) {
- const opt = document.createElement("option");
- const label = `${fw.version}${fw.prerelease ? " (pre)" : ""}`;
- opt.value = fw.file;
- opt.textContent = label;
- firmwareSelect.appendChild(opt);
- }
-
- firmwareSelect.addEventListener("change", () => {
- const selected = firmwareSelect.value;
- if (selected) {
- flashButton.setAttribute("manifest", manifestBase + selected.replace(/\.bin$/, ".json"));
- flashButton.setAttribute("enabled", "");
- } else {
- flashButton.removeAttribute("manifest");
- flashButton.removeAttribute("enabled");
- }
- });
- } catch (err) {
- console.error("Fehler beim Laden der Firmware-Liste:", err);
- const status = document.getElementById("status");
- if (status) status.textContent = "Fehler beim Laden der Firmware-Dateien.";
- }
-});
\ No newline at end of file
diff --git a/platformio.ini b/platformio.ini
index 7ab13cc..fc18a31 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -11,7 +11,7 @@
[env:esp32dev]
custom_project_name = BLLEDController
custom_project_codename = Balder
-custom_version = 1.0.0.nightly.180525.1 ; for github release name the release VX.Y.Z X=(Incerase when Modifications oder new functions Break the API/webUI) Y=(Incerase for add oder modify changes that not breake the API/webUI until X incearase) Z=(Incerase for bugfix releases until minor is incerase)
+custom_version = 1.0.0.nightly.250525.1 ; for github release name the release VX.Y.Z X=(Incerase when Modifications oder new functions Break the API/webUI) Y=(Incerase for add oder modify changes that not breake the API/webUI until X incearase) Z=(Incerase for bugfix releases until minor is incerase)
platform = espressif32
board = esp32dev
framework = arduino
@@ -30,4 +30,4 @@ lib_deps =
luc-github/ESP32SSDP@1.2.1
ESP32Async/AsyncTCP
ESP32Async/ESPAsyncWebServer
- mathieucarbou/MycilaWebSerial@^8.0.0
\ No newline at end of file
+ mathieucarbou/MycilaWebSerial@^8.1.1
\ No newline at end of file
diff --git a/src/blled/AutoGrowBufferStream.h b/src/blled/AutoGrowBufferStream.h
index 95c2fd0..6589de9 100644
--- a/src/blled/AutoGrowBufferStream.h
+++ b/src/blled/AutoGrowBufferStream.h
@@ -29,7 +29,7 @@ class AutoGrowBufferStream : public Stream
if (this->_len + 1 > this->buffer_size) {
auto tmp = (char*)realloc(this->_buffer, this->buffer_size + BUFFER_INCREMENTS);
if (tmp == NULL) {
- Serial.println(F("Failed to grow buffer"));
+ LogSerial.println(F("Failed to grow buffer"));
return 0;
}
this->_buffer = tmp;
diff --git a/src/blled/filesystem.h b/src/blled/filesystem.h
index abe3275..f1cf177 100644
--- a/src/blled/filesystem.h
+++ b/src/blled/filesystem.h
@@ -28,7 +28,7 @@ char *generateRandomString(int length)
void saveFileSystem()
{
- Serial.println(F("Saving config"));
+ LogSerial.println(F("Saving config"));
JsonDocument json;
json["ssid"] = globalVariables.SSID;
@@ -124,17 +124,17 @@ void saveFileSystem()
File configFile = LittleFS.open(configPath, "w");
if (!configFile)
{
- Serial.println(F("Failed to save config"));
+ LogSerial.println(F("Failed to save config"));
return;
}
serializeJson(json, configFile);
configFile.close();
- Serial.println(F("Config Saved"));
+ LogSerial.println(F("Config Saved"));
}
void loadFileSystem()
{
- Serial.println(F("Loading config"));
+ LogSerial.println(F("Loading config"));
File configFile;
int attempts = 0;
@@ -146,16 +146,16 @@ void loadFileSystem()
break;
}
attempts++;
- Serial.println(F("Failed to open config file, retrying.."));
+ LogSerial.println(F("Failed to open config file, retrying.."));
delay(2000);
}
if (!configFile)
{
- Serial.print(F("Failed to open config file after "));
- Serial.print(attempts);
- Serial.println(F(" retries"));
+ LogSerial.print(F("Failed to open config file after "));
+ LogSerial.print(attempts);
+ LogSerial.println(F(" retries"));
- Serial.println(F("Clearing config"));
+ LogSerial.println(F("Clearing config"));
// LittleFS.remove(configPath);
saveFileSystem();
return;
@@ -222,15 +222,15 @@ void loadFileSystem()
printerConfig.frontCoverRGB = hex2rgb(json["frontCoverRGB"], json["frontCoverWW"], json["frontCoverCW"]);
printerConfig.nozzleTempRGB = hex2rgb(json["nozzleTempRGB"], json["nozzleTempWW"], json["nozzleTempCW"]);
printerConfig.bedTempRGB = hex2rgb(json["bedTempRGB"], json["bedTempWW"], json["bedTempCW"]);
- Serial.println(F("Loaded config"));
+ LogSerial.println(F("Loaded config"));
}
else
{
- Serial.println(F("Failed loading config"));
- Serial.println(F("Clearing config"));
+ LogSerial.println(F("Failed loading config"));
+ LogSerial.println(F("Clearing config"));
LittleFS.remove(configPath);
- // Serial.println(F("Generating new password"));
+ // LogSerial.println(F("Generating new password"));
// char* pw = generateRandomString(8);
// strcpy(printerConfig.webpagePassword, pw);
}
@@ -240,7 +240,7 @@ void loadFileSystem()
void deleteFileSystem()
{
- Serial.println(F("Deleting LittleFS"));
+ LogSerial.println(F("Deleting LittleFS"));
LittleFS.remove(configPath);
}
@@ -251,17 +251,17 @@ bool hasFileSystem()
void setupFileSystem()
{
- Serial.println(F("Mounting LittleFS"));
+ LogSerial.println(F("Mounting LittleFS"));
if (!LittleFS.begin())
{
- Serial.println(F("Failed to mount LittleFS"));
+ LogSerial.println(F("Failed to mount LittleFS"));
LittleFS.format();
- Serial.println(F("Formatting LittleFS"));
- Serial.println(F("Restarting Device"));
+ LogSerial.println(F("Formatting LittleFS"));
+ LogSerial.println(F("Restarting Device"));
delay(1000);
ESP.restart();
}
- Serial.println(F("Mounted LittleFS"));
+ LogSerial.println(F("Mounted LittleFS"));
};
#endif
\ No newline at end of file
diff --git a/src/blled/leds.h b/src/blled/leds.h
index 76dc7e2..36ae1f8 100644
--- a/src/blled/leds.h
+++ b/src/blled/leds.h
@@ -10,6 +10,15 @@ const int bluePin = 21;
const int warmPin = 22;
const int coldPin = 23;
+const int redChannel = 0;
+const int greenChannel = 1;
+const int blueChannel = 2;
+const int warmChannel = 3;
+const int coldChannel = 4;
+
+const int pwmFreq = 5000;
+const int pwmResolution = 8; // 8-bit PWM = 0-255
+
int currentRed = 0;
int currentGreen = 0;
int currentBlue = 0;
@@ -19,29 +28,33 @@ int currentCold = 0;
unsigned long lastUpdatems = 0;
unsigned long oldms = 0;
-COLOR hex2rgb(String hex, short ww_value = 0, short cw_value = 0) {
+COLOR hex2rgb(String hex, short ww_value = 0, short cw_value = 0)
+{
COLOR color;
long hexcolor;
strcpy(color.RGBhex, hex.c_str());
- if(hex.charAt(0) == '#') {
- hex.remove(0,1);
+ if (hex.charAt(0) == '#')
+ {
+ hex.remove(0, 1);
}
- while(hex.length() != 6) {
+ while (hex.length() != 6)
+ {
hex += "0";
}
hexcolor = strtol(hex.c_str(), NULL, 16);
color.r = (hexcolor & 0xFF0000) >> 16;
color.g = (hexcolor & 0x00FF00) >> 8;
- color.b = (hexcolor & 0x0000FF);
+ color.b = (hexcolor & 0x0000FF);
color.ww = ww_value;
color.cw = cw_value;
-
+
return color;
}
-void tweenToColor(int targetRed, int targetGreen, int targetBlue, int targetWarm, int targetCold, int duration = 500) {
+void tweenToColor(int targetRed, int targetGreen, int targetBlue, int targetWarm, int targetCold, int duration = 500)
+{
- float brightness = (float)printerConfig.brightness/100.0;
+ float brightness = (float)printerConfig.brightness / 100.0;
int brightenedRed = round(targetRed * brightness);
int brightenedGreen = round(targetGreen * brightness);
@@ -49,22 +62,24 @@ void tweenToColor(int targetRed, int targetGreen, int targetBlue, int targetWarm
int brightenedWarm = round(targetWarm * brightness);
int brightenedCold = round(targetCold * brightness);
- if (brightenedRed == currentRed && brightenedGreen == currentGreen && brightenedBlue == currentBlue && brightenedWarm == currentWarm && brightenedCold == currentCold){
+ if (brightenedRed == currentRed && brightenedGreen == currentGreen && brightenedBlue == currentBlue && brightenedWarm == currentWarm && brightenedCold == currentCold)
+ {
// Already set to the requested color
- if (printerConfig.debuging){
- Serial.print(F("LEDS already at color: ("));
- Serial.print(currentRed);
- Serial.print(F(", "));
- Serial.print(currentGreen);
- Serial.print(F(", "));
- Serial.print(currentBlue);
- Serial.print(F(", "));
- Serial.print(currentWarm);
- Serial.print(F(", "));
- Serial.print(currentCold);
- Serial.print(F(" Brightness: "));
- Serial.print(printerConfig.brightness);
- Serial.println(F(")"));
+ if (printerConfig.debuging)
+ {
+ LogSerial.print(F("LEDS already at color: ("));
+ LogSerial.print(currentRed);
+ LogSerial.print(F(", "));
+ LogSerial.print(currentGreen);
+ LogSerial.print(F(", "));
+ LogSerial.print(currentBlue);
+ LogSerial.print(F(", "));
+ LogSerial.print(currentWarm);
+ LogSerial.print(F(", "));
+ LogSerial.print(currentCold);
+ LogSerial.print(F(" Brightness: "));
+ LogSerial.print(printerConfig.brightness);
+ LogSerial.println(F(")"));
};
return;
}
@@ -75,18 +90,19 @@ void tweenToColor(int targetRed, int targetGreen, int targetBlue, int targetWarm
int warmStep = (brightenedWarm - currentWarm) / 255;
int coldStep = (brightenedCold - currentCold) / 255;
- for (int i = 0; i < 256; i++) {
+ for (int i = 0; i < 256; i++)
+ {
currentRed += redStep;
currentGreen += greenStep;
currentBlue += blueStep;
currentWarm += warmStep;
currentCold += coldStep;
- analogWrite(redPin, currentRed);
- analogWrite(greenPin, currentGreen);
- analogWrite(bluePin, currentBlue);
- analogWrite(warmPin, currentWarm);
- analogWrite(coldPin, currentCold);
+ ledcWrite(redChannel, currentRed);
+ ledcWrite(greenChannel, currentGreen);
+ ledcWrite(blueChannel, currentBlue);
+ ledcWrite(warmChannel, currentWarm);
+ ledcWrite(coldChannel, currentCold);
delay(stepTime);
}
@@ -96,25 +112,28 @@ void tweenToColor(int targetRed, int targetGreen, int targetBlue, int targetWarm
currentWarm = brightenedWarm;
currentCold = brightenedCold;
- analogWrite(redPin, currentRed);
- analogWrite(greenPin, currentGreen);
- analogWrite(bluePin, currentBlue);
- analogWrite(warmPin, currentWarm);
- analogWrite(coldPin, currentCold);
+ ledcWrite(redChannel, currentRed);
+ ledcWrite(greenChannel, currentGreen);
+ ledcWrite(blueChannel, currentBlue);
+ ledcWrite(warmChannel, currentWarm);
+ ledcWrite(coldChannel, currentCold);
}
-//Helper functions to allow changes colors by using a string or integer hex code
-void tweenToColor(COLOR targetcolor) {
+// Helper functions to allow changes colors by using a string or integer hex code
+void tweenToColor(COLOR targetcolor)
+{
tweenToColor(targetcolor.r, targetcolor.g, targetcolor.b, targetcolor.ww, targetcolor.cw);
}
-//Example: tweenToColor("#33FD67")
-void tweenToColor(String strTargetColor, short ww_value = 0, short cw_value = 0) {
+// Example: tweenToColor("#33FD67")
+void tweenToColor(String strTargetColor, short ww_value = 0, short cw_value = 0)
+{
COLOR targetcolor;
targetcolor = hex2rgb(strTargetColor, ww_value, cw_value);
tweenToColor(targetcolor.r, targetcolor.g, targetcolor.b, targetcolor.ww, targetcolor.cw);
}
-//Example: tweenToColor(0xFFACA5)
-void tweenToColor(int hexValue, short ww_value = 0, short cw_value = 0) {
+// Example: tweenToColor(0xFFACA5)
+void tweenToColor(int hexValue, short ww_value = 0, short cw_value = 0)
+{
COLOR targetcolor;
targetcolor.r = ((hexValue >> 16) & 0xFF) / 255.0;
targetcolor.g = ((hexValue >> 8) & 0xFF) / 255.0;
@@ -126,32 +145,38 @@ void tweenToColor(int hexValue, short ww_value = 0, short cw_value = 0) {
float hue = 0.0;
-void RGBCycle() {
- if (printerConfig.discoMode == false) {
- //Skip changing colors if RGB Mode not enabled
+void RGBCycle()
+{
+ if (printerConfig.discoMode == false)
+ {
+ // Skip changing colors if RGB Mode not enabled
printerConfig.discoMode_update = true;
return;
}
- if(printerConfig.discoMode_update){
+ if (printerConfig.discoMode_update)
+ {
printerConfig.discoMode_update = false;
- if (printerConfig.debugingchange){
- Serial.print(F("["));
- Serial.print(millis());
- Serial.print(F("]"));
- Serial.println(F(" ** RGB Cycle Mode **"));
+ if (printerConfig.debugingchange)
+ {
+ LogSerial.print(F("["));
+ LogSerial.print(millis());
+ LogSerial.print(F("]"));
+ LogSerial.println(F(" ** RGB Cycle Mode **"));
};
}
- if (printerVariables.online == false) {
- analogWrite(redPin, 0);
- analogWrite(greenPin, 0);
- analogWrite(bluePin, 0);
- analogWrite(warmPin, 0);
- analogWrite(coldPin, 0);
+ if (printerVariables.online == false)
+ {
+ ledcWrite(redChannel, 0);
+ ledcWrite(greenChannel, 0);
+ ledcWrite(blueChannel, 0);
+ ledcWrite(warmChannel, 0);
+ ledcWrite(coldChannel, 0);
return;
}
hue += 0.1;
- if (hue > 360.0) {
+ if (hue > 360.0)
+ {
hue = 0.0;
}
@@ -161,38 +186,42 @@ void RGBCycle() {
currentWarm = 0;
currentCold = 0;
- //Need to add code so it adjusts to set brightness level
+ // Need to add code so it adjusts to set brightness level
- analogWrite(redPin, currentRed);
- analogWrite(greenPin, currentGreen);
- analogWrite(bluePin, currentBlue);
- analogWrite(warmPin, currentWarm);
- analogWrite(coldPin, currentCold);
+ ledcWrite(redChannel, currentRed);
+ ledcWrite(greenChannel, currentGreen);
+ ledcWrite(blueChannel, currentBlue);
+ ledcWrite(warmChannel, currentWarm);
+ ledcWrite(coldChannel, currentCold);
}
-void printLogs(String Desc, COLOR thisColor){
- if (printerConfig.debuging || printerConfig.debugingchange){
- Serial.print(Desc);
- Serial.print(F(" - Turning LEDs to: "));
- if((thisColor.r + thisColor.g + thisColor.b + thisColor.ww + thisColor.cw) == 0){
- Serial.println(F(" OFF"));
+void printLogs(String Desc, COLOR thisColor)
+{
+ if (printerConfig.debuging || printerConfig.debugingchange)
+ {
+ LogSerial.print(Desc);
+ LogSerial.print(F(" - Turning LEDs to: "));
+ if ((thisColor.r + thisColor.g + thisColor.b + thisColor.ww + thisColor.cw) == 0)
+ {
+ LogSerial.println(F(" OFF"));
return;
}
- Serial.print(F(" r:"));
- Serial.print(thisColor.r);
- Serial.print(F(" g:"));
- Serial.print(thisColor.g);
- Serial.print(F(" b:"));
- Serial.print(thisColor.b);
- Serial.print(F(" ww:"));
- Serial.print(thisColor.ww);
- Serial.print(F(" cw:"));
- Serial.print(thisColor.cw);
- Serial.print(F(" Brightness: "));
- Serial.println(printerConfig.brightness);
+ LogSerial.print(F(" r:"));
+ LogSerial.print(thisColor.r);
+ LogSerial.print(F(" g:"));
+ LogSerial.print(thisColor.g);
+ LogSerial.print(F(" b:"));
+ LogSerial.print(thisColor.b);
+ LogSerial.print(F(" ww:"));
+ LogSerial.print(thisColor.ww);
+ LogSerial.print(F(" cw:"));
+ LogSerial.print(thisColor.cw);
+ LogSerial.print(F(" Brightness: "));
+ LogSerial.println(printerConfig.brightness);
};
}
-void printLogs(String Desc, short r, short g, short b, short ww, short cw){
+void printLogs(String Desc, short r, short g, short b, short ww, short cw)
+{
COLOR tempColor;
tempColor.r = r;
tempColor.g = g;
@@ -201,359 +230,414 @@ void printLogs(String Desc, short r, short g, short b, short ww, short cw){
tempColor.cw = cw;
printLogs(Desc, tempColor);
}
-void updateleds(){
- //Maintenance Mode - White lights on regardless of printer power, WiFi or MQTT connection
- //priortised over Wifi Strength Display or Custom TEST color
- if (printerConfig.maintMode && printerConfig.maintMode_update){
- tweenToColor(0,0,0,255,255); //WHITE
+void updateleds()
+{
+ // Maintenance Mode - White lights on regardless of printer power, WiFi or MQTT connection
+ // priortised over Wifi Strength Display or Custom TEST color
+ if (printerConfig.maintMode && printerConfig.maintMode_update)
+ {
+ tweenToColor(0, 0, 0, 255, 255); // WHITE
printerConfig.maintMode_update = false;
- printLogs("Maintenance Mode", 0,0,0,255,255);
- Serial.print(F("["));
- Serial.print(millis());
- Serial.print(F("]"));
- Serial.println(F(" ** Maintenance Mode **"));
+ printLogs("Maintenance Mode", 0, 0, 0, 255, 255);
+ LogSerial.print(F("["));
+ LogSerial.print(millis());
+ LogSerial.print(F("]"));
+ LogSerial.println(F(" ** Maintenance Mode **"));
return;
}
- //Use LED to show WIFI Strength (enabled via Setup Webpage)
- if (printerConfig.debugwifi){
+ // Use LED to show WIFI Strength (enabled via Setup Webpage)
+ if (printerConfig.debugwifi)
+ {
//<=-50 dBm Green, <= -60 dBm LightGreen, <= -70 dBm Yellow, <= -80 dBm Orange, >80 Red
- if (WiFi.status() == WL_CONNECTED){
+ if (WiFi.status() == WL_CONNECTED)
+ {
long wifiNow = WiFi.RSSI();
- if (printerConfig.debugingchange){
- Serial.print(F("WiFi Strength Visialisation, display LEDs for: "));
- Serial.println(wifiNow);
+ if (printerConfig.debugingchange)
+ {
+ LogSerial.print(F("WiFi Strength Visialisation, display LEDs for: "));
+ LogSerial.println(wifiNow);
}
- if (wifiNow >= -50) tweenToColor(0,255,0,0,0); //GREEN
- else if (wifiNow >= -60) tweenToColor(128,255,0,0,0); //LIGHTGREEN
- else if (wifiNow >= -70) tweenToColor(255,255,0,0,0); //YELLOW
- else if (wifiNow >= -80) tweenToColor(255,128,0,0,0); //ORANGE
- else if (wifiNow < -80) tweenToColor(255,0,0,0,0); //RED
- else tweenToColor(0,0,255,0,0); //BLUE
+ if (wifiNow >= -50)
+ tweenToColor(0, 255, 0, 0, 0); // GREEN
+ else if (wifiNow >= -60)
+ tweenToColor(128, 255, 0, 0, 0); // LIGHTGREEN
+ else if (wifiNow >= -70)
+ tweenToColor(255, 255, 0, 0, 0); // YELLOW
+ else if (wifiNow >= -80)
+ tweenToColor(255, 128, 0, 0, 0); // ORANGE
+ else if (wifiNow < -80)
+ tweenToColor(255, 0, 0, 0, 0); // RED
+ else
+ tweenToColor(0, 0, 255, 0, 0); // BLUE
};
return;
}
- //TEST Color Enabled - LED ON regardless of printer state
- if (printerConfig.testcolorEnabled && printerConfig.testcolor_update){
- tweenToColor(printerConfig.testColor); //Variable Test Color
+ // TEST Color Enabled - LED ON regardless of printer state
+ if (printerConfig.testcolorEnabled && printerConfig.testcolor_update)
+ {
+ tweenToColor(printerConfig.testColor); // Variable Test Color
printLogs("LED Test ON", printerConfig.testColor);
- Serial.print(F("["));
- Serial.print(millis());
- Serial.print(F("]"));
- Serial.println(F(" ** Test Color Mode **"));
+ LogSerial.print(F("["));
+ LogSerial.print(millis());
+ LogSerial.print(F("]"));
+ LogSerial.println(F(" ** Test Color Mode **"));
printerConfig.testcolor_update = false;
return;
}
- //From here the BBLP status sets the colors
- if (printerConfig.debuging == true){
- Serial.println(F("Updating LEDs"));
+ // From here the BBLP status sets the colors
+ if (printerConfig.debuging == true)
+ {
+ LogSerial.println(F("Updating LEDs"));
- Serial.println(printerVariables.stage);
- Serial.println(printerVariables.gcodeState);
- Serial.println(printerVariables.printerledstate);
- Serial.println(printerVariables.hmsstate);
- Serial.println(printerVariables.parsedHMSlevel);
+ LogSerial.println(printerVariables.stage);
+ LogSerial.println(printerVariables.gcodeState);
+ LogSerial.println(printerVariables.printerledstate);
+ LogSerial.println(printerVariables.hmsstate);
+ LogSerial.println(printerVariables.parsedHMSlevel);
}
- //Initial Boot
- if (printerVariables.initalisedLEDs == false) {
- printerVariables.initalisedLEDs = true; //Run once per boot
- printerConfig.inactivityStartms = millis(); //restart idle timer
+ // Initial Boot
+ if (printerVariables.initalisedLEDs == false)
+ {
+ printerVariables.initalisedLEDs = true; // Run once per boot
+ printerConfig.inactivityStartms = millis(); // restart idle timer
printerConfig.isIdleOFFActive = false;
printerVariables.waitingForDoor = false;
printerConfig.finish_check = false;
printerVariables.lastdoorClosems = millis();
- Serial.println(F("Initial Boot"));
+ LogSerial.println(F("Initial Boot"));
return;
}
- if(printerConfig.testcolorEnabled || printerConfig.maintMode || printerConfig.debugwifi || printerConfig.discoMode){
- //Skip trying to set a color as it's in one of the override states
+ if (printerConfig.testcolorEnabled || printerConfig.maintMode || printerConfig.debugwifi || printerConfig.discoMode)
+ {
+ // Skip trying to set a color as it's in one of the override states
return;
}
- //TOGGLE LIGHTS via DOOR
- //If door is closed twice in 6 seconds, it will flip the state of the lights
- if (printerVariables.doorSwitchTriggered == true){
- if (printerConfig.debugingchange){
- Serial.print(F("Door closed twice within 6 seconds - Toggling LEDs to "));
+ // TOGGLE LIGHTS via DOOR
+ // If door is closed twice in 6 seconds, it will flip the state of the lights
+ if (printerVariables.doorSwitchTriggered == true)
+ {
+ if (printerConfig.debugingchange)
+ {
+ LogSerial.print(F("Door closed twice within 6 seconds - Toggling LEDs to "));
}
- if(currentWarm == 0 && currentCold == 0)
+ if (currentWarm == 0 && currentCold == 0)
{
- tweenToColor(0,0,0,255,255); //WHITE
- if (printerConfig.debuging || printerConfig.debugingchange) {
- Serial.println(F("ON"));
+ tweenToColor(0, 0, 0, 255, 255); // WHITE
+ if (printerConfig.debuging || printerConfig.debugingchange)
+ {
+ LogSerial.println(F("ON"));
}
printerConfig.isIdleOFFActive = false;
}
else
{
- tweenToColor(0,0,0,0,0); //OFF
- //Shortcut to idle state - note: light will go back on immediately if there is an MQTT change of any sort
+ tweenToColor(0, 0, 0, 0, 0); // OFF
+ // Shortcut to idle state - note: light will go back on immediately if there is an MQTT change of any sort
printerConfig.isIdleOFFActive = true;
- printerConfig.inactivityStartms = (millis()-printerConfig.inactivityTimeOut);
- if (printerConfig.debuging || printerConfig.debugingchange) {
- Serial.println(F("OFF"));
+ printerConfig.inactivityStartms = (millis() - printerConfig.inactivityTimeOut);
+ if (printerConfig.debuging || printerConfig.debugingchange)
+ {
+ LogSerial.println(F("OFF"));
}
}
printerVariables.doorSwitchTriggered = false;
return;
}
-
- //RED -- RED -- RED -- RED
+
+ // RED -- RED -- RED -- RED
// allow errordetection to turn ledstrip red
- if (printerConfig.errordetection == true){
+ if (printerConfig.errordetection == true)
+ {
- //Fillament runout
- if (printerVariables.stage == 6 || printerVariables.overridestage == 6){
- tweenToColor(printerConfig.filamentRunoutRGB); //Customisable - Default is RED
+ // Fillament runout
+ if (printerVariables.stage == 6 || printerVariables.overridestage == 6)
+ {
+ tweenToColor(printerConfig.filamentRunoutRGB); // Customisable - Default is RED
printLogs("Stage 6, FILAMENT RUNOUT", printerConfig.filamentRunoutRGB);
return;
};
- //Front Cover Removed
- if (printerVariables.stage == 17 || printerVariables.overridestage == 17){
- tweenToColor(printerConfig.frontCoverRGB); //Customisable - Default is RED
+ // Front Cover Removed
+ if (printerVariables.stage == 17 || printerVariables.overridestage == 17)
+ {
+ tweenToColor(printerConfig.frontCoverRGB); // Customisable - Default is RED
printLogs("Stage 17, FRONT COVER REMOVED", printerConfig.frontCoverRGB);
return;
};
- //Nozzle Temp fail
- if (printerVariables.stage == 20 || printerVariables.overridestage == 20){
- tweenToColor(printerConfig.nozzleTempRGB); //Customisable - Default is RED
+ // Nozzle Temp fail
+ if (printerVariables.stage == 20 || printerVariables.overridestage == 20)
+ {
+ tweenToColor(printerConfig.nozzleTempRGB); // Customisable - Default is RED
printLogs("Stage 20, NOZZLE TEMP FAIL", printerConfig.nozzleTempRGB);
return;
};
- //Bed Temp Fail
- if (printerVariables.stage == 21 || printerVariables.overridestage == 21){
- tweenToColor(printerConfig.bedTempRGB); //Customisable - Default is RED
+ // Bed Temp Fail
+ if (printerVariables.stage == 21 || printerVariables.overridestage == 21)
+ {
+ tweenToColor(printerConfig.bedTempRGB); // Customisable - Default is RED
printLogs("Stage 21, BED TEMP FAIL", printerConfig.bedTempRGB);
return;
};
- //SERIOUS HMS state
- if (printerVariables.parsedHMSlevel == "Serious"){
- tweenToColor(printerConfig.hmsSeriousRGB); //Customisable - Default is RED
- Serial.print(F("HMS SERIOUS Severity "));
- Serial.print(F("Error Code: "));
- Serial.printf("%016llX\n", printerVariables.parsedHMScode);
+ // SERIOUS HMS state
+ if (printerVariables.parsedHMSlevel == "Serious")
+ {
+ tweenToColor(printerConfig.hmsSeriousRGB); // Customisable - Default is RED
+ LogSerial.print(F("HMS SERIOUS Severity "));
+ LogSerial.print(F("Error Code: "));
+ LogSerial.printf("%016llX\n", printerVariables.parsedHMScode);
printLogs("PROBLEM", printerConfig.hmsSeriousRGB);
return;
};
- //FATAL HMS state
- if (printerVariables.parsedHMSlevel == "Fatal"){
- tweenToColor(printerConfig.hmsFatalRGB); //Customisable - Default is RED
- Serial.print(F("HMS FATAL Severity "));
- Serial.print(F("Error Code: "));
- Serial.printf("%016llX\n", printerVariables.parsedHMScode);
+ // FATAL HMS state
+ if (printerVariables.parsedHMSlevel == "Fatal")
+ {
+ tweenToColor(printerConfig.hmsFatalRGB); // Customisable - Default is RED
+ LogSerial.print(F("HMS FATAL Severity "));
+ LogSerial.print(F("Error Code: "));
+ LogSerial.printf("%016llX\n", printerVariables.parsedHMScode);
printLogs("PROBLEM", printerConfig.hmsFatalRGB);
return;
};
};
- //BLUE -- BLUE -- BLUE -- BLUE
-
+ // BLUE -- BLUE -- BLUE -- BLUE
+
// Pause (by user or via Gcode)
- if ((printerVariables.stage == 16 || printerVariables.stage == 30) || printerVariables.gcodeState == "PAUSE"){
- tweenToColor(printerConfig.pauseRGB); //Customisable - Default is BLUE
+ if ((printerVariables.stage == 16 || printerVariables.stage == 30) || printerVariables.gcodeState == "PAUSE")
+ {
+ tweenToColor(printerConfig.pauseRGB); // Customisable - Default is BLUE
printLogs("Stage 16, gcodeState pause, PAUSED", printerConfig.pauseRGB);
return;
}
- //First Layer Error PAUSED
- if (printerVariables.stage == 34){
- tweenToColor(printerConfig.firstlayerRGB); //Customisable - Default is BLUE
+ // First Layer Error PAUSED
+ if (printerVariables.stage == 34)
+ {
+ tweenToColor(printerConfig.firstlayerRGB); // Customisable - Default is BLUE
printLogs("Stage 34, FIRST LAYER ERROR, PAUSED", printerConfig.firstlayerRGB);
return;
}
- //Nozzle Clog PAUSED
- if (printerVariables.stage == 35){
- tweenToColor(printerConfig.nozzleclogRGB); //Customisable - Default is BLUE
+ // Nozzle Clog PAUSED
+ if (printerVariables.stage == 35)
+ {
+ tweenToColor(printerConfig.nozzleclogRGB); // Customisable - Default is BLUE
printLogs("Stage 35, NOZZLE CLOG, PAUSED", printerConfig.nozzleclogRGB);
return;
}
- //OFF -- OFF -- OFF -- OFF
+ // OFF -- OFF -- OFF -- OFF
- //printer offline and MQTT disconnect more than 5 seconds.
- if (printerVariables.online == false && (millis() - printerVariables.disconnectMQTTms) >= 5000){
- tweenToColor(0,0,0,0,0); //OFF
- printLogs("Printer offline", 0,0,0,0,0);
+ // printer offline and MQTT disconnect more than 5 seconds.
+ if (printerVariables.online == false && (millis() - printerVariables.disconnectMQTTms) >= 5000)
+ {
+ tweenToColor(0, 0, 0, 0, 0); // OFF
+ printLogs("Printer offline", 0, 0, 0, 0, 0);
return;
}
// replicate printer behaviour OFF
- if (printerConfig.replicatestate && printerConfig.replicate_update && printerVariables.printerledstate == false){
- tweenToColor(0,0,0,0,0); //OFF
- printLogs("LED Replication OFF", 0,0,0,0,0);
+ if (printerConfig.replicatestate && printerConfig.replicate_update && printerVariables.printerledstate == false)
+ {
+ tweenToColor(0, 0, 0, 0, 0); // OFF
+ printLogs("LED Replication OFF", 0, 0, 0, 0, 0);
printerConfig.replicate_update = false;
return;
}
- //Cleaning nozzle
- if (printerVariables.stage == 14){
- tweenToColor(printerConfig.stage14Color); //Customisable - Default is OFF
+ // Cleaning nozzle
+ if (printerVariables.stage == 14)
+ {
+ tweenToColor(printerConfig.stage14Color); // Customisable - Default is OFF
printLogs("Stage 14, CLEANING NOZZLE", printerConfig.stage14Color);
return;
}
- //Auto Bed Leveling
- if (printerVariables.stage == 1){
- tweenToColor(printerConfig.stage1Color); //Customisable - Default is OFF
+ // Auto Bed Leveling
+ if (printerVariables.stage == 1)
+ {
+ tweenToColor(printerConfig.stage1Color); // Customisable - Default is OFF
printLogs("Stage 1, BED LEVELING", printerConfig.stage1Color);
return;
}
- //Calibrating Extrusion
- if (printerVariables.stage == 8){
- tweenToColor(printerConfig.stage8Color); //Customisable - Default is OFF
+ // Calibrating Extrusion
+ if (printerVariables.stage == 8)
+ {
+ tweenToColor(printerConfig.stage8Color); // Customisable - Default is OFF
printLogs("Stage 8, CALIBRATING EXTRUSION", printerConfig.stage8Color);
return;
}
- //Scaning surface
- if (printerVariables.stage == 9){
- tweenToColor(printerConfig.stage9Color); //Customisable - Default is OFF
+ // Scaning surface
+ if (printerVariables.stage == 9)
+ {
+ tweenToColor(printerConfig.stage9Color); // Customisable - Default is OFF
printLogs("Stage 9, SCANNING BED SURFACE", printerConfig.stage9Color);
return;
}
- //Inspecting First Layer
- if (printerVariables.stage == 10 || printerVariables.overridestage == 10){
- tweenToColor(printerConfig.stage10Color); //Customisable - Default is OFF
+ // Inspecting First Layer
+ if (printerVariables.stage == 10 || printerVariables.overridestage == 10)
+ {
+ tweenToColor(printerConfig.stage10Color); // Customisable - Default is OFF
printLogs("Stage 10 / HMS 0C00, FIRST LAYER INSPECTION", printerConfig.stage10Color);
return;
}
- //Calibrating MicroLidar
- if (printerVariables.stage == 12){
- tweenToColor(printerConfig.stage10Color);
+ // Calibrating MicroLidar
+ if (printerVariables.stage == 12)
+ {
+ tweenToColor(printerConfig.stage10Color);
printLogs("Stage 12, CALIBRATING MICRO LIDAR", printerConfig.stage10Color);
return;
}
// Idle Timeout (Has to be enabled)
- if ((printerVariables.stage == -1 || printerVariables.stage == 255)
- && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut)))
- && (millis() - printerConfig.inactivityStartms) > printerConfig.inactivityTimeOut
- && printerConfig.isIdleOFFActive == false
- && printerConfig.inactivityEnabled){
- tweenToColor(0,0,0,0,0); //OFF
+ if ((printerVariables.stage == -1 || printerVariables.stage == 255) && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut))) && (millis() - printerConfig.inactivityStartms) > printerConfig.inactivityTimeOut && printerConfig.isIdleOFFActive == false && printerConfig.inactivityEnabled)
+ {
+ tweenToColor(0, 0, 0, 0, 0); // OFF
printerConfig.isIdleOFFActive = true;
- if (printerConfig.debuging || printerConfig.debugingchange){
- Serial.print(F("Idle Timeout ["));
- Serial.print((int)(printerConfig.inactivityTimeOut / 60000));
- Serial.println(F(" mins] - Turning LEDs OFF"));
+ if (printerConfig.debuging || printerConfig.debugingchange)
+ {
+ LogSerial.print(F("Idle Timeout ["));
+ LogSerial.print((int)(printerConfig.inactivityTimeOut / 60000));
+ LogSerial.println(F(" mins] - Turning LEDs OFF"));
};
return;
}
- //ON -- ON -- ON -- ON
+ // ON -- ON -- ON -- ON
- //Preheating Bed
- if (printerVariables.stage == 2){
- tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE
+ // Preheating Bed
+ if (printerVariables.stage == 2)
+ {
+ tweenToColor(printerConfig.runningColor); // Customisable - Default is WHITE
printLogs("Stage 2, PREHEATING BED", printerConfig.runningColor);
return;
}
- //Printing or Resume after Pausing
- if (printerVariables.stage == 0 && printerVariables.gcodeState == "RUNNING"){
- tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE
+ // Printing or Resume after Pausing
+ if (printerVariables.stage == 0 && printerVariables.gcodeState == "RUNNING")
+ {
+ tweenToColor(printerConfig.runningColor); // Customisable - Default is WHITE
printLogs("Stage 0, PRINTING - gcodeState RUNNING", printerConfig.runningColor);
return;
}
- //for IDLE - P1 uses 255, X1 uses -1
- if ((printerVariables.stage == -1 || printerVariables.stage == 255)
- && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut)))
- && (millis() - printerConfig.inactivityStartms < printerConfig.inactivityTimeOut)){
- tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE
+ // for IDLE - P1 uses 255, X1 uses -1
+ if ((printerVariables.stage == -1 || printerVariables.stage == 255) && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut))) && (millis() - printerConfig.inactivityStartms < printerConfig.inactivityTimeOut))
+ {
+ tweenToColor(printerConfig.runningColor); // Customisable - Default is WHITE
printLogs("Stage -1/255, IDLE", printerConfig.runningColor);
return;
}
- //User Cancelled Print
- if (printerVariables.gcodeState == "FAILED"){
- tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE
+ // User Cancelled Print
+ if (printerVariables.gcodeState == "FAILED")
+ {
+ tweenToColor(printerConfig.runningColor); // Customisable - Default is WHITE
printLogs("Stage -1/255, FAILED", printerConfig.runningColor);
return;
}
- //Print file just sent
- if (printerVariables.gcodeState == "PREPARE"){
- tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE
+ // Print file just sent
+ if (printerVariables.gcodeState == "PREPARE")
+ {
+ tweenToColor(printerConfig.runningColor); // Customisable - Default is WHITE
printLogs("Stage -1/255, PREPARE", printerConfig.runningColor);
return;
}
- //Homing ToolHead
- if (printerVariables.stage == 13){
- //No color change assigned
- Serial.println(F("STAGE 13, HOMING TOOL HEAD"));
+ // Homing ToolHead
+ if (printerVariables.stage == 13)
+ {
+ // No color change assigned
+ LogSerial.println(F("STAGE 13, HOMING TOOL HEAD"));
return;
}
- //Offline
- if (printerVariables.gcodeState == "OFFLINE" || printerVariables.stage == -2){
- tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE
+ // Offline
+ if (printerVariables.gcodeState == "OFFLINE" || printerVariables.stage == -2)
+ {
+ tweenToColor(printerConfig.runningColor); // Customisable - Default is WHITE
printLogs("Stage -1/255, OFFLINE", printerConfig.runningColor);
return;
}
- //GREEN -- GREEN -- GREEN -- GREEN
+ // GREEN -- GREEN -- GREEN -- GREEN
- //Sets to green when print finishes AND user wants Finish Indication enabled
- if (printerVariables.finished == true && printerConfig.finishindication == true){
- tweenToColor(printerConfig.finishColor); //Customisable - Default is GREEN
+ // Sets to green when print finishes AND user wants Finish Indication enabled
+ if (printerVariables.finished == true && printerConfig.finishindication == true)
+ {
+ tweenToColor(printerConfig.finishColor); // Customisable - Default is GREEN
printLogs("Finished print", printerConfig.finishColor);
printerVariables.finished = false;
return;
}
// replicate printer behaviour ON
- if (printerConfig.replicatestate && printerConfig.replicate_update && printerVariables.printerledstate
- && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut)))){
- tweenToColor(printerConfig.runningColor); //Customisable - Default is WHITE
+ if (printerConfig.replicatestate && printerConfig.replicate_update && printerVariables.printerledstate && !((printerConfig.finishExit && printerVariables.waitingForDoor) || (printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) < printerConfig.finishTimeOut))))
+ {
+ tweenToColor(printerConfig.runningColor); // Customisable - Default is WHITE
printLogs("LED Replication ON", printerConfig.runningColor);
printerConfig.replicate_update = false;
return;
}
}
-
-void setupLeds() {
- Serial.println(F("Updating from setupleds"));
- pinMode(redPin, OUTPUT);
- pinMode(greenPin, OUTPUT);
- pinMode(bluePin, OUTPUT);
- pinMode(coldPin, OUTPUT);
- pinMode(warmPin, OUTPUT);
+void setupLeds()
+{
+ LogSerial.println(F("Updating from setupleds"));
+
+ ledcSetup(redChannel, pwmFreq, pwmResolution);
+ ledcSetup(greenChannel, pwmFreq, pwmResolution);
+ ledcSetup(blueChannel, pwmFreq, pwmResolution);
+ ledcSetup(warmChannel, pwmFreq, pwmResolution);
+ ledcSetup(coldChannel, pwmFreq, pwmResolution);
+
+ ledcAttachPin(redPin, redChannel);
+ ledcAttachPin(greenPin, greenChannel);
+ ledcAttachPin(bluePin, blueChannel);
+ ledcAttachPin(warmPin, warmChannel);
+ ledcAttachPin(coldPin, coldChannel);
}
-void ledsloop(){
+void ledsloop()
+{
RGBCycle();
- if((millis() - lastUpdatems) > 30000 && (printerConfig.maintMode || printerConfig.testcolorEnabled || printerConfig.discoMode || printerConfig.debugwifi)) {
- Serial.print(F("["));
- Serial.print(millis());
- Serial.print(F("]"));
- if(printerConfig.maintMode) Serial.println(F(" Maintenance Mode - next update in 30 seconds"));
- if(printerConfig.testcolorEnabled) Serial.println(F(" Test Color - next update in 30 seconds"));
- if(printerConfig.discoMode) Serial.println(F(" RGB Cycle Mode - next update in 30 seconds"));
- if(printerConfig.debugwifi) Serial.println(F(" Wifi Debug Mode - next update in 30 seconds"));
+ if ((millis() - lastUpdatems) > 30000 && (printerConfig.maintMode || printerConfig.testcolorEnabled || printerConfig.discoMode || printerConfig.debugwifi))
+ {
+ LogSerial.print(F("["));
+ LogSerial.print(millis());
+ LogSerial.print(F("]"));
+ if (printerConfig.maintMode)
+ LogSerial.println(F(" Maintenance Mode - next update in 30 seconds"));
+ if (printerConfig.testcolorEnabled)
+ LogSerial.println(F(" Test Color - next update in 30 seconds"));
+ if (printerConfig.discoMode)
+ LogSerial.println(F(" RGB Cycle Mode - next update in 30 seconds"));
+ if (printerConfig.debugwifi)
+ LogSerial.println(F(" Wifi Debug Mode - next update in 30 seconds"));
lastUpdatems = millis();
}
// Turn off GREEN if... finished and Door OPENED or CLOSED in last 5 secs AND user wants Finish Indication enabled
// Can't use Boolean finished as printer defaults back to IDLE via MQTT
- if((printerVariables.waitingForDoor && printerConfig.finishindication && printerConfig.finishExit
- && ((millis() - printerVariables.lastdoorClosems) < 6000 || (millis() - printerVariables.lastdoorOpenms) < 6000))){
- if (printerConfig.debuging || printerConfig.debugingchange){
- Serial.println(F("Updating from finishloop after Door interaction - Starting IDLE timer"));
+ if ((printerVariables.waitingForDoor && printerConfig.finishindication && printerConfig.finishExit && ((millis() - printerVariables.lastdoorClosems) < 6000 || (millis() - printerVariables.lastdoorOpenms) < 6000)))
+ {
+ if (printerConfig.debuging || printerConfig.debugingchange)
+ {
+ LogSerial.println(F("Updating from finishloop after Door interaction - Starting IDLE timer"));
}
printerVariables.waitingForDoor = false;
printerConfig.inactivityStartms = millis();
@@ -561,10 +645,11 @@ void ledsloop(){
updateleds();
}
- if((printerConfig.finish_check && printerConfig.finishindication && printerConfig.finishExit == false
- && ((millis() - printerConfig.finishStartms) > printerConfig.finishTimeOut))){
- if (printerConfig.debuging || printerConfig.debugingchange){
- Serial.println(F("Updating from finishloop after Finish timer expired - Starting IDLE timer"));
+ if ((printerConfig.finish_check && printerConfig.finishindication && printerConfig.finishExit == false && ((millis() - printerConfig.finishStartms) > printerConfig.finishTimeOut)))
+ {
+ if (printerConfig.debuging || printerConfig.debugingchange)
+ {
+ LogSerial.println(F("Updating from finishloop after Finish timer expired - Starting IDLE timer"));
}
printerConfig.finish_check = false;
printerConfig.inactivityStartms = millis();
@@ -572,13 +657,11 @@ void ledsloop(){
updateleds();
}
- //Need an trigger action to run updateleds() so lights turn off
- //There is no change in the printer STATE, just monitoring the timer and triggering when over a threshhold
- if(printerConfig.inactivityEnabled
- && (millis() - printerConfig.inactivityStartms) > printerConfig.inactivityTimeOut
- && printerVariables.finished == false && printerConfig.isIdleOFFActive == false)
+ // Need an trigger action to run updateleds() so lights turn off
+ // There is no change in the printer STATE, just monitoring the timer and triggering when over a threshhold
+ if (printerConfig.inactivityEnabled && (millis() - printerConfig.inactivityStartms) > printerConfig.inactivityTimeOut && printerVariables.finished == false && printerConfig.isIdleOFFActive == false)
{
- //Opening or Closing the Door will turn LEDs back on and restart the timer.
+ // Opening or Closing the Door will turn LEDs back on and restart the timer.
updateleds();
}
diff --git a/src/blled/logSerial.h b/src/blled/logSerial.h
new file mode 100644
index 0000000..1ebb08c
--- /dev/null
+++ b/src/blled/logSerial.h
@@ -0,0 +1,60 @@
+#ifndef LOGSERIAL_H
+#define LOGSERIAL_H
+
+#include
+#include
+
+class AsyncWebServer;
+
+class LogSerialClass : public Stream {
+private:
+WebSerial webSerial;
+public:
+ void begin(unsigned long baud = 115200) {
+ Serial.begin(baud);
+ }
+
+ void begin(AsyncWebServer* server, unsigned long baud = 115200, size_t bufferSize = 100) {
+ Serial.begin(baud);
+ webSerial.begin(server);
+ webSerial.setBuffer(bufferSize);
+ webSerial.onMessage([](const std::string& msg) {
+ Serial.print("[WebSerial RX] ");
+ Serial.println(msg.c_str());
+ });
+ }
+
+ void onMessage(std::function cb) {
+ webSerial.onMessage(cb);
+ }
+
+ void setBuffer(size_t size) {
+ webSerial.setBuffer(size);
+ }
+
+ int available() override { return Serial.available(); }
+ int read() override { return Serial.read(); }
+ int peek() override { return Serial.peek(); }
+ void flush() override { Serial.flush(); }
+
+ size_t write(uint8_t b) override {
+ Serial.write(b);
+ webSerial.write(&b, 1);
+ return 1;
+ }
+
+ size_t write(const uint8_t* buffer, size_t size) override {
+ Serial.write(buffer, size);
+ webSerial.write(buffer, size);
+ return size;
+ }
+
+ using Print::write;
+ operator bool() { return (bool)Serial; }
+
+
+};
+
+LogSerialClass LogSerial;
+
+#endif // LOGSERIAL_H
diff --git a/src/blled/message.json b/src/blled/message.json
deleted file mode 100644
index d07b706..0000000
--- a/src/blled/message.json
+++ /dev/null
@@ -1,588 +0,0 @@
-{
- "print": {
- "3D": {
- "layer_num": 0,
- "total_layer_num": 0
- },
- "ams": {
- "ams": [
- {
- "dry_time": 0,
- "humidity": "5",
- "humidity_raw": "20",
- "id": "0",
- "info": "1001",
- "temp": "22.2",
- "tray": [
- {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": 2740,
- "cols": [
- "161616FF"
- ],
- "ctype": 0,
- "drying_temp": "0",
- "drying_time": "0",
- "id": "0",
- "nozzle_temp_max": "240",
- "nozzle_temp_min": "190",
- "remain": -1,
- "state": 11,
- "tag_uid": "0000000000000000",
- "total_len": 330000,
- "tray_color": "161616FF",
- "tray_diameter": "1.75",
- "tray_id_name": "",
- "tray_info_idx": "GFL99",
- "tray_sub_brands": "",
- "tray_type": "PLA",
- "tray_uuid": "00000000000000000000000000000000",
- "tray_weight": "0",
- "xcam_info": "000000000000000000000000"
- },
- {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": -1,
- "cols": [
- "F98C36FF"
- ],
- "ctype": 0,
- "drying_temp": "0",
- "drying_time": "0",
- "id": "1",
- "nozzle_temp_max": "240",
- "nozzle_temp_min": "190",
- "remain": -1,
- "state": 11,
- "tag_uid": "0000000000000000",
- "total_len": 330000,
- "tray_color": "F98C36FF",
- "tray_diameter": "1.75",
- "tray_id_name": "",
- "tray_info_idx": "GFL99",
- "tray_sub_brands": "",
- "tray_type": "PLA",
- "tray_uuid": "00000000000000000000000000000000",
- "tray_weight": "0",
- "xcam_info": "000000000000000000000000"
- },
- {
- "bed_temp": "35",
- "bed_temp_type": "1",
- "cali_idx": 3693,
- "cols": [
- "792B36FF"
- ],
- "ctype": 0,
- "drying_temp": "55",
- "drying_time": "8",
- "id": "2",
- "nozzle_temp_max": "230",
- "nozzle_temp_min": "190",
- "remain": 40,
- "state": 11,
- "tag_uid": "A0E4C32F00000100",
- "total_len": 330000,
- "tray_color": "792B36FF",
- "tray_diameter": "1.75",
- "tray_id_name": "A08-R2",
- "tray_info_idx": "GFA08",
- "tray_sub_brands": "PLA Sparkle",
- "tray_type": "PLA",
- "tray_uuid": "D481BCAAC6E043C8BEA355364A1CF641",
- "tray_weight": "1000",
- "xcam_info": "1027EC2CBC02E8033333333F"
- },
- {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": 208,
- "cols": [
- "F98C36FF"
- ],
- "ctype": 0,
- "drying_temp": "0",
- "drying_time": "0",
- "id": "3",
- "nozzle_temp_max": "240",
- "nozzle_temp_min": "190",
- "remain": -1,
- "state": 11,
- "tag_uid": "0000000000000000",
- "total_len": 330000,
- "tray_color": "F98C36FF",
- "tray_diameter": "1.75",
- "tray_id_name": "",
- "tray_info_idx": "GFL99",
- "tray_sub_brands": "",
- "tray_type": "PLA",
- "tray_uuid": "00000000000000000000000000000000",
- "tray_weight": "0",
- "xcam_info": "000000000000000000000000"
- }
- ]
- },
- {
- "dry_time": 0,
- "humidity": "5",
- "humidity_raw": "18",
- "id": "1",
- "info": "2003",
- "temp": "19.9",
- "tray": [
- {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": -1,
- "cols": [
- "FFFFFFFF"
- ],
- "ctype": 0,
- "drying_temp": "65",
- "drying_time": "8",
- "id": "0",
- "nozzle_temp_max": "260",
- "nozzle_temp_min": "230",
- "remain": 27,
- "state": 11,
- "tag_uid": "BA919CF000000100",
- "total_len": 330000,
- "tray_color": "FFFFFFFF",
- "tray_diameter": "1.75",
- "tray_id_name": "G02-W0",
- "tray_info_idx": "GFG02",
- "tray_sub_brands": "PETG HF",
- "tray_type": "PETG",
- "tray_uuid": "2B5A1171556548DDA48A14D87FC0C041",
- "tray_weight": "1000",
- "xcam_info": "803E803E8403E8030000803F"
- },
- {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": -1,
- "cols": [
- "87909AFF"
- ],
- "ctype": 0,
- "drying_temp": "0",
- "drying_time": "0",
- "id": "1",
- "nozzle_temp_max": "270",
- "nozzle_temp_min": "220",
- "remain": -1,
- "state": 11,
- "tag_uid": "0000000000000000",
- "total_len": 330000,
- "tray_color": "87909AFF",
- "tray_diameter": "1.75",
- "tray_id_name": "",
- "tray_info_idx": "GFG99",
- "tray_sub_brands": "",
- "tray_type": "PETG",
- "tray_uuid": "00000000000000000000000000000000",
- "tray_weight": "0",
- "xcam_info": "000000000000000000000000"
- },
- {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": -1,
- "cols": [
- "FFFFFFFF"
- ],
- "ctype": 0,
- "drying_temp": "0",
- "drying_time": "0",
- "id": "2",
- "nozzle_temp_max": "280",
- "nozzle_temp_min": "240",
- "remain": -1,
- "state": 11,
- "tag_uid": "0000000000000000",
- "total_len": 330000,
- "tray_color": "FFFFFFFF",
- "tray_diameter": "1.75",
- "tray_id_name": "",
- "tray_info_idx": "GFB99",
- "tray_sub_brands": "",
- "tray_type": "ABS",
- "tray_uuid": "00000000000000000000000000000000",
- "tray_weight": "0",
- "xcam_info": "000000000000000000000000"
- },
- {
- "bed_temp": "80",
- "bed_temp_type": "1",
- "cali_idx": -1,
- "cols": [
- "87909AFF"
- ],
- "ctype": 0,
- "drying_temp": "80",
- "drying_time": "8",
- "id": "3",
- "nozzle_temp_max": "270",
- "nozzle_temp_min": "240",
- "remain": 96,
- "state": 11,
- "tag_uid": "205F1AFF00000100",
- "total_len": 330000,
- "tray_color": "87909AFF",
- "tray_diameter": "1.75",
- "tray_id_name": "B00-D1",
- "tray_info_idx": "GFB00",
- "tray_sub_brands": "ABS",
- "tray_type": "ABS",
- "tray_uuid": "F7B057CBC44348C4B92A1971036811E1",
- "tray_weight": "1000",
- "xcam_info": "D007D007E803E8036666663F"
- }
- ]
- }
- ],
- "ams_exist_bits": "3",
- "ams_exist_bits_raw": "3",
- "cali_id": 0,
- "cali_stat": 0,
- "insert_flag": false,
- "power_on_flag": false,
- "tray_exist_bits": "ff",
- "tray_is_bbl_bits": "ff",
- "tray_now": "255",
- "tray_pre": "255",
- "tray_read_done_bits": "ff",
- "tray_reading_bits": "0",
- "tray_tar": "255",
- "unbind_ams_stat": 0,
- "version": 863
- },
- "ams_rfid_status": 0,
- "ams_status": 0,
- "ap_err": 0,
- "aux": "280100C",
- "aux_part_fan": true,
- "batch_id": 0,
- "bed_target_temper": 0,
- "bed_temper": 19,
- "big_fan1_speed": "0",
- "big_fan2_speed": "0",
- "cali_version": 0,
- "canvas_id": 0,
- "care": [
- {
- "id": "cr",
- "info": "20631064"
- },
- {
- "id": "ls",
- "info": "67F984D"
- }
- ],
- "cfg": "FCA98",
- "command": "push_status",
- "cooling_fan_speed": "0",
- "design_id": "",
- "device": {
- "bed": {
- "info": {
- "temp": 19
- },
- "state": 0
- },
- "bed_temp": 19,
- "cam": {
- "laser": {
- "cond": 253,
- "state": 0
- }
- },
- "ctc": {
- "info": {
- "temp": 21
- },
- "state": 0
- },
- "ext_tool": {
- "calib": 2,
- "low_prec": true,
- "mount": 0,
- "th_temp": 0,
- "type": ""
- },
- "extruder": {
- "info": [
- {
- "filam_bak": [
- 10
- ],
- "hnow": 0,
- "hpre": 0,
- "htar": 0,
- "id": 0,
- "info": 8,
- "snow": 65535,
- "spre": 65535,
- "star": 65535,
- "stat": 0,
- "temp": 20
- }
- ],
- "state": 1
- },
- "fan": 0,
- "laser": {
- "power": 0
- },
- "nozzle": {
- "exist": 1,
- "info": [
- {
- "diameter": 0.4,
- "id": 0,
- "tm": 0,
- "type": "HX01",
- "wear": 0
- }
- ],
- "state": 0
- },
- "plate": {
- "base": 1,
- "cali2d_id": "",
- "cur_id": "",
- "mat": 1,
- "tar_id": ""
- },
- "type": 1
- },
- "err": "0",
- "fail_reason": "0",
- "fan_gear": 0,
- "file": "",
- "force_upgrade": false,
- "fun": "11A30F9CFF",
- "gcode_file": "",
- "gcode_file_prepare_percent": "0",
- "gcode_state": "IDLE",
- "heatbreak_fan_speed": "0",
- "hms": [],
-
-
- "home_flag": -1067070056, #tΓΌr zu bin -111111100110100011001001101000
- "home_flag": -1058681448, #tΓΌr auf bin -111111000110100011001001101000
-
-
-1
----------------------------------------
--1058681448 offen
-1
----------------------------------------
--1067070056 zu
-1
-
-
- "hw_switch_state": 0,
- "info": {
- "temp": 21
- },
- "ipcam": {
- "agora_service": "disable",
- "brtc_service": "enable",
- "bs_state": 0,
- "ipcam_dev": "1",
- "ipcam_record": "enable",
- "laser_preview_res": 7,
- "mode_bits": 2,
- "resolution": "1080p",
- "rtsp_url": "disable",
- "timelapse": "disable",
- "tl_store_hpd_type": 2,
- "tl_store_path_type": 2,
- "tutk_server": "disable"
- },
- "job": {
- "cur_stage": {
- "idx": 0,
- "state": 0
- },
- "stage": []
- },
- "job_attr": 3,
- "job_id": "",
- "layer_num": 0,
- "lights_report": [
- {
- "mode": "on",
- "node": "chamber_light"
- },
- {
- "mode": "flashing",
- "node": "work_light"
- }
- ],
- "mapping": [],
- "mc_action": 0,
- "mc_err": 0,
- "mc_percent": 0,
- "mc_print_error_code": "0",
- "mc_print_stage": "1",
- "mc_print_sub_stage": 0,
- "mc_remaining_time": 0,
- "mc_stage": 1,
- "model_id": "",
- "net": {
- "conf": 16,
- "info": [
- {
- "ip": 2317877770,
- "mask": 16777215
- },
- {
- "ip": 0,
- "mask": 0
- }
- ]
- },
- "nozzle_diameter": "0.4",
- "nozzle_target_temper": 0,
- "nozzle_temper": 20,
- "nozzle_type": "hardened_steel",
- "online": {
- "ahb": true,
- "ext": false,
- "version": 6
- },
- "percent": 0,
- "plate_cnt": 0,
- "plate_id": 0,
- "plate_idx": 0,
- "prepare_per": 0,
- "print_error": 0,
- "print_gcode_action": 0,
- "print_real_action": 0,
- "print_type": "",
- "profile_id": "",
- "project_id": "",
- "queue": 0,
- "queue_est": 0,
- "queue_number": 0,
- "queue_sts": 0,
- "queue_total": 0,
- "remain_time": 0,
- "s_obj": [],
- "sdcard": true,
- "sequence_id": "2021",
- "spd_lvl": 2,
- "spd_mag": 100,
- "stat": "7A48000",
- "state": 0,
- "stg": [],
- "stg_cur": -1,
- "subtask_id": "",
- "subtask_name": "",
- "task_id": "",
- "total_layer_num": 0,
- "upgrade_state": {
- "ahb_new_version_number": "",
- "ams_new_version_number": "",
- "consistency_request": false,
- "dis_state": 0,
- "err_code": 0,
- "ext_new_version_number": "",
- "force_upgrade": false,
- "idx": 6,
- "idx2": 745459320,
- "lower_limit": "00.00.00.00",
- "message": "",
- "module": "",
- "new_version_state": 2,
- "ota_new_version_number": "",
- "progress": "0",
- "sequence_id": 0,
- "sn": "00M09B431900386",
- "status": "IDLE"
- },
- "upload": {
- "file_size": 0,
- "finish_size": 0,
- "message": "Good",
- "oss_url": "",
- "progress": 0,
- "sequence_id": "0903",
- "speed": 0,
- "status": "idle",
- "task_id": "",
- "time_remaining": 0,
- "trouble_id": ""
- },
- "ver": "20010",
- "vir_slot": [
- {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": -1,
- "cols": [
- "BCBCBCFF"
- ],
- "ctype": 0,
- "drying_temp": "0",
- "drying_time": "0",
- "id": "255",
- "nozzle_temp_max": "250",
- "nozzle_temp_min": "200",
- "remain": 0,
- "tag_uid": "0000000000000000",
- "total_len": 330000,
- "tray_color": "BCBCBCFF",
- "tray_diameter": "1.75",
- "tray_id_name": "",
- "tray_info_idx": "GFU99",
- "tray_sub_brands": "",
- "tray_type": "TPU",
- "tray_uuid": "00000000000000000000000000000000",
- "tray_weight": "0",
- "xcam_info": "000000000000000000000000"
- }
- ],
- "vt_tray": {
- "bed_temp": "0",
- "bed_temp_type": "0",
- "cali_idx": -1,
- "cols": [
- "BCBCBCFF"
- ],
- "ctype": 0,
- "drying_temp": "0",
- "drying_time": "0",
- "id": "255",
- "nozzle_temp_max": "250",
- "nozzle_temp_min": "200",
- "remain": 0,
- "tag_uid": "0000000000000000",
- "total_len": 330000,
- "tray_color": "BCBCBCFF",
- "tray_diameter": "1.75",
- "tray_id_name": "",
- "tray_info_idx": "GFU99",
- "tray_sub_brands": "",
- "tray_type": "TPU",
- "tray_uuid": "00000000000000000000000000000000",
- "tray_weight": "0",
- "xcam_info": "000000000000000000000000"
- },
- "wifi_signal": "-33dBm",
- "xcam": {
- "allow_skip_parts": false,
- "buildplate_marker_detector": true,
- "first_layer_inspector": false,
- "halt_print_sensitivity": "medium",
- "print_halt": true,
- "printing_monitor": true,
- "spaghetti_detector": true
- },
- "xcam_status": "0"
- }
-}
\ No newline at end of file
diff --git a/src/blled/mqttmanager.h b/src/blled/mqttmanager.h
index 95258b8..52659d2 100644
--- a/src/blled/mqttmanager.h
+++ b/src/blled/mqttmanager.h
@@ -24,6 +24,9 @@ AutoGrowBufferStream stream;
unsigned long mqttattempt = (millis() - 3000);
unsigned long lastMQTTupdate = millis();
+TaskHandle_t mqttTaskHandle = NULL;
+bool mqttTaskRunning = false;
+
// With a Default BLLED
// Expected information when viewing MQTT status messages
@@ -43,43 +46,43 @@ unsigned long lastMQTTupdate = millis();
void connectMqtt()
{
- if (WiFi.status() != WL_CONNECTED)
+ if (WiFi.status() != WL_CONNECTED || WiFi.getMode() != WIFI_MODE_STA)
{
// Abort MQTT connection attempt when no Wifi
return;
}
if (strlen(printerConfig.printerIP) == 0 || strlen(printerConfig.accessCode) == 0)
{
- Serial.println(F("[MQTT] Abort connect: printerIP oder accessCode wrong or empty"));
+ LogSerial.println(F("[MQTT] Abort connect: printerIP oder accessCode wrong or empty"));
return;
}
if (!mqttClient.connected() && (millis() - mqttattempt) >= 3000)
{
tweenToColor(10, 10, 10, 10, 10);
- Serial.println(F("Connecting to mqtt..."));
+ LogSerial.println(F("Connecting to mqtt..."));
if (mqttClient.connect(clientId.c_str(), "bblp", printerConfig.accessCode))
{
- Serial.print(F("MQTT connected, subscribing to MQTT Topic: "));
- Serial.println(report_topic);
+ LogSerial.print(F("MQTT connected, subscribing to MQTT Topic: "));
+ LogSerial.println(report_topic);
mqttClient.subscribe(report_topic.c_str());
printerVariables.online = true;
printerVariables.disconnectMQTTms = 0;
- // Serial.println(F("Updating LEDs from MQTT connect"));
+ // LogSerial.println(F("Updating LEDs from MQTT connect"));
// updateleds();
}
else
{
- Serial.println(F("Failed to connect with error code: "));
- Serial.print(mqttClient.state());
- Serial.print(F(" "));
+ LogSerial.println(F("Failed to connect with error code: "));
+ LogSerial.print(mqttClient.state());
+ LogSerial.print(F(" "));
ParseMQTTState(mqttClient.state());
if (mqttClient.state() == 5)
{
- delay(500);
+ //delay(500);
tweenToColor(127, 0, 0, 0, 0); // light red, indicating not authorized
- delay(500);
+ //delay(500);
mqttattempt = (millis() - 3000);
- // Serial.println(F("Restarting Device"));
+ // LogSerial.println(F("Restarting Device"));
// delay(1000);
// ESP.restart();
}
@@ -87,6 +90,46 @@ void connectMqtt()
}
}
+void mqttTask(void *parameter)
+{
+ mqttTaskRunning = true;
+
+ while (true)
+ {
+ if (WiFi.status() != WL_CONNECTED || WiFi.getMode() != WIFI_MODE_STA)
+ {
+ printerVariables.online = false;
+ vTaskDelay(pdMS_TO_TICKS(2000));
+ continue;
+ }
+
+ if (!mqttClient.connected())
+ {
+ printerVariables.online = false;
+
+ if (printerVariables.disconnectMQTTms == 0)
+ {
+ printerVariables.disconnectMQTTms = millis();
+ LogSerial.println(F("[MQTT Task] Disconnected"));
+ ParseMQTTState(mqttClient.state());
+ }
+
+ connectMqtt();
+ vTaskDelay(pdMS_TO_TICKS(32));
+ }
+ else
+ {
+ printerVariables.disconnectMQTTms = 0;
+ mqttClient.loop();
+ }
+
+ vTaskDelay(pdMS_TO_TICKS(10));
+ }
+
+ mqttTaskRunning = false;
+ vTaskDelete(NULL);
+}
+
void ParseCallback(char *topic, byte *payload, unsigned int length)
{
JsonDocument messageobject;
@@ -112,14 +155,14 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
{
if (printerConfig.debuging)
{
- Serial.println(F("Mqtt message received."));
- Serial.print(F("FreeHeap: "));
- Serial.println(ESP.getFreeHeap());
+ LogSerial.println(F("Mqtt message received."));
+ LogSerial.print(F("FreeHeap: "));
+ LogSerial.println(ESP.getFreeHeap());
}
bool Changed = false;
- if (messageobject["print"]["command"].is())
+ if (!messageobject["print"]["command"].isNull())
{
if (messageobject["print"]["command"] == "gcode_line" // gcode_line used a lot during print initialisations - Skip these
|| messageobject["print"]["command"] == "project_prepare" // 1 message per print
@@ -127,7 +170,8 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
|| messageobject["print"]["command"] == "clean_print_error" // During error (no info)
|| messageobject["print"]["command"] == "resume" // After error or pause
|| messageobject["print"]["command"] == "get_accessories" // After error or pause
- || messageobject["print"]["command"] == "prepare")
+ || messageobject["print"]["command"] == "prepare"
+ || messageobject["print"]["command"] == "extrusion_cali_get")
{ // 1 message per print
return;
}
@@ -141,30 +185,30 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
// Output Filtered MQTT message
if (printerConfig.mqttdebug)
{
- Serial.print(F("(Filtered) MQTT payload, ["));
- Serial.print(millis());
- Serial.print(F("], "));
- serializeJson(messageobject, Serial);
- Serial.println();
+ LogSerial.print(F("(Filtered) MQTT payload, ["));
+ LogSerial.print(millis());
+ LogSerial.print(F("], "));
+ serializeJson(messageobject, LogSerial);
+ LogSerial.println();
}
if (printerConfig.mqttdebug && (printerConfig.maintMode || printerConfig.testcolorEnabled || printerConfig.discoMode || printerConfig.debugwifi))
{
- Serial.print(F("MQTT Message Ignored while in "));
+ LogSerial.print(F("MQTT Message Ignored while in "));
if (printerConfig.maintMode)
- Serial.print(F("Maintenance"));
+ LogSerial.print(F("Maintenance"));
if (printerConfig.testcolorEnabled)
- Serial.print(F("Test Color"));
+ LogSerial.print(F("Test Color"));
if (printerConfig.discoMode)
- Serial.print(F("RGB Cycle"));
+ LogSerial.print(F("RGB Cycle"));
if (printerConfig.debugwifi)
- Serial.print(F("Wifi Debug"));
- Serial.println(F(" mode"));
+ LogSerial.print(F("Wifi Debug"));
+ LogSerial.println(F(" mode"));
return;
}
// Check for Door Status
- if (messageobject["print"]["home_flag"].is())
+ if (!messageobject["print"]["home_flag"].isNull())
{
// https://github.com/greghesp/ha-bambulab/blob/main/custom_components/bambu_lab/pybambu/const.py#L324
@@ -178,12 +222,12 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
printerVariables.doorOpen = doorState;
if (printerConfig.debugingchange)
- Serial.print(F("MQTT Door "));
+ LogSerial.print(F("MQTT Door "));
if (printerVariables.doorOpen)
{
printerVariables.lastdoorOpenms = millis();
if (printerConfig.debugingchange)
- Serial.println(F("Opened"));
+ LogSerial.println(F("Opened"));
}
else
{
@@ -193,14 +237,14 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
}
printerVariables.lastdoorClosems = millis();
if (printerConfig.debugingchange)
- Serial.println(F("Closed"));
+ LogSerial.println(F("Closed"));
}
Changed = true;
}
}
// Check BBLP Stage
- if (messageobject["print"]["stg_cur"].is())
+ if (!messageobject["print"]["stg_cur"].isNull())
{
if (printerVariables.stage != messageobject["print"]["stg_cur"].as())
{
@@ -208,15 +252,15 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
if (printerConfig.debugingchange || printerConfig.debuging)
{
- Serial.print(F("MQTT update - stg_cur now: "));
- Serial.println(printerVariables.stage);
+ LogSerial.print(F("MQTT update - stg_cur now: "));
+ LogSerial.println(printerVariables.stage);
}
Changed = true;
}
}
// Check BBLP GCode State
- if (messageobject["print"]["gcode_state"].is() && ((millis() - lastMQTTupdate) > 3000))
+ if (!messageobject["print"]["gcode_state"].isNull() && ((millis() - lastMQTTupdate) > 3000))
{
String mqttgcodeState = messageobject["print"]["gcode_state"].as();
@@ -240,27 +284,27 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
if (printerConfig.debugingchange || printerConfig.debuging)
{
- Serial.print(F("MQTT update - gcode_state now: "));
- Serial.println(printerVariables.gcodeState);
+ LogSerial.print(F("MQTT update - gcode_state now: "));
+ LogSerial.println(printerVariables.gcodeState);
}
Changed = true;
}
}
// Pause Command - quicker, but Only for user generated pause - error & code pauses don't trigger this.
- if (messageobject["print"]["command"].is())
+ if (!messageobject["print"]["command"].isNull())
{
if (messageobject["print"]["command"] == "pause")
{
lastMQTTupdate = millis();
- Serial.println(F("MQTT update - manual PAUSE"));
+ LogSerial.println(F("MQTT update - manual PAUSE"));
printerVariables.gcodeState = "PAUSE";
Changed = true;
}
}
// Added a delay so the slower MQTT status message doesn't reverse the "system" commands
- if (messageobject["print"]["lights_report"].is() && ((millis() - lastMQTTupdate) > 3000))
+ if (!messageobject["print"]["lights_report"].isNull() && ((millis() - lastMQTTupdate) > 3000))
{
JsonArray lightsReport = messageobject["print"]["lights_report"];
for (JsonObject light : lightsReport)
@@ -274,8 +318,8 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
printerConfig.replicate_update = true;
if (printerConfig.debugingchange || printerConfig.debuging)
{
- Serial.print(F("MQTT chamber_light now: "));
- Serial.println(printerVariables.printerledstate);
+ LogSerial.print(F("MQTT chamber_light now: "));
+ LogSerial.println(printerVariables.printerledstate);
}
if (printerVariables.waitingForDoor && printerConfig.finish_check)
{
@@ -288,7 +332,7 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
}
// System Commands are sent quicker than the push_status
// Message only sent onChange
- if (messageobject["system"]["command"].is())
+ if (!messageobject["system"]["command"].isNull())
{
if (messageobject["system"]["command"] == "ledctrl")
{
@@ -300,8 +344,8 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
lastMQTTupdate = millis();
if (printerConfig.debugingchange || printerConfig.debuging)
{
- Serial.print(F("MQTT led_mode now: "));
- Serial.println(printerVariables.printerledstate);
+ LogSerial.print(F("MQTT led_mode now: "));
+ LogSerial.println(printerVariables.printerledstate);
}
if (printerVariables.waitingForDoor && printerConfig.finish_check)
{
@@ -314,7 +358,7 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
}
// Bambu Health Management System (HMS)
- if (messageobject["print"]["hms"].is())
+ if (!messageobject["print"]["hms"].isNull())
{
String oldHMSlevel = "";
oldHMSlevel = printerVariables.parsedHMSlevel;
@@ -346,31 +390,31 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
if (printerConfig.debuging || printerConfig.debugingchange)
{
- Serial.print(F("MQTT update - parsedHMSlevel now: "));
+ LogSerial.print(F("MQTT update - parsedHMSlevel now: "));
if (printerVariables.parsedHMSlevel.length() > 0)
{
- Serial.print(printerVariables.parsedHMSlevel);
- Serial.print(F(" Error Code: "));
- // Serial.println(F("https://wiki.bambulab.com/en/x1/troubleshooting/how-to-enter-the-specific-code-page"));
+ LogSerial.print(printerVariables.parsedHMSlevel);
+ LogSerial.print(F(" Error Code: "));
+ // LogSerial.println(F("https://wiki.bambulab.com/en/x1/troubleshooting/how-to-enter-the-specific-code-page"));
int chunk1 = (printerVariables.parsedHMScode >> 48);
int chunk2 = (printerVariables.parsedHMScode >> 32) & 0xFFFF;
int chunk3 = (printerVariables.parsedHMScode >> 16) & 0xFFFF;
int chunk4 = printerVariables.parsedHMScode & 0xFFFF;
char strHMScode[20];
sprintf(strHMScode, "%04X_%04X_%04X_%04X", chunk1, chunk2, chunk3, chunk4);
- Serial.print(strHMScode);
+ LogSerial.print(strHMScode);
if (printerVariables.overridestage != printerVariables.stage)
{
- Serial.println(F(" **"));
+ LogSerial.println(F(" **"));
}
else
{
- Serial.println(F(""));
+ LogSerial.println(F(""));
}
}
else
{
- Serial.println(F("NULL"));
+ LogSerial.println(F("NULL"));
printerVariables.overridestage = 999;
}
}
@@ -384,7 +428,7 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
printerConfig.isIdleOFFActive = false;
if (printerConfig.debuging)
{
- Serial.println(F("Change from mqtt"));
+ LogSerial.println(F("Change from mqtt"));
}
printerConfig.maintMode_update = true;
printerConfig.discoMode_update = true;
@@ -396,7 +440,7 @@ void ParseCallback(char *topic, byte *payload, unsigned int length)
}
else
{
- Serial.println(F("Deserialize error while parsing mqtt"));
+ LogSerial.println(F("Deserialize error while parsing mqtt"));
return;
}
}
@@ -410,25 +454,62 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
void setupMqtt()
{
clientId += String(random(0xffff), HEX);
- Serial.print(F("Setting up MQTT with Bambu Lab Printer IP address: "));
- Serial.println(printerConfig.printerIP);
+ LogSerial.print(F("Setting up MQTT with Bambu Lab Printer IP address: "));
+ LogSerial.println(printerConfig.printerIP);
device_topic = String("device/") + printerConfig.serialNumber;
report_topic = device_topic + String("/report");
wifiSecureClient.setInsecure();
- mqttClient.setBufferSize(1024); // 1024
+ wifiSecureClient.setTimeout(3);
+ mqttClient.setSocketTimeout(3);
+ mqttClient.setBufferSize(1024);
mqttClient.setServer(printerConfig.printerIP, 8883);
mqttClient.setStream(stream);
mqttClient.setCallback(mqttCallback);
- mqttClient.setSocketTimeout(20);
- Serial.println(F("Finished setting up MQTT"));
- connectMqtt();
+
+ LogSerial.println(F("Finished setting up MQTT"));
+
+ if (mqttTaskHandle == NULL)
+ {
+ BaseType_t result;
+
+ #if CONFIG_FREERTOS_UNICORE
+ result = xTaskCreate(
+ mqttTask,
+ "mqttTask",
+ 6144,
+ NULL,
+ 1,
+ &mqttTaskHandle
+ );
+ #else
+ result = xTaskCreatePinnedToCore(
+ mqttTask,
+ "mqttTask",
+ 6144,
+ NULL,
+ 1,
+ &mqttTaskHandle,
+ 1 // Core 1 (App Core)
+ );
+ #endif
+
+ if (result == pdPASS)
+ {
+ LogSerial.println(F("MQTT task successfully started"));
+ }
+ else
+ {
+ LogSerial.println(F("Failed to create MQTT task!"));
+ }
+ }
}
+
void mqttloop()
{
- if (WiFi.status() != WL_CONNECTED)
+ if (WiFi.status() != WL_CONNECTED || WiFi.getMode() != WIFI_MODE_STA)
{
// Abort MQTT connection attempt when no Wifi
return;
@@ -441,10 +522,10 @@ void mqttloop()
{
printerVariables.disconnectMQTTms = millis();
// Record last time MQTT dropped connection
- Serial.println(F("MQTT dropped during mqttloop"));
+ LogSerial.println(F("MQTT dropped during mqttloop"));
ParseMQTTState(mqttClient.state());
}
- delay(500);
+ //delay(500);
connectMqtt();
delay(32);
return;
diff --git a/src/blled/mqttparsingutility.h b/src/blled/mqttparsingutility.h
index 1040314..ebc7d05 100644
--- a/src/blled/mqttparsingutility.h
+++ b/src/blled/mqttparsingutility.h
@@ -23,34 +23,34 @@ void ParseMQTTState(int code){
switch (code)
{
case -4: // MQTT_CONNECTION_TIMEOUT
- Serial.println(F("MQTT TIMEOUT"));
+ LogSerial.println(F("MQTT TIMEOUT"));
break;
case -3: // MQTT_CONNECTION_LOST
- Serial.println(F("MQTT CONNECTION_LOST"));
+ LogSerial.println(F("MQTT CONNECTION_LOST"));
break;
case -2: // MQTT_CONNECT_FAILED
- Serial.println(F("MQTT CONNECT_FAILED"));
+ LogSerial.println(F("MQTT CONNECT_FAILED"));
break;
case -1: // MQTT_DISCONNECTED
- Serial.println(F("MQTT DISCONNECTED"));
+ LogSerial.println(F("MQTT DISCONNECTED"));
break;
case 0: // MQTT_CONNECTED
- Serial.println(F("MQTT CONNECTED"));
+ LogSerial.println(F("MQTT CONNECTED"));
break;
case 1: // MQTT_CONNECT_BAD_PROTOCOL
- Serial.println(F("MQTT BAD PROTOCOL"));
+ LogSerial.println(F("MQTT BAD PROTOCOL"));
break;
case 2: // MQTT_CONNECT_BAD_CLIENT_ID
- Serial.println(F("MQTT BAD CLIENT ID"));
+ LogSerial.println(F("MQTT BAD CLIENT ID"));
break;
case 3: // MQTT_CONNECT_UNAVAILABLE
- Serial.println(F("MQTT UNAVAILABLE"));
+ LogSerial.println(F("MQTT UNAVAILABLE"));
break;
case 4: // MQTT_CONNECT_BAD_CREDENTIALS
- Serial.println(F("MQTT BAD CREDENTIALS"));
+ LogSerial.println(F("MQTT BAD CREDENTIALS"));
break;
case 5: // MQTT UNAUTHORIZED
- Serial.println(F("MQTT UNAUTHORIZED"));
+ LogSerial.println(F("MQTT UNAUTHORIZED"));
break;
}
}
diff --git a/src/blled/types.h b/src/blled/types.h
index 4e05e76..ec4bd72 100644
--- a/src/blled/types.h
+++ b/src/blled/types.h
@@ -54,7 +54,7 @@ extern "C"
typedef struct GlobalVariablesStruct{
char SSID[32];
- char APPW[32];
+ char APPW[64];
String FWVersion = STRVERSION;
String Host = "BLLED";
bool started = false;
diff --git a/src/blled/web-server.h b/src/blled/web-server.h
index 5affcab..df0c61c 100644
--- a/src/blled/web-server.h
+++ b/src/blled/web-server.h
@@ -14,8 +14,6 @@ AsyncWebServer webServer(80);
AsyncWebSocket ws("/ws");
#include "../www/www.h"
-#include "../www/blled_svg.h"
-#include "../www/favicon.h"
unsigned long lastWsPush = 0;
const unsigned long wsPushInterval = 1000; // alle 1000ms
@@ -207,6 +205,17 @@ void handlePrinterConfigJson(AsyncWebServerRequest *request)
request->send(200, "application/json", json);
}
+void handleStyleCss(AsyncWebServerRequest *request)
+{
+ if (!isAuthorized(request))
+ {
+ return request->requestAuthentication();
+ }
+ AsyncWebServerResponse *response = request->beginResponse(200, style_css_gz_mime, style_css_gz, style_css_gz_len);
+ response->addHeader("Content-Encoding", "gzip");
+ request->send(response);
+}
+
void handleSubmitConfig(AsyncWebServerRequest *request)
{
if (!isAuthorized(request))
@@ -214,83 +223,56 @@ void handleSubmitConfig(AsyncWebServerRequest *request)
return request->requestAuthentication();
}
- bool newBSSID = false;
- printerConfig.brightness = request->getParam("brightnessslider", true)->value().toInt();
- printerConfig.rescanWiFiNetwork = (request->hasParam("rescanWiFiNetwork", true));
- printerConfig.maintMode = (request->hasParam("maintMode", true));
- printerConfig.discoMode = (request->hasParam("discoMode", true));
- printerConfig.replicatestate = (request->hasParam("replicateLedState", true));
- printerConfig.runningColor = hex2rgb(request->getParam("runningRGB", true)->value().c_str(),
- request->getParam("runningWW", true)->value().toInt(),
- request->getParam("runningCW", true)->value().toInt());
- printerConfig.testcolorEnabled = (request->hasParam("showtestcolor", true));
- printerConfig.testColor = hex2rgb(request->getParam("testRGB", true)->value().c_str(),
- request->getParam("testWW", true)->value().toInt(),
- request->getParam("testCW", true)->value().toInt());
- printerConfig.debugwifi = (request->hasParam("debugwifi", true));
- printerConfig.finishindication = (request->hasParam("finishIndication", true));
- printerConfig.finishColor = hex2rgb(request->getParam("finishColor", true)->value().c_str(),
- request->getParam("finishWW", true)->value().toInt(),
- request->getParam("finishCW", true)->value().toInt());
- printerConfig.finishExit = !(request->hasParam("finishEndTimer", true));
- printerConfig.finishTimeOut = request->getParam("finishTimerMins", true)->value().toInt() * 60000;
- printerConfig.inactivityEnabled = (request->hasParam("inactivityEnabled", true));
- printerConfig.inactivityTimeOut = request->getParam("inactivityMins", true)->value().toInt() * 60000;
- printerConfig.debuging = (request->hasParam("debuging", true));
- printerConfig.debugingchange = (request->hasParam("debugingchange", true));
- printerConfig.mqttdebug = (request->hasParam("mqttdebug", true));
- printerVariables.isP1Printer = (request->hasParam("p1Printer", true));
- printerVariables.useDoorSwtich = (request->hasParam("doorSwitch", true));
-
- printerConfig.stage14Color = hex2rgb(request->getParam("stage14RGB", true)->value().c_str(),
- request->getParam("stage14WW", true)->value().toInt(),
- request->getParam("stage14CW", true)->value().toInt());
- printerConfig.stage1Color = hex2rgb(request->getParam("stage1RGB", true)->value().c_str(),
- request->getParam("stage1WW", true)->value().toInt(),
- request->getParam("stage1CW", true)->value().toInt());
- printerConfig.stage8Color = hex2rgb(request->getParam("stage8RGB", true)->value().c_str(),
- request->getParam("stage8WW", true)->value().toInt(),
- request->getParam("stage8CW", true)->value().toInt());
- printerConfig.stage9Color = hex2rgb(request->getParam("stage9RGB", true)->value().c_str(),
- request->getParam("stage9WW", true)->value().toInt(),
- request->getParam("stage9CW", true)->value().toInt());
- printerConfig.stage10Color = hex2rgb(request->getParam("stage10RGB", true)->value().c_str(),
- request->getParam("stage10WW", true)->value().toInt(),
- request->getParam("stage10CW", true)->value().toInt());
- printerConfig.errordetection = (request->hasParam("errorDetection", true));
- printerConfig.wifiRGB = hex2rgb(request->getParam("wifiRGB", true)->value().c_str(),
- request->getParam("wifiWW", true)->value().toInt(),
- request->getParam("wifiCW", true)->value().toInt());
- printerConfig.pauseRGB = hex2rgb(request->getParam("pauseRGB", true)->value().c_str(),
- request->getParam("pauseWW", true)->value().toInt(),
- request->getParam("pauseCW", true)->value().toInt());
- printerConfig.firstlayerRGB = hex2rgb(request->getParam("firstlayerRGB", true)->value().c_str(),
- request->getParam("firstlayerWW", true)->value().toInt(),
- request->getParam("firstlayerCW", true)->value().toInt());
- printerConfig.nozzleclogRGB = hex2rgb(request->getParam("nozzleclogRGB", true)->value().c_str(),
- request->getParam("nozzleclogWW", true)->value().toInt(),
- request->getParam("nozzleclogCW", true)->value().toInt());
- printerConfig.hmsSeriousRGB = hex2rgb(request->getParam("hmsSeriousRGB", true)->value().c_str(),
- request->getParam("hmsSeriousWW", true)->value().toInt(),
- request->getParam("hmsSeriousCW", true)->value().toInt());
- printerConfig.hmsFatalRGB = hex2rgb(request->getParam("hmsFatalRGB", true)->value().c_str(),
- request->getParam("hmsFatalWW", true)->value().toInt(),
- request->getParam("hmsFatalCW", true)->value().toInt());
- printerConfig.filamentRunoutRGB = hex2rgb(request->getParam("filamentRunoutRGB", true)->value().c_str(),
- request->getParam("filamentRunoutWW", true)->value().toInt(),
- request->getParam("filamentRunoutCW", true)->value().toInt());
- printerConfig.frontCoverRGB = hex2rgb(request->getParam("frontCoverRGB", true)->value().c_str(),
- request->getParam("frontCoverWW", true)->value().toInt(),
- request->getParam("frontCoverCW", true)->value().toInt());
- printerConfig.nozzleTempRGB = hex2rgb(request->getParam("nozzleTempRGB", true)->value().c_str(),
- request->getParam("nozzleTempWW", true)->value().toInt(),
- request->getParam("nozzleTempCW", true)->value().toInt());
- printerConfig.bedTempRGB = hex2rgb(request->getParam("bedTempRGB", true)->value().c_str(),
- request->getParam("bedTempWW", true)->value().toInt(),
- request->getParam("bedTempCW", true)->value().toInt());
+ auto getSafeParamValue = [](AsyncWebServerRequest *req, const char *name, const char *fallback = "") -> String
+ {
+ return req->hasParam(name, true) ? req->getParam(name, true)->value() : fallback;
+ };
+
+ auto getSafeParamInt = [](AsyncWebServerRequest *req, const char *name, int fallback = 0) -> int
+ {
+ return req->hasParam(name, true) ? req->getParam(name, true)->value().toInt() : fallback;
+ };
+
+ printerConfig.brightness = getSafeParamInt(request, "brightnessslider");
+ printerConfig.rescanWiFiNetwork = request->hasParam("rescanWiFiNetwork", true);
+ printerConfig.maintMode = request->hasParam("maintMode", true);
+ printerConfig.discoMode = request->hasParam("discoMode", true);
+ printerConfig.replicatestate = request->hasParam("replicateLedState", true);
+ printerConfig.runningColor = hex2rgb(getSafeParamValue(request, "runningRGB").c_str(), getSafeParamInt(request, "runningWW"), getSafeParamInt(request, "runningCW"));
+ printerConfig.testcolorEnabled = request->hasParam("showtestcolor", true);
+ printerConfig.testColor = hex2rgb(getSafeParamValue(request, "testRGB").c_str(), getSafeParamInt(request, "testWW"), getSafeParamInt(request, "testCW"));
+ printerConfig.debugwifi = request->hasParam("debugwifi", true);
+ printerConfig.finishindication = request->hasParam("finishIndication", true);
+ printerConfig.finishColor = hex2rgb(getSafeParamValue(request, "finishColor").c_str(), getSafeParamInt(request, "finishWW"), getSafeParamInt(request, "finishCW"));
+ printerConfig.finishExit = !request->hasParam("finishEndTimer", true);
+ printerConfig.finishTimeOut = getSafeParamInt(request, "finishTimerMins") * 60000;
+ printerConfig.inactivityEnabled = request->hasParam("inactivityEnabled", true);
+ printerConfig.inactivityTimeOut = getSafeParamInt(request, "inactivityMins") * 60000;
+ printerConfig.debuging = request->hasParam("debuging", true);
+ printerConfig.debugingchange = request->hasParam("debugingchange", true);
+ printerConfig.mqttdebug = request->hasParam("mqttdebug", true);
+ printerVariables.isP1Printer = request->hasParam("p1Printer", true);
+ printerVariables.useDoorSwtich = request->hasParam("doorSwitch", true);
+
+ printerConfig.stage14Color = hex2rgb(getSafeParamValue(request, "stage14RGB").c_str(), getSafeParamInt(request, "stage14WW"), getSafeParamInt(request, "stage14CW"));
+ printerConfig.stage1Color = hex2rgb(getSafeParamValue(request, "stage1RGB").c_str(), getSafeParamInt(request, "stage1WW"), getSafeParamInt(request, "stage1CW"));
+ printerConfig.stage8Color = hex2rgb(getSafeParamValue(request, "stage8RGB").c_str(), getSafeParamInt(request, "stage8WW"), getSafeParamInt(request, "stage8CW"));
+ printerConfig.stage9Color = hex2rgb(getSafeParamValue(request, "stage9RGB").c_str(), getSafeParamInt(request, "stage9WW"), getSafeParamInt(request, "stage9CW"));
+ printerConfig.stage10Color = hex2rgb(getSafeParamValue(request, "stage10RGB").c_str(), getSafeParamInt(request, "stage10WW"), getSafeParamInt(request, "stage10CW"));
+ printerConfig.errordetection = request->hasParam("errorDetection", true);
+ printerConfig.wifiRGB = hex2rgb(getSafeParamValue(request, "wifiRGB").c_str(), getSafeParamInt(request, "wifiWW"), getSafeParamInt(request, "wifiCW"));
+ printerConfig.pauseRGB = hex2rgb(getSafeParamValue(request, "pauseRGB").c_str(), getSafeParamInt(request, "pauseWW"), getSafeParamInt(request, "pauseCW"));
+ printerConfig.firstlayerRGB = hex2rgb(getSafeParamValue(request, "firstlayerRGB").c_str(), getSafeParamInt(request, "firstlayerWW"), getSafeParamInt(request, "firstlayerCW"));
+ printerConfig.nozzleclogRGB = hex2rgb(getSafeParamValue(request, "nozzleclogRGB").c_str(), getSafeParamInt(request, "nozzleclogWW"), getSafeParamInt(request, "nozzleclogCW"));
+ printerConfig.hmsSeriousRGB = hex2rgb(getSafeParamValue(request, "hmsSeriousRGB").c_str(), getSafeParamInt(request, "hmsSeriousWW"), getSafeParamInt(request, "hmsSeriousCW"));
+ printerConfig.hmsFatalRGB = hex2rgb(getSafeParamValue(request, "hmsFatalRGB").c_str(), getSafeParamInt(request, "hmsFatalWW"), getSafeParamInt(request, "hmsFatalCW"));
+ printerConfig.filamentRunoutRGB = hex2rgb(getSafeParamValue(request, "filamentRunoutRGB").c_str(), getSafeParamInt(request, "filamentRunoutWW"), getSafeParamInt(request, "filamentRunoutCW"));
+ printerConfig.frontCoverRGB = hex2rgb(getSafeParamValue(request, "frontCoverRGB").c_str(), getSafeParamInt(request, "frontCoverWW"), getSafeParamInt(request, "frontCoverCW"));
+ printerConfig.nozzleTempRGB = hex2rgb(getSafeParamValue(request, "nozzleTempRGB").c_str(), getSafeParamInt(request, "nozzleTempWW"), getSafeParamInt(request, "nozzleTempCW"));
+ printerConfig.bedTempRGB = hex2rgb(getSafeParamValue(request, "bedTempRGB").c_str(), getSafeParamInt(request, "bedTempWW"), getSafeParamInt(request, "bedTempCW"));
saveFileSystem();
- Serial.println(F("Packet received from setuppage"));
+ LogSerial.println(F("Packet received from setuppage"));
printerConfig.inactivityStartms = millis();
printerConfig.isIdleOFFActive = false;
printerConfig.replicate_update = true;
@@ -298,7 +280,7 @@ void handleSubmitConfig(AsyncWebServerRequest *request)
printerConfig.discoMode_update = true;
printerConfig.testcolor_update = true;
updateleds();
- request->redirect("/");
+ request->send(200, "text/plain", "OK");
}
void sendJsonToAll(JsonDocument &doc)
@@ -349,23 +331,23 @@ void handleSubmitWiFi(AsyncWebServerRequest *request)
if (ssid.length() > 0 && pass.length() > 0)
{
- Serial.println(F("[WiFiSetup] Updating WiFi credentials:"));
- Serial.print(F("SSID: "));
- Serial.println(ssid);
- Serial.print(F("Password: "));
- Serial.println(pass);
+ LogSerial.println(F("[WiFiSetup] Updating WiFi credentials:"));
+ LogSerial.print(F("SSID: "));
+ LogSerial.println(ssid);
+ LogSerial.print(F("Password: "));
+ LogSerial.println(pass);
strlcpy(globalVariables.SSID, ssid.c_str(), sizeof(globalVariables.SSID));
strlcpy(globalVariables.APPW, pass.c_str(), sizeof(globalVariables.APPW));
}
else
{
- Serial.println(F("[WiFiSetup] Empty SSID or PASS received β ignoring WiFi update."));
+ LogSerial.println(F("[WiFiSetup] Empty SSID or PASS received β ignoring WiFi update."));
}
}
else
{
- Serial.println(F("[WiFiSetup] No SSID or PASS provided β keeping existing WiFi credentials."));
+ LogSerial.println(F("[WiFiSetup] No SSID or PASS provided β keeping existing WiFi credentials."));
}
// Optional other fields (printerIP, printerSerial, etc.)
@@ -407,10 +389,8 @@ void websocketLoop()
doc["doorOpen"] = printerVariables.doorOpen;
doc["printerConnection"] = printerVariables.online;
doc["clients"] = ws.count();
-
+ doc["stg_cur"] = printerVariables.stage;
sendJsonToAll(doc);
-
- Serial.println(F("[WS] JSON Status Push send."));
}
}
@@ -429,14 +409,49 @@ void handleDownloadConfigFile(AsyncWebServerRequest *request)
{
return request->requestAuthentication();
}
+
if (!LittleFS.exists(configPath))
{
request->send(404, "text/plain", "Config file not found");
return;
}
- request->send(LittleFS, configPath, "application/json", true, nullptr);
+
+ File configFile = LittleFS.open(configPath, "r");
+ if (!configFile)
+ {
+ request->send(500, "text/plain", "Failed to open config file");
+ return;
+ }
+
+ JsonDocument doc;
+ DeserializationError error = deserializeJson(doc, configFile);
+ configFile.close();
+
+ if (error)
+ {
+ request->send(500, "text/plain", "Failed to parse config file");
+ return;
+ }
+
+ String jsonString;
+ serializeJsonPretty(doc, jsonString);
+
+ AsyncWebServerResponse *response = request->beginResponse(200, "application/json", jsonString);
+ response->addHeader("Content-Disposition", "attachment; filename=\"blledconfig.json\"");
+ request->send(response);
+}
+
+
+void handleWebSerialPage(AsyncWebServerRequest *request)
+{
+ if (!isAuthorized(request))
+ return request->requestAuthentication();
+ AsyncWebServerResponse *response = request->beginResponse(200, webSerialPage_html_gz_mime, webSerialPage_html_gz, webSerialPage_html_gz_len);
+ response->addHeader("Content-Encoding", "gzip");
+ request->send(response);
}
+
void handleUploadConfigFileData(AsyncWebServerRequest *request, const String &filename,
size_t index, uint8_t *data, size_t len, bool final)
{
@@ -444,7 +459,7 @@ void handleUploadConfigFileData(AsyncWebServerRequest *request, const String &fi
if (!index)
{
- Serial.println(F("[ConfigUpload] Start"));
+ LogSerial.println(F("[ConfigUpload] Start"));
uploadFile = LittleFS.open(configPath, "w");
}
if (uploadFile)
@@ -454,7 +469,7 @@ void handleUploadConfigFileData(AsyncWebServerRequest *request, const String &fi
if (final)
{
uploadFile.close();
- Serial.println(F("[ConfigUpload] Finished"));
+ LogSerial.println(F("[ConfigUpload] Finished"));
}
shouldRestart = true;
restartRequestTime = millis();
@@ -466,20 +481,21 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
switch (type)
{
case WS_EVT_CONNECT:
- Serial.printf("[WS] Client connected: %u\n", client->id());
+ LogSerial.printf("[WS] Client connected: %u\n", client->id());
+ websocketLoop();
break;
case WS_EVT_DISCONNECT:
- Serial.printf("[WS] Client disconnected: %u\n", client->id());
+ LogSerial.printf("[WS] Client disconnected: %u\n", client->id());
ws.cleanupClients();
break;
case WS_EVT_DATA:
- Serial.printf("[WS] Data received from client %u\n", client->id());
+ LogSerial.printf("[WS] Data received from client %u\n", client->id());
break;
case WS_EVT_PONG:
- Serial.printf("[WS] Pong received from %u\n", client->id());
+ LogSerial.printf("[WS] Pong received from %u\n", client->id());
break;
case WS_EVT_ERROR:
- Serial.printf("[WS] Error on connection %u\n", client->id());
+ LogSerial.printf("[WS] Error on connection %u\n", client->id());
ws.cleanupClients();
break;
}
@@ -489,38 +505,38 @@ void setupWebserver()
{
if (!MDNS.begin(globalVariables.Host.c_str()))
{
- Serial.println(F("Error setting up MDNS responder!"));
+ LogSerial.println(F("Error setting up MDNS responder!"));
while (1)
delay(500);
}
- Serial.println(F("Setting up webserver"));
+ LogSerial.println(F("Setting up webserver"));
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
if (WiFi.getMode() == WIFI_AP) {
- Serial.println(F("[WebServer] Captive Portal activ β redirect to /wifi"));
+ LogSerial.println(F("[WebServer] Captive Portal activ β redirect to /wifi"));
request->redirect("/wifi");
} else {
+ handleSetup(request);
//handleOldSetup(request);
- handleOldSetup(request);
} });
- // webServer.on("/old", HTTP_GET, handleOldSetup);
- webServer.on("/old", HTTP_GET, handleSetup);
+ webServer.on("/old", HTTP_GET, handleOldSetup);
webServer.on("/fwupdate", HTTP_GET, handleUpdatePage);
webServer.on("/getConfig", HTTP_GET, handleGetConfig);
webServer.on("/submitConfig", HTTP_POST, handleSubmitConfig);
- webServer.on("/blled.png", HTTP_GET, handleGetIcon);
+ webServer.on("/blled.svg", HTTP_GET, handleGetIcon);
webServer.on("/favicon.ico", HTTP_GET, handleGetfavicon);
webServer.on("/particleCanvas.js", HTTP_GET, handleGetPCC);
webServer.on("/config.json", HTTP_GET, handlePrinterConfigJson);
webServer.on("/wifi", HTTP_GET, handleWiFiSetupPage);
webServer.on("/wifiScan", HTTP_GET, handleWiFiScan);
webServer.on("/submitWiFi", HTTP_POST, handleSubmitWiFi);
-
+ webServer.on("/style.css", HTTP_GET, handleStyleCss);
webServer.on("/backuprestore", HTTP_GET, handleConfigPage);
webServer.on("/configfile.json", HTTP_GET, handleDownloadConfigFile);
- webServer.on("/confirestore", HTTP_POST, [](AsyncWebServerRequest *request)
+ webServer.on("/webserial", HTTP_GET, handleWebSerialPage);
+ webServer.on("/configrestore", HTTP_POST, [](AsyncWebServerRequest *request)
{
if (!isAuthorized(request)) {
return request->requestAuthentication();
@@ -532,7 +548,7 @@ void setupWebserver()
static File uploadFile;
if (!index) {
- Serial.printf("[ConfigUpload] Start: %s\n", filename.c_str());
+ LogSerial.printf("[ConfigUpload] Start: %s\n", filename.c_str());
uploadFile = LittleFS.open(configPath, "w");
}
if (uploadFile) {
@@ -540,40 +556,43 @@ void setupWebserver()
}
if (final) {
uploadFile.close();
- Serial.println(F("[ConfigUpload] Finished"));
+ LogSerial.println(F("[ConfigUpload] Finished"));
} });
webServer.on("/update", HTTP_POST, [](AsyncWebServerRequest *request)
{
request->send(200, "text/plain", "OK");
- Serial.println(F("Restarting Device"));
+ LogSerial.println(F("OTA Upload done. Marking for restart."));
shouldRestart = true;
- restartRequestTime = millis(); });
-
- webServer.onFileUpload([](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final)
- {
+ restartRequestTime = millis(); }, [](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
+ {
if (!index) {
- Serial.printf("Update: %s\n", filename.c_str());
+ LogSerial.printf("[OTA] Start: %s\n", filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) {
- Update.printError(Serial);
+ Update.printError(LogSerial);
}
}
+
if (Update.write(data, len) != len) {
- Update.printError(Serial);
+ Update.printError(LogSerial);
}
+
if (final) {
if (Update.end(true)) {
- Serial.printf("Update Success: %u\nRebooting...\n", index + len);
+ LogSerial.printf("[OTA] Success (%u bytes). Awaiting reboot...\n", index + len);
} else {
- Update.printError(Serial);
+ Update.printError(LogSerial);
}
} });
+ LogSerial.begin(&webServer);
+
ws.onEvent(onWsEvent);
webServer.addHandler(&ws);
+
webServer.begin();
- Serial.println(F("Webserver started"));
+ LogSerial.println(F("Webserver started"));
}
#endif
diff --git a/src/main.cpp b/src/main.cpp
index 50cf6ae..4ccd435 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#include
bool shouldRestart = false;
unsigned long restartRequestTime = 0;
+#include "./blled/logSerial.h"
#include "./blled/web-server.h"
#include "./blled/mqttmanager.h"
#include "./blled/filesystem.h"
@@ -14,7 +15,7 @@ int wifi_reconnect_count = 0;
void defaultcolors()
{
- Serial.println(F("Setting default customisable colors"));
+ LogSerial.println(F("Setting default customisable colors"));
printerConfig.runningColor = hex2rgb("#000000", 255, 255); // WHITE Running
printerConfig.testColor = hex2rgb("#3F3CFB"); // Violet Test
printerConfig.finishColor = hex2rgb("#00FF00"); // Green Finish
@@ -70,19 +71,21 @@ void setup()
setupWebserver();
return;
}
+ else
- if (!connectToWifi())
+ if (!connectToWifi())
{
Serial.println(F("[WiFiManager] Not connected β AP Mode"));
startAPMode();
setupWebserver();
return;
}
- Serial.println(F("[WiFiManager] connected. Starting webUI."));
- setupWebserver();
-
- tweenToColor(0, 0, 255, 0, 0); // BLUE
- setupWebserver();
+ else
+ {
+ Serial.println(F("[WiFiManager] connected. Starting webUI."));
+ tweenToColor(0, 0, 255, 0, 0); // BLUE
+ setupWebserver();
+ }
start_ssdp();
@@ -105,16 +108,15 @@ void loop()
serialLoop();
if (globalVariables.started)
{
- mqttloop();
websocketLoop();
ledsloop();
if (WiFi.status() != WL_CONNECTED)
{
- Serial.print(F("Wifi connection dropped. "));
- Serial.print(F("Wifi Status: "));
- Serial.println(wl_status_to_string(WiFi.status()));
- Serial.println(F("Attempting to reconnect to WiFi..."));
+ LogSerial.print(F("Wifi connection dropped. "));
+ LogSerial.print(F("Wifi Status: "));
+ LogSerial.println(wl_status_to_string(WiFi.status()));
+ LogSerial.println(F("Attempting to reconnect to WiFi..."));
wifi_reconnect_count += 1;
if (wifi_reconnect_count <= 2)
{
@@ -138,7 +140,7 @@ void loop()
}
if (printerConfig.rescanWiFiNetwork)
{
- Serial.println(F("Web submitted refresh of Wifi Scan (assigning Strongest AP)"));
+ LogSerial.println(F("Web submitted refresh of Wifi Scan (assigning Strongest AP)"));
tweenToColor(printerConfig.wifiRGB); // Customisable - Default is ORANGE
scanNetwork(); // Sets the MAC address for following connection attempt
printerConfig.rescanWiFiNetwork = false;
@@ -146,7 +148,7 @@ void loop()
}
if (shouldRestart && millis() - restartRequestTime > 1500)
{
- Serial.println(F("[WiFiSetup] Restarting now..."));
+ LogSerial.println(F("[WiFiSetup] Restarting now..."));
ESP.restart();
}
}
\ No newline at end of file
diff --git a/src/www/backupRestore.html b/src/www/backupRestore.html
index 2e9cb8a..c4bd36c 100644
--- a/src/www/backupRestore.html
+++ b/src/www/backupRestore.html
@@ -5,103 +5,35 @@
BLLED Config Backup
-
+
+
diff --git a/src/www/blled_svg.h b/src/www/blled_svg.h
deleted file mode 100644
index 9fc8a0d..0000000
--- a/src/www/blled_svg.h
+++ /dev/null
@@ -1,232 +0,0 @@
-#include
-//https://tomeko.net/online_tools/file_to_hex.php?lang=en
-const unsigned int BBLED_svg_len = 3626;
-const uint8_t BBLED_svg[] PROGMEM = {
-0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31,
-0x2E, 0x30, 0x22, 0x20, 0x65, 0x6E, 0x63, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x3D, 0x22, 0x55, 0x54,
-0x46, 0x2D, 0x38, 0x22, 0x20, 0x73, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x6C, 0x6F, 0x6E, 0x65, 0x3D,
-0x22, 0x6E, 0x6F, 0x22, 0x3F, 0x3E, 0x0A, 0x3C, 0x21, 0x2D, 0x2D, 0x20, 0x43, 0x72, 0x65, 0x61,
-0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x49, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70,
-0x65, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E,
-0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x29, 0x20, 0x2D, 0x2D, 0x3E,
-0x0A, 0x0A, 0x3C, 0x73, 0x76, 0x67, 0x0A, 0x20, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3D,
-0x22, 0x37, 0x33, 0x2E, 0x35, 0x38, 0x33, 0x38, 0x34, 0x37, 0x6D, 0x6D, 0x22, 0x0A, 0x20, 0x20,
-0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3D, 0x22, 0x31, 0x31, 0x38, 0x2E, 0x34, 0x35, 0x31,
-0x36, 0x31, 0x6D, 0x6D, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x76, 0x69, 0x65, 0x77, 0x42, 0x6F, 0x78,
-0x3D, 0x22, 0x30, 0x20, 0x30, 0x20, 0x37, 0x33, 0x2E, 0x35, 0x38, 0x33, 0x38, 0x34, 0x38, 0x20,
-0x31, 0x31, 0x38, 0x2E, 0x34, 0x35, 0x31, 0x36, 0x32, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x76, 0x65,
-0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x31, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x69,
-0x64, 0x3D, 0x22, 0x73, 0x76, 0x67, 0x31, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x78, 0x6D, 0x6C, 0x3A,
-0x73, 0x70, 0x61, 0x63, 0x65, 0x3D, 0x22, 0x70, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x22,
-0x0A, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x76, 0x65, 0x72,
-0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x22, 0x31, 0x2E, 0x34, 0x20, 0x28, 0x38, 0x36, 0x61, 0x38, 0x61,
-0x64, 0x37, 0x2C, 0x20, 0x32, 0x30, 0x32, 0x34, 0x2D, 0x31, 0x30, 0x2D, 0x31, 0x31, 0x29, 0x22,
-0x0A, 0x20, 0x20, 0x20, 0x73, 0x6F, 0x64, 0x69, 0x70, 0x6F, 0x64, 0x69, 0x3A, 0x64, 0x6F, 0x63,
-0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x22, 0x62, 0x6C, 0x6C, 0x65, 0x64, 0x2E, 0x73, 0x76, 0x67, 0x22,
-0x0A, 0x20, 0x20, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61,
-0x70, 0x65, 0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x69,
-0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x6E, 0x61, 0x6D, 0x65,
-0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2F, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x22,
-0x0A, 0x20, 0x20, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x73, 0x6F, 0x64, 0x69, 0x70, 0x6F,
-0x64, 0x69, 0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x73, 0x6F, 0x64, 0x69, 0x70,
-0x6F, 0x64, 0x69, 0x2E, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x66, 0x6F, 0x72, 0x67, 0x65, 0x2E,
-0x6E, 0x65, 0x74, 0x2F, 0x44, 0x54, 0x44, 0x2F, 0x73, 0x6F, 0x64, 0x69, 0x70, 0x6F, 0x64, 0x69,
-0x2D, 0x30, 0x2E, 0x64, 0x74, 0x64, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73,
-0x3D, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x33, 0x2E,
-0x6F, 0x72, 0x67, 0x2F, 0x32, 0x30, 0x30, 0x30, 0x2F, 0x73, 0x76, 0x67, 0x22, 0x0A, 0x20, 0x20,
-0x20, 0x78, 0x6D, 0x6C, 0x6E, 0x73, 0x3A, 0x73, 0x76, 0x67, 0x3D, 0x22, 0x68, 0x74, 0x74, 0x70,
-0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x77, 0x33, 0x2E, 0x6F, 0x72, 0x67, 0x2F, 0x32, 0x30,
-0x30, 0x30, 0x2F, 0x73, 0x76, 0x67, 0x22, 0x3E, 0x3C, 0x73, 0x6F, 0x64, 0x69, 0x70, 0x6F, 0x64,
-0x69, 0x3A, 0x6E, 0x61, 0x6D, 0x65, 0x64, 0x76, 0x69, 0x65, 0x77, 0x0A, 0x20, 0x20, 0x20, 0x20,
-0x20, 0x69, 0x64, 0x3D, 0x22, 0x6E, 0x61, 0x6D, 0x65, 0x64, 0x76, 0x69, 0x65, 0x77, 0x31, 0x22,
-0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x67, 0x65, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3D,
-0x22, 0x23, 0x35, 0x30, 0x35, 0x30, 0x35, 0x30, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62,
-0x6F, 0x72, 0x64, 0x65, 0x72, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3D, 0x22, 0x23, 0x65, 0x65, 0x65,
-0x65, 0x65, 0x65, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72,
-0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3D, 0x22, 0x31, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20,
-0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x73, 0x68, 0x6F, 0x77, 0x70, 0x61,
-0x67, 0x65, 0x73, 0x68, 0x61, 0x64, 0x6F, 0x77, 0x3D, 0x22, 0x30, 0x22, 0x0A, 0x20, 0x20, 0x20,
-0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x70, 0x61, 0x67, 0x65, 0x6F,
-0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3D, 0x22, 0x30, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
-0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x70, 0x61, 0x67, 0x65, 0x63, 0x68, 0x65,
-0x63, 0x6B, 0x65, 0x72, 0x62, 0x6F, 0x61, 0x72, 0x64, 0x3D, 0x22, 0x30, 0x22, 0x0A, 0x20, 0x20,
-0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x64, 0x65, 0x73, 0x6B,
-0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3D, 0x22, 0x23, 0x35, 0x30, 0x35, 0x30, 0x35, 0x30, 0x22, 0x0A,
-0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x64, 0x6F,
-0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2D, 0x75, 0x6E, 0x69, 0x74, 0x73, 0x3D, 0x22, 0x6D, 0x6D,
-0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A,
-0x7A, 0x6F, 0x6F, 0x6D, 0x3D, 0x22, 0x30, 0x2E, 0x37, 0x31, 0x38, 0x39, 0x31, 0x38, 0x33, 0x35,
-0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A,
-0x63, 0x78, 0x3D, 0x22, 0x2D, 0x33, 0x31, 0x36, 0x2E, 0x34, 0x34, 0x37, 0x36, 0x32, 0x22, 0x0A,
-0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x63, 0x79,
-0x3D, 0x22, 0x32, 0x32, 0x36, 0x2E, 0x30, 0x33, 0x34, 0x30, 0x31, 0x22, 0x0A, 0x20, 0x20, 0x20,
-0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x77, 0x69, 0x6E, 0x64, 0x6F,
-0x77, 0x2D, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3D, 0x22, 0x31, 0x39, 0x32, 0x30, 0x22, 0x0A, 0x20,
-0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x77, 0x69, 0x6E,
-0x64, 0x6F, 0x77, 0x2D, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3D, 0x22, 0x31, 0x30, 0x30, 0x39,
-0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A,
-0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2D, 0x78, 0x3D, 0x22, 0x2D, 0x38, 0x22, 0x0A, 0x20, 0x20,
-0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x77, 0x69, 0x6E, 0x64,
-0x6F, 0x77, 0x2D, 0x79, 0x3D, 0x22, 0x2D, 0x38, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69,
-0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x2D, 0x6D,
-0x61, 0x78, 0x69, 0x6D, 0x69, 0x7A, 0x65, 0x64, 0x3D, 0x22, 0x31, 0x22, 0x0A, 0x20, 0x20, 0x20,
-0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x63, 0x75, 0x72, 0x72, 0x65,
-0x6E, 0x74, 0x2D, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x3D, 0x22, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x31,
-0x22, 0x20, 0x2F, 0x3E, 0x3C, 0x64, 0x65, 0x66, 0x73, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69,
-0x64, 0x3D, 0x22, 0x64, 0x65, 0x66, 0x73, 0x31, 0x22, 0x20, 0x2F, 0x3E, 0x3C, 0x67, 0x0A, 0x20,
-0x20, 0x20, 0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x6C, 0x61, 0x62,
-0x65, 0x6C, 0x3D, 0x22, 0x45, 0x62, 0x65, 0x6E, 0x65, 0x20, 0x31, 0x22, 0x0A, 0x20, 0x20, 0x20,
-0x20, 0x20, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x3A, 0x67, 0x72, 0x6F, 0x75, 0x70,
-0x6D, 0x6F, 0x64, 0x65, 0x3D, 0x22, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x22, 0x0A, 0x20, 0x20, 0x20,
-0x20, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x31, 0x22, 0x0A, 0x20, 0x20,
-0x20, 0x20, 0x20, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x66, 0x6F, 0x72, 0x6D, 0x3D, 0x22, 0x74, 0x72,
-0x61, 0x6E, 0x73, 0x6C, 0x61, 0x74, 0x65, 0x28, 0x2D, 0x31, 0x38, 0x38, 0x2E, 0x36, 0x34, 0x36,
-0x36, 0x32, 0x2C, 0x2D, 0x38, 0x38, 0x2E, 0x35, 0x37, 0x32, 0x30, 0x30, 0x33, 0x29, 0x22, 0x3E,
-0x3C, 0x70, 0x61, 0x74, 0x68, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x79,
-0x6C, 0x65, 0x3D, 0x22, 0x66, 0x69, 0x6C, 0x6C, 0x3A, 0x23, 0x30, 0x31, 0x61, 0x37, 0x34, 0x66,
-0x3B, 0x66, 0x69, 0x6C, 0x6C, 0x2D, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3A, 0x31, 0x22,
-0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x3D, 0x22, 0x6D, 0x20, 0x32, 0x32, 0x32,
-0x2E, 0x33, 0x38, 0x33, 0x33, 0x38, 0x2C, 0x32, 0x30, 0x36, 0x2E, 0x36, 0x39, 0x34, 0x35, 0x37,
-0x20, 0x63, 0x20, 0x2D, 0x34, 0x2E, 0x31, 0x31, 0x38, 0x36, 0x36, 0x2C, 0x2D, 0x31, 0x2E, 0x31,
-0x39, 0x32, 0x30, 0x31, 0x20, 0x2D, 0x37, 0x2E, 0x34, 0x38, 0x30, 0x37, 0x38, 0x2C, 0x2D, 0x33,
-0x2E, 0x39, 0x33, 0x31, 0x31, 0x36, 0x20, 0x2D, 0x39, 0x2E, 0x31, 0x37, 0x30, 0x32, 0x32, 0x2C,
-0x2D, 0x37, 0x2E, 0x34, 0x37, 0x31, 0x30, 0x36, 0x20, 0x2D, 0x30, 0x2E, 0x35, 0x38, 0x33, 0x31,
-0x39, 0x2C, 0x2D, 0x31, 0x2E, 0x32, 0x32, 0x31, 0x39, 0x35, 0x20, 0x2D, 0x31, 0x2E, 0x30, 0x36,
-0x30, 0x33, 0x34, 0x2C, 0x2D, 0x32, 0x2E, 0x34, 0x35, 0x39, 0x31, 0x38, 0x20, 0x2D, 0x31, 0x2E,
-0x30, 0x36, 0x30, 0x33, 0x34, 0x2C, 0x2D, 0x32, 0x2E, 0x37, 0x34, 0x39, 0x33, 0x39, 0x20, 0x30,
-0x2C, 0x2D, 0x30, 0x2E, 0x33, 0x32, 0x32, 0x39, 0x31, 0x20, 0x2D, 0x30, 0x2E, 0x34, 0x37, 0x35,
-0x31, 0x39, 0x2C, 0x2D, 0x30, 0x2E, 0x36, 0x31, 0x36, 0x38, 0x31, 0x20, 0x2D, 0x31, 0x2E, 0x32,
-0x32, 0x34, 0x35, 0x38, 0x2C, 0x2D, 0x30, 0x2E, 0x37, 0x35, 0x37, 0x34, 0x20, 0x2D, 0x32, 0x2E,
-0x30, 0x33, 0x31, 0x36, 0x35, 0x2C, 0x2D, 0x30, 0x2E, 0x33, 0x38, 0x31, 0x31, 0x34, 0x20, 0x2D,
-0x32, 0x2E, 0x33, 0x30, 0x33, 0x31, 0x39, 0x2C, 0x2D, 0x31, 0x2E, 0x31, 0x34, 0x32, 0x34, 0x32,
-0x20, 0x2D, 0x32, 0x2E, 0x33, 0x30, 0x33, 0x31, 0x39, 0x2C, 0x2D, 0x36, 0x2E, 0x34, 0x35, 0x37,
-0x30, 0x39, 0x20, 0x76, 0x20, 0x2D, 0x34, 0x2E, 0x36, 0x38, 0x37, 0x34, 0x33, 0x20, 0x6C, 0x20,
-0x31, 0x36, 0x2E, 0x37, 0x39, 0x35, 0x30, 0x31, 0x2C, 0x30, 0x2E, 0x30, 0x39, 0x31, 0x36, 0x20,
-0x31, 0x36, 0x2E, 0x37, 0x39, 0x35, 0x2C, 0x30, 0x2E, 0x30, 0x39, 0x31, 0x36, 0x20, 0x2D, 0x30,
-0x2E, 0x30, 0x35, 0x35, 0x39, 0x2C, 0x34, 0x2E, 0x39, 0x32, 0x34, 0x31, 0x38, 0x20, 0x63, 0x20,
-0x2D, 0x30, 0x2E, 0x30, 0x33, 0x32, 0x32, 0x2C, 0x32, 0x2E, 0x38, 0x33, 0x34, 0x32, 0x34, 0x20,
-0x2D, 0x30, 0x2E, 0x32, 0x31, 0x33, 0x30, 0x37, 0x2C, 0x35, 0x2E, 0x31, 0x31, 0x33, 0x36, 0x32,
-0x20, 0x2D, 0x30, 0x2E, 0x34, 0x32, 0x36, 0x32, 0x39, 0x2C, 0x35, 0x2E, 0x33, 0x37, 0x30, 0x35,
-0x33, 0x20, 0x2D, 0x30, 0x2E, 0x32, 0x30, 0x33, 0x37, 0x34, 0x2C, 0x30, 0x2E, 0x32, 0x34, 0x35,
-0x34, 0x39, 0x20, 0x2D, 0x30, 0x2E, 0x38, 0x38, 0x39, 0x30, 0x39, 0x2C, 0x30, 0x2E, 0x35, 0x34,
-0x33, 0x36, 0x34, 0x20, 0x2D, 0x31, 0x2E, 0x35, 0x32, 0x33, 0x2C, 0x30, 0x2E, 0x36, 0x36, 0x32,
-0x35, 0x37, 0x20, 0x2D, 0x30, 0x2E, 0x39, 0x38, 0x33, 0x31, 0x35, 0x2C, 0x30, 0x2E, 0x31, 0x38,
-0x34, 0x34, 0x33, 0x20, 0x2D, 0x31, 0x2E, 0x32, 0x31, 0x35, 0x37, 0x39, 0x2C, 0x30, 0x2E, 0x34,
-0x33, 0x32, 0x31, 0x33, 0x20, 0x2D, 0x31, 0x2E, 0x35, 0x38, 0x32, 0x36, 0x2C, 0x31, 0x2E, 0x36,
-0x38, 0x35, 0x30, 0x33, 0x20, 0x2D, 0x31, 0x2E, 0x30, 0x37, 0x31, 0x36, 0x38, 0x2C, 0x33, 0x2E,
-0x36, 0x36, 0x30, 0x34, 0x38, 0x20, 0x2D, 0x34, 0x2E, 0x35, 0x31, 0x30, 0x38, 0x2C, 0x37, 0x2E,
-0x33, 0x38, 0x32, 0x33, 0x31, 0x20, 0x2D, 0x38, 0x2E, 0x30, 0x34, 0x32, 0x35, 0x39, 0x2C, 0x38,
-0x2E, 0x37, 0x30, 0x33, 0x37, 0x32, 0x20, 0x2D, 0x32, 0x2E, 0x35, 0x32, 0x32, 0x33, 0x31, 0x2C,
-0x30, 0x2E, 0x39, 0x34, 0x33, 0x37, 0x32, 0x20, 0x2D, 0x36, 0x2E, 0x30, 0x39, 0x36, 0x37, 0x34,
-0x2C, 0x31, 0x2E, 0x32, 0x30, 0x32, 0x32, 0x31, 0x20, 0x2D, 0x38, 0x2E, 0x32, 0x30, 0x31, 0x33,
-0x35, 0x2C, 0x30, 0x2E, 0x35, 0x39, 0x33, 0x31, 0x31, 0x20, 0x7A, 0x20, 0x6D, 0x20, 0x2D, 0x31,
-0x33, 0x2E, 0x37, 0x36, 0x32, 0x32, 0x32, 0x2C, 0x2D, 0x32, 0x38, 0x2E, 0x39, 0x30, 0x36, 0x35,
-0x20, 0x63, 0x20, 0x2D, 0x30, 0x2E, 0x30, 0x30, 0x32, 0x2C, 0x2D, 0x30, 0x2E, 0x38, 0x32, 0x34,
-0x36, 0x32, 0x20, 0x2D, 0x30, 0x2E, 0x31, 0x30, 0x32, 0x32, 0x38, 0x2C, 0x2D, 0x32, 0x2E, 0x30,
-0x39, 0x34, 0x36, 0x32, 0x20, 0x2D, 0x30, 0x2E, 0x32, 0x32, 0x32, 0x35, 0x34, 0x2C, 0x2D, 0x32,
-0x2E, 0x38, 0x32, 0x32, 0x32, 0x32, 0x20, 0x6C, 0x20, 0x2D, 0x30, 0x2E, 0x32, 0x31, 0x38, 0x36,
-0x37, 0x2C, 0x2D, 0x31, 0x2E, 0x33, 0x32, 0x32, 0x39, 0x32, 0x20, 0x68, 0x20, 0x31, 0x37, 0x2E,
-0x33, 0x37, 0x33, 0x34, 0x32, 0x20, 0x31, 0x37, 0x2E, 0x33, 0x37, 0x33, 0x34, 0x31, 0x20, 0x6C,
-0x20, 0x2D, 0x30, 0x2E, 0x32, 0x31, 0x32, 0x37, 0x31, 0x2C, 0x30, 0x2E, 0x37, 0x39, 0x33, 0x37,
-0x35, 0x20, 0x63, 0x20, 0x2D, 0x30, 0x2E, 0x31, 0x31, 0x37, 0x2C, 0x30, 0x2E, 0x34, 0x33, 0x36,
-0x35, 0x36, 0x20, 0x2D, 0x30, 0x2E, 0x32, 0x31, 0x34, 0x38, 0x39, 0x2C, 0x31, 0x2E, 0x37, 0x30,
-0x36, 0x35, 0x36, 0x20, 0x2D, 0x30, 0x2E, 0x32, 0x31, 0x37, 0x35, 0x34, 0x2C, 0x32, 0x2E, 0x38,
-0x32, 0x32, 0x32, 0x32, 0x20, 0x6C, 0x20, 0x2D, 0x30, 0x2E, 0x30, 0x30, 0x35, 0x2C, 0x32, 0x2E,
-0x30, 0x32, 0x38, 0x34, 0x38, 0x20, 0x68, 0x20, 0x2D, 0x31, 0x36, 0x2E, 0x39, 0x33, 0x33, 0x31,
-0x35, 0x20, 0x2D, 0x31, 0x36, 0x2E, 0x39, 0x33, 0x33, 0x33, 0x33, 0x20, 0x7A, 0x20, 0x6D, 0x20,
-0x2D, 0x32, 0x2E, 0x31, 0x33, 0x32, 0x37, 0x39, 0x2C, 0x2D, 0x31, 0x31, 0x2E, 0x38, 0x31, 0x38,
-0x30, 0x36, 0x20, 0x63, 0x20, 0x2D, 0x31, 0x2E, 0x37, 0x38, 0x35, 0x33, 0x32, 0x2C, 0x2D, 0x35,
-0x2E, 0x34, 0x32, 0x38, 0x38, 0x39, 0x20, 0x2D, 0x35, 0x2E, 0x30, 0x36, 0x38, 0x31, 0x37, 0x2C,
-0x2D, 0x31, 0x31, 0x2E, 0x34, 0x32, 0x38, 0x38, 0x34, 0x20, 0x2D, 0x38, 0x2E, 0x38, 0x38, 0x37,
-0x36, 0x33, 0x2C, 0x2D, 0x31, 0x36, 0x2E, 0x32, 0x34, 0x33, 0x36, 0x20, 0x2D, 0x30, 0x2E, 0x39,
-0x36, 0x38, 0x39, 0x2C, 0x2D, 0x31, 0x2E, 0x32, 0x32, 0x31, 0x33, 0x38, 0x20, 0x2D, 0x31, 0x2E,
-0x36, 0x39, 0x33, 0x34, 0x33, 0x2C, 0x2D, 0x32, 0x2E, 0x32, 0x38, 0x38, 0x38, 0x39, 0x20, 0x2D,
-0x31, 0x2E, 0x36, 0x31, 0x30, 0x30, 0x38, 0x2C, 0x2D, 0x32, 0x2E, 0x33, 0x37, 0x32, 0x32, 0x34,
-0x20, 0x30, 0x2E, 0x30, 0x38, 0x33, 0x34, 0x2C, 0x2D, 0x30, 0x2E, 0x30, 0x38, 0x33, 0x34, 0x20,
-0x35, 0x2E, 0x37, 0x37, 0x38, 0x30, 0x31, 0x2C, 0x2D, 0x32, 0x2E, 0x33, 0x38, 0x30, 0x37, 0x31,
-0x20, 0x31, 0x32, 0x2E, 0x36, 0x35, 0x34, 0x37, 0x38, 0x2C, 0x2D, 0x35, 0x2E, 0x31, 0x30, 0x35,
-0x32, 0x33, 0x20, 0x36, 0x2E, 0x38, 0x37, 0x36, 0x37, 0x37, 0x2C, 0x2D, 0x32, 0x2E, 0x37, 0x32,
-0x34, 0x35, 0x32, 0x20, 0x31, 0x32, 0x2E, 0x38, 0x36, 0x30, 0x34, 0x31, 0x2C, 0x2D, 0x35, 0x2E,
-0x31, 0x30, 0x36, 0x34, 0x32, 0x20, 0x31, 0x33, 0x2E, 0x32, 0x39, 0x36, 0x39, 0x37, 0x2C, 0x2D,
-0x35, 0x2E, 0x32, 0x39, 0x33, 0x31, 0x31, 0x20, 0x6C, 0x20, 0x30, 0x2E, 0x37, 0x39, 0x33, 0x37,
-0x35, 0x2C, 0x2D, 0x30, 0x2E, 0x33, 0x33, 0x39, 0x34, 0x34, 0x20, 0x76, 0x20, 0x31, 0x35, 0x2E,
-0x38, 0x36, 0x37, 0x34, 0x34, 0x20, 0x31, 0x35, 0x2E, 0x38, 0x36, 0x37, 0x34, 0x33, 0x20, 0x68,
-0x20, 0x2D, 0x37, 0x2E, 0x37, 0x33, 0x32, 0x33, 0x35, 0x20, 0x2D, 0x37, 0x2E, 0x37, 0x33, 0x32,
-0x33, 0x35, 0x20, 0x7A, 0x20, 0x6D, 0x20, 0x32, 0x32, 0x2E, 0x38, 0x34, 0x30, 0x30, 0x37, 0x2C,
-0x32, 0x2E, 0x31, 0x35, 0x33, 0x31, 0x36, 0x20, 0x63, 0x20, 0x2D, 0x30, 0x2E, 0x33, 0x34, 0x36,
-0x38, 0x38, 0x2C, 0x2D, 0x30, 0x2E, 0x33, 0x34, 0x36, 0x38, 0x38, 0x20, 0x2D, 0x30, 0x2E, 0x33,
-0x30, 0x30, 0x38, 0x38, 0x2C, 0x2D, 0x35, 0x30, 0x2E, 0x39, 0x32, 0x34, 0x36, 0x38, 0x20, 0x30,
-0x2E, 0x30, 0x34, 0x36, 0x33, 0x2C, 0x2D, 0x35, 0x30, 0x2E, 0x39, 0x32, 0x34, 0x36, 0x38, 0x20,
-0x30, 0x2E, 0x31, 0x35, 0x38, 0x37, 0x33, 0x2C, 0x30, 0x20, 0x33, 0x2E, 0x39, 0x32, 0x39, 0x30,
-0x34, 0x2C, 0x31, 0x2E, 0x34, 0x33, 0x39, 0x31, 0x38, 0x20, 0x38, 0x2E, 0x33, 0x37, 0x38, 0x34,
-0x37, 0x2C, 0x33, 0x2E, 0x31, 0x39, 0x38, 0x31, 0x39, 0x20, 0x34, 0x2E, 0x34, 0x34, 0x39, 0x34,
-0x34, 0x2C, 0x31, 0x2E, 0x37, 0x35, 0x39, 0x20, 0x31, 0x31, 0x2E, 0x37, 0x34, 0x31, 0x31, 0x34,
-0x2C, 0x34, 0x2E, 0x36, 0x33, 0x39, 0x34, 0x38, 0x20, 0x31, 0x36, 0x2E, 0x32, 0x30, 0x33, 0x37,
-0x37, 0x2C, 0x36, 0x2E, 0x34, 0x30, 0x31, 0x30, 0x36, 0x20, 0x34, 0x2E, 0x34, 0x36, 0x32, 0x36,
-0x34, 0x2C, 0x31, 0x2E, 0x37, 0x36, 0x31, 0x35, 0x38, 0x20, 0x38, 0x2E, 0x31, 0x35, 0x36, 0x33,
-0x38, 0x2C, 0x33, 0x2E, 0x32, 0x33, 0x35, 0x36, 0x31, 0x20, 0x38, 0x2E, 0x32, 0x30, 0x38, 0x33,
-0x2C, 0x33, 0x2E, 0x32, 0x37, 0x35, 0x36, 0x31, 0x20, 0x30, 0x2E, 0x31, 0x39, 0x32, 0x31, 0x31,
-0x2C, 0x30, 0x2E, 0x31, 0x34, 0x38, 0x30, 0x33, 0x20, 0x2D, 0x30, 0x2E, 0x39, 0x37, 0x34, 0x38,
-0x36, 0x2C, 0x35, 0x2E, 0x31, 0x31, 0x31, 0x30, 0x35, 0x20, 0x2D, 0x31, 0x2E, 0x37, 0x31, 0x32,
-0x33, 0x33, 0x2C, 0x37, 0x2E, 0x32, 0x38, 0x32, 0x33, 0x33, 0x20, 0x2D, 0x31, 0x2E, 0x32, 0x30,
-0x31, 0x2C, 0x33, 0x2E, 0x35, 0x33, 0x36, 0x30, 0x38, 0x20, 0x2D, 0x33, 0x2E, 0x30, 0x37, 0x39,
-0x34, 0x37, 0x2C, 0x36, 0x2E, 0x38, 0x38, 0x32, 0x31, 0x39, 0x20, 0x2D, 0x36, 0x2E, 0x31, 0x31,
-0x31, 0x39, 0x37, 0x2C, 0x31, 0x30, 0x2E, 0x38, 0x38, 0x37, 0x32, 0x35, 0x20, 0x2D, 0x35, 0x2E,
-0x31, 0x30, 0x32, 0x33, 0x37, 0x2C, 0x36, 0x2E, 0x37, 0x33, 0x38, 0x37, 0x36, 0x20, 0x2D, 0x37,
-0x2E, 0x31, 0x36, 0x38, 0x31, 0x38, 0x2C, 0x31, 0x30, 0x2E, 0x33, 0x36, 0x30, 0x39, 0x37, 0x20,
-0x2D, 0x39, 0x2E, 0x33, 0x35, 0x35, 0x35, 0x38, 0x2C, 0x31, 0x36, 0x2E, 0x34, 0x30, 0x34, 0x31,
-0x37, 0x20, 0x6C, 0x20, 0x2D, 0x31, 0x2E, 0x32, 0x37, 0x36, 0x39, 0x32, 0x2C, 0x33, 0x2E, 0x35,
-0x32, 0x37, 0x37, 0x38, 0x20, 0x2D, 0x37, 0x2E, 0x30, 0x36, 0x38, 0x38, 0x38, 0x2C, 0x30, 0x2E,
-0x30, 0x39, 0x35, 0x33, 0x20, 0x63, 0x20, 0x2D, 0x33, 0x2E, 0x38, 0x38, 0x37, 0x38, 0x39, 0x2C,
-0x30, 0x2E, 0x30, 0x35, 0x32, 0x34, 0x20, 0x2D, 0x37, 0x2E, 0x31, 0x37, 0x37, 0x39, 0x32, 0x2C,
-0x2D, 0x30, 0x2E, 0x30, 0x31, 0x33, 0x37, 0x20, 0x2D, 0x37, 0x2E, 0x33, 0x31, 0x31, 0x31, 0x37,
-0x2C, 0x2D, 0x30, 0x2E, 0x31, 0x34, 0x36, 0x39, 0x39, 0x20, 0x7A, 0x20, 0x6D, 0x20, 0x2D, 0x33,
-0x38, 0x2E, 0x31, 0x32, 0x34, 0x31, 0x2C, 0x2D, 0x32, 0x38, 0x2E, 0x39, 0x36, 0x34, 0x32, 0x37,
-0x20, 0x63, 0x20, 0x2D, 0x36, 0x2E, 0x30, 0x32, 0x38, 0x31, 0x2C, 0x2D, 0x31, 0x35, 0x2E, 0x39,
-0x31, 0x36, 0x38, 0x37, 0x20, 0x2D, 0x31, 0x2E, 0x31, 0x37, 0x38, 0x38, 0x37, 0x2C, 0x2D, 0x33,
-0x33, 0x2E, 0x30, 0x35, 0x36, 0x36, 0x20, 0x31, 0x32, 0x2E, 0x32, 0x30, 0x35, 0x39, 0x39, 0x2C,
-0x2D, 0x34, 0x33, 0x2E, 0x31, 0x34, 0x32, 0x33, 0x39, 0x39, 0x20, 0x34, 0x2E, 0x37, 0x38, 0x34,
-0x34, 0x33, 0x2C, 0x2D, 0x33, 0x2E, 0x36, 0x30, 0x35, 0x31, 0x37, 0x37, 0x20, 0x31, 0x31, 0x2E,
-0x38, 0x31, 0x39, 0x36, 0x34, 0x2C, 0x2D, 0x36, 0x2E, 0x35, 0x33, 0x32, 0x31, 0x39, 0x37, 0x20,
-0x31, 0x37, 0x2E, 0x33, 0x30, 0x30, 0x32, 0x31, 0x2C, 0x2D, 0x37, 0x2E, 0x31, 0x39, 0x37, 0x37,
-0x39, 0x38, 0x20, 0x6C, 0x20, 0x32, 0x2E, 0x30, 0x33, 0x31, 0x33, 0x33, 0x2C, 0x2D, 0x30, 0x2E,
-0x32, 0x34, 0x36, 0x37, 0x20, 0x2D, 0x30, 0x2E, 0x30, 0x39, 0x31, 0x2C, 0x32, 0x30, 0x2E, 0x35,
-0x33, 0x31, 0x37, 0x33, 0x37, 0x20, 0x2D, 0x30, 0x2E, 0x30, 0x39, 0x31, 0x31, 0x2C, 0x32, 0x30,
-0x2E, 0x35, 0x33, 0x31, 0x37, 0x34, 0x20, 0x2D, 0x31, 0x34, 0x2E, 0x39, 0x39, 0x33, 0x30, 0x36,
-0x2C, 0x35, 0x2E, 0x39, 0x35, 0x30, 0x37, 0x34, 0x20, 0x63, 0x20, 0x2D, 0x38, 0x2E, 0x32, 0x34,
-0x36, 0x31, 0x38, 0x2C, 0x33, 0x2E, 0x32, 0x37, 0x32, 0x39, 0x31, 0x20, 0x2D, 0x31, 0x35, 0x2E,
-0x30, 0x39, 0x38, 0x32, 0x34, 0x2C, 0x35, 0x2E, 0x39, 0x35, 0x31, 0x34, 0x36, 0x20, 0x2D, 0x31,
-0x35, 0x2E, 0x32, 0x32, 0x36, 0x37, 0x39, 0x2C, 0x35, 0x2E, 0x39, 0x35, 0x32, 0x33, 0x34, 0x20,
-0x2D, 0x30, 0x2E, 0x31, 0x32, 0x38, 0x35, 0x36, 0x2C, 0x38, 0x2E, 0x38, 0x65, 0x2D, 0x34, 0x20,
-0x2D, 0x30, 0x2E, 0x36, 0x33, 0x39, 0x35, 0x37, 0x2C, 0x2D, 0x31, 0x2E, 0x30, 0x36, 0x39, 0x39,
-0x37, 0x20, 0x2D, 0x31, 0x2E, 0x31, 0x33, 0x35, 0x35, 0x38, 0x2C, 0x2D, 0x32, 0x2E, 0x33, 0x37,
-0x39, 0x36, 0x36, 0x20, 0x7A, 0x20, 0x6D, 0x20, 0x35, 0x34, 0x2E, 0x38, 0x31, 0x35, 0x31, 0x35,
-0x2C, 0x2D, 0x32, 0x32, 0x2E, 0x35, 0x31, 0x30, 0x37, 0x35, 0x20, 0x63, 0x20, 0x2D, 0x38, 0x2E,
-0x34, 0x34, 0x30, 0x32, 0x2C, 0x2D, 0x33, 0x2E, 0x33, 0x36, 0x36, 0x32, 0x31, 0x20, 0x2D, 0x31,
-0x35, 0x2E, 0x37, 0x30, 0x33, 0x30, 0x32, 0x2C, 0x2D, 0x36, 0x2E, 0x32, 0x38, 0x32, 0x39, 0x35,
-0x20, 0x2D, 0x31, 0x36, 0x2E, 0x31, 0x33, 0x39, 0x35, 0x38, 0x2C, 0x2D, 0x36, 0x2E, 0x34, 0x38,
-0x31, 0x36, 0x33, 0x20, 0x6C, 0x20, 0x2D, 0x30, 0x2E, 0x37, 0x39, 0x33, 0x37, 0x35, 0x2C, 0x2D,
-0x30, 0x2E, 0x33, 0x36, 0x31, 0x32, 0x34, 0x20, 0x56, 0x20, 0x39, 0x39, 0x2E, 0x31, 0x39, 0x30,
-0x36, 0x30, 0x39, 0x20, 0x63, 0x20, 0x30, 0x2C, 0x2D, 0x39, 0x2E, 0x39, 0x33, 0x38, 0x39, 0x37,
-0x39, 0x20, 0x30, 0x2E, 0x30, 0x33, 0x39, 0x33, 0x2C, 0x2D, 0x31, 0x30, 0x2E, 0x36, 0x30, 0x33,
-0x38, 0x31, 0x35, 0x20, 0x30, 0x2E, 0x36, 0x31, 0x37, 0x33, 0x36, 0x2C, 0x2D, 0x31, 0x30, 0x2E,
-0x34, 0x34, 0x34, 0x31, 0x36, 0x32, 0x20, 0x30, 0x2E, 0x33, 0x33, 0x39, 0x35, 0x35, 0x2C, 0x30,
-0x2E, 0x30, 0x39, 0x33, 0x37, 0x38, 0x20, 0x31, 0x2E, 0x34, 0x31, 0x31, 0x31, 0x31, 0x2C, 0x30,
-0x2E, 0x32, 0x37, 0x38, 0x36, 0x34, 0x20, 0x32, 0x2E, 0x33, 0x38, 0x31, 0x32, 0x35, 0x2C, 0x30,
-0x2E, 0x34, 0x31, 0x30, 0x38, 0x30, 0x31, 0x20, 0x30, 0x2E, 0x39, 0x37, 0x30, 0x31, 0x34, 0x2C,
-0x30, 0x2E, 0x31, 0x33, 0x32, 0x31, 0x36, 0x31, 0x20, 0x33, 0x2E, 0x30, 0x33, 0x33, 0x38, 0x39,
-0x2C, 0x30, 0x2E, 0x36, 0x33, 0x38, 0x32, 0x31, 0x36, 0x20, 0x34, 0x2E, 0x35, 0x38, 0x36, 0x31,
-0x31, 0x2C, 0x31, 0x2E, 0x31, 0x32, 0x34, 0x35, 0x36, 0x36, 0x20, 0x39, 0x2E, 0x37, 0x31, 0x36,
-0x31, 0x37, 0x2C, 0x33, 0x2E, 0x30, 0x34, 0x34, 0x33, 0x32, 0x31, 0x20, 0x31, 0x38, 0x2E, 0x32,
-0x35, 0x35, 0x33, 0x34, 0x2C, 0x31, 0x30, 0x2E, 0x36, 0x30, 0x39, 0x33, 0x33, 0x36, 0x20, 0x32,
-0x32, 0x2E, 0x36, 0x30, 0x37, 0x30, 0x34, 0x2C, 0x32, 0x30, 0x2E, 0x30, 0x32, 0x38, 0x30, 0x33,
-0x36, 0x20, 0x32, 0x2E, 0x30, 0x34, 0x38, 0x32, 0x32, 0x2C, 0x34, 0x2E, 0x34, 0x33, 0x33, 0x31,
-0x31, 0x20, 0x33, 0x2E, 0x37, 0x32, 0x39, 0x31, 0x2C, 0x31, 0x32, 0x2E, 0x35, 0x38, 0x33, 0x33,
-0x38, 0x20, 0x32, 0x2E, 0x35, 0x37, 0x37, 0x31, 0x2C, 0x31, 0x32, 0x2E, 0x34, 0x39, 0x35, 0x38,
-0x39, 0x20, 0x2D, 0x30, 0x2E, 0x32, 0x36, 0x39, 0x33, 0x33, 0x2C, 0x2D, 0x30, 0x2E, 0x30, 0x32,
-0x30, 0x35, 0x20, 0x2D, 0x37, 0x2E, 0x33, 0x39, 0x35, 0x33, 0x32, 0x2C, 0x2D, 0x32, 0x2E, 0x37,
-0x39, 0x31, 0x33, 0x37, 0x20, 0x2D, 0x31, 0x35, 0x2E, 0x38, 0x33, 0x35, 0x35, 0x33, 0x2C, 0x2D,
-0x36, 0x2E, 0x31, 0x35, 0x37, 0x35, 0x39, 0x20, 0x7A, 0x22, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
-0x20, 0x20, 0x69, 0x64, 0x3D, 0x22, 0x70, 0x61, 0x74, 0x68, 0x31, 0x22, 0x20, 0x2F, 0x3E, 0x3C,
-0x2F, 0x67, 0x3E, 0x3C, 0x2F, 0x73, 0x76, 0x67, 0x3E, 0x0A
- };
\ No newline at end of file
diff --git a/src/www/colorpicker.html.unused b/src/www/colorpicker.html.unused
new file mode 100644
index 0000000..674d0ee
--- /dev/null
+++ b/src/www/colorpicker.html.unused
@@ -0,0 +1,147 @@
+
+
+
+
+ BLLED Custom Colorpicker
+
+
+
+
+LED Farbe wΓ€hlen
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/www/favicon.h b/src/www/favicon.h
deleted file mode 100644
index c6f156c..0000000
--- a/src/www/favicon.h
+++ /dev/null
@@ -1,278 +0,0 @@
-#include
-//https://tomeko.net/online_tools/file_to_hex.php?lang=en
-const unsigned int BBLED_favicon_len = 4359;
-const uint8_t BBLED_favicon[] PROGMEM = {
-0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
-0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x00, 0xE2, 0x98, 0x77,
-0x38, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00,
-0x10, 0xC1, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0x9D, 0x7B, 0x90, 0x1C, 0xC5, 0x7D, 0xC7,
-0x3F, 0xBF, 0x99, 0xDD, 0xDB, 0xD3, 0xDD, 0xE9, 0x85, 0x10, 0x6F, 0xDB, 0x18, 0x10, 0x21, 0x60,
-0x20, 0x04, 0xFC, 0x20, 0x15, 0x6C, 0x11, 0x03, 0x41, 0xC2, 0xD2, 0x81, 0xE0, 0x0E, 0x2C, 0x2C,
-0x90, 0x1D, 0x47, 0x18, 0x1C, 0x08, 0x94, 0xC1, 0xA6, 0x22, 0x4C, 0x2E, 0x8E, 0x71, 0xEC, 0x32,
-0xB6, 0xCB, 0x60, 0x57, 0x8C, 0x52, 0x01, 0x0C, 0x92, 0xA0, 0xEE, 0xCA, 0x12, 0x3A, 0x21, 0x04,
-0x22, 0x65, 0x29, 0x54, 0x62, 0x11, 0x61, 0x61, 0x1B, 0x2C, 0x15, 0x16, 0x46, 0x15, 0x5B, 0x80,
-0x64, 0x0B, 0xF4, 0x3A, 0x49, 0xF7, 0x9A, 0x99, 0x5F, 0xAE, 0x67, 0x77, 0x4F, 0xBB, 0x7B, 0xBB,
-0x3B, 0xB3, 0xBB, 0xB3, 0x0F, 0x52, 0xD7, 0xFF, 0xA8, 0x74, 0xD3, 0xD3, 0xD3, 0xFD, 0xFB, 0xF6,
-0xEF, 0xD1, 0xBF, 0x47, 0xAF, 0x30, 0xDE, 0xEA, 0x4A, 0x01, 0xA9, 0xEB, 0xD7, 0xC7, 0x3F, 0xCE,
-0x38, 0x00, 0x75, 0xDE, 0x04, 0xE3, 0x00, 0x8C, 0x03, 0x10, 0x40, 0x01, 0x45, 0x78, 0x74, 0x66,
-0x82, 0xC9, 0x53, 0x5B, 0xE9, 0x1F, 0x3E, 0x8A, 0x98, 0x75, 0x3C, 0x43, 0x96, 0x45, 0x22, 0xFE,
-0x0B, 0x3A, 0x7B, 0xF6, 0xFB, 0x6F, 0x77, 0x77, 0xD8, 0xD0, 0x7F, 0x22, 0xAE, 0x35, 0x0D, 0xDB,
-0x7B, 0x97, 0x61, 0xED, 0xE3, 0x5D, 0xEF, 0x30, 0xB7, 0xAD, 0x1D, 0x02, 0xB4, 0xCE, 0x34, 0x2E,
-0xFA, 0xF9, 0xC6, 0xE4, 0x00, 0x43, 0xF4, 0x9E, 0x8E, 0x56, 0x06, 0x07, 0x4F, 0x24, 0x26, 0x67,
-0xA3, 0xFA, 0x31, 0x84, 0x8F, 0xA3, 0x9C, 0x86, 0x48, 0x1C, 0x74, 0x1B, 0xB6, 0x37, 0x97, 0xCE,
-0xA7, 0xDF, 0xF2, 0x57, 0xF7, 0xC0, 0xAC, 0x04, 0x47, 0x27, 0x16, 0x81, 0xDE, 0xE3, 0x93, 0x5B,
-0xD8, 0x0A, 0xFC, 0x37, 0x1E, 0x9B, 0x89, 0x0D, 0x6F, 0xC1, 0x6A, 0x7D, 0x9B, 0x8E, 0x9E, 0x43,
-0x48, 0xE3, 0x81, 0xD1, 0x58, 0x00, 0x98, 0x9D, 0x3C, 0xE0, 0x4C, 0x23, 0xE6, 0x9E, 0x0B, 0x72,
-0xB5, 0xA0, 0xED, 0x2A, 0x32, 0x09, 0x25, 0x0E, 0xD8, 0x80, 0xE5, 0x13, 0x5C, 0xD8, 0x02, 0xCC,
-0xE2, 0xD3, 0xAB, 0x76, 0xF8, 0xFF, 0x7F, 0x66, 0x56, 0x82, 0x7D, 0x89, 0x9B, 0x11, 0xBD, 0x0F,
-0x98, 0x80, 0xFA, 0x84, 0x76, 0x01, 0xC3, 0x01, 0x07, 0x80, 0x5E, 0x2C, 0x59, 0x81, 0xE7, 0xFD,
-0x8A, 0x58, 0xE2, 0x1D, 0x3A, 0x7B, 0xCC, 0xB3, 0x86, 0x68, 0x8D, 0x01, 0x80, 0xD9, 0xF1, 0x4F,
-0xCC, 0x99, 0x86, 0x5A, 0x1F, 0x01, 0xEE, 0xC4, 0xE2, 0x7C, 0x94, 0x09, 0x08, 0x31, 0xCC, 0xB3,
-0xDC, 0x96, 0x0F, 0x80, 0x03, 0x89, 0x9B, 0x41, 0xEF, 0xC3, 0xA3, 0x25, 0xAB, 0xBB, 0xD9, 0xF5,
-0x2A, 0x0E, 0xE8, 0x00, 0xF0, 0x4B, 0x70, 0xBF, 0x8D, 0x13, 0xFF, 0x1F, 0x16, 0xAC, 0xDC, 0xDD,
-0x08, 0x1C, 0x51, 0x7F, 0x00, 0x1E, 0x99, 0xD9, 0x4C, 0xD3, 0x94, 0xB3, 0x10, 0x6F, 0x31, 0x2A,
-0x97, 0x20, 0x3E, 0x01, 0xCD, 0x6E, 0x2F, 0xD6, 0xB6, 0x20, 0x39, 0x1C, 0x60, 0x00, 0x50, 0xBD,
-0x0F, 0xCD, 0x01, 0x20, 0x73, 0x14, 0xC1, 0x45, 0x39, 0x0C, 0xFA, 0x02, 0x9E, 0xFE, 0x13, 0x4D,
-0xCD, 0xBF, 0xA6, 0xB3, 0xA7, 0xBF, 0x9E, 0xAC, 0x50, 0x3F, 0x00, 0x7C, 0x39, 0x3F, 0xEB, 0x68,
-0xDC, 0xF8, 0x1C, 0x54, 0xBE, 0x81, 0x30, 0x0D, 0x25, 0x56, 0x90, 0x18, 0x66, 0xA6, 0x47, 0xD4,
-0xE9, 0x58, 0x00, 0xD2, 0x22, 0x48, 0x69, 0xF1, 0xBB, 0xA6, 0x57, 0x96, 0x4F, 0x05, 0x0B, 0x8E,
-0x28, 0x7B, 0x14, 0xEE, 0xC5, 0xE9, 0x5F, 0xC9, 0x82, 0x75, 0x75, 0xE3, 0x86, 0xFA, 0x00, 0xD0,
-0x35, 0x33, 0xC6, 0x8C, 0xD6, 0xF7, 0x23, 0xF6, 0xB7, 0x50, 0x99, 0x8D, 0xE5, 0xCB, 0xED, 0xF0,
-0x73, 0x29, 0x24, 0x82, 0x82, 0x38, 0x20, 0xA9, 0x3F, 0x92, 0x40, 0x26, 0x15, 0x72, 0x3F, 0xCA,
-0x5A, 0x62, 0xDE, 0x5D, 0x6C, 0xED, 0xDB, 0x41, 0xD7, 0x06, 0xA7, 0xD6, 0xDC, 0x10, 0x7E, 0xD1,
-0x51, 0xCD, 0xAC, 0xBB, 0xA3, 0x89, 0xA1, 0xA1, 0xD3, 0xB0, 0xF8, 0x31, 0xC8, 0xB9, 0x23, 0x72,
-0xDB, 0x28, 0xD8, 0xD0, 0x2D, 0x45, 0xBF, 0x82, 0x22, 0x48, 0x94, 0x96, 0x62, 0x76, 0x67, 0x36,
-0x23, 0xF9, 0x88, 0x0C, 0x23, 0xFA, 0x32, 0xEA, 0x2D, 0x24, 0xF6, 0xC6, 0x76, 0x3A, 0xB7, 0x1A,
-0xC5, 0x5D, 0xB3, 0x56, 0x5B, 0x00, 0x8C, 0xB9, 0x78, 0x4C, 0xF3, 0x0C, 0x3C, 0xAF, 0x1B, 0xF8,
-0x93, 0x51, 0xAB, 0xA6, 0xD4, 0xE5, 0x56, 0xC2, 0x01, 0xF9, 0xBE, 0xE5, 0xEB, 0x06, 0x7D, 0x0D,
-0x4F, 0x3A, 0x69, 0x6A, 0xFA, 0x2D, 0x9D, 0x3D, 0x35, 0x03, 0xA1, 0x76, 0x00, 0xA4, 0x77, 0xBE,
-0xD0, 0x83, 0x70, 0x46, 0xD9, 0xC4, 0x4F, 0x4A, 0x91, 0x2D, 0x9A, 0xAB, 0x84, 0x33, 0x74, 0xC0,
-0x28, 0x8D, 0xC7, 0x6E, 0xF7, 0x23, 0x22, 0x68, 0x2C, 0x10, 0x1E, 0xA2, 0xAF, 0xE2, 0x70, 0x2D,
-0x87, 0xDF, 0xDA, 0xCE, 0x4D, 0x9B, 0x87, 0x4B, 0xDD, 0x17, 0xE5, 0xF4, 0xAF, 0x0D, 0x00, 0xBE,
-0xCC, 0x6F, 0x39, 0x11, 0x89, 0x19, 0xB1, 0x73, 0x51, 0x51, 0xE2, 0xE7, 0x23, 0xDA, 0xD8, 0x95,
-0x95, 0x65, 0x05, 0x05, 0x0E, 0x9D, 0xB4, 0x92, 0xD6, 0xA3, 0xC3, 0x9F, 0xE7, 0xF5, 0xC3, 0x6F,
-0xD5, 0x42, 0x27, 0x54, 0x1F, 0x80, 0xAE, 0x2E, 0x8B, 0x73, 0x7E, 0x35, 0x95, 0x01, 0xFD, 0x07,
-0xD0, 0xDB, 0xA0, 0x80, 0xA5, 0x13, 0x48, 0x9D, 0x23, 0x28, 0x84, 0xE6, 0x80, 0x72, 0xB6, 0x24,
-0x98, 0x33, 0xC3, 0x0F, 0x41, 0xBF, 0xCE, 0xB6, 0xF3, 0xF7, 0xD0, 0xD5, 0xE5, 0x95, 0x37, 0x4C,
-0xB8, 0xB7, 0xAA, 0x0F, 0xC0, 0x63, 0x97, 0xB5, 0xD2, 0x94, 0xB8, 0x04, 0x4F, 0x96, 0x81, 0xB4,
-0x86, 0x9B, 0x56, 0x60, 0xAF, 0xA2, 0x66, 0x68, 0xE0, 0xDB, 0x41, 0x1D, 0xC4, 0x9C, 0x15, 0xB8,
-0x11, 0x7B, 0xFF, 0xB3, 0x74, 0x6E, 0x38, 0x18, 0xD4, 0xBD, 0x92, 0xE7, 0xD5, 0x05, 0x60, 0xFD,
-0xCC, 0x18, 0x3B, 0x27, 0x9E, 0x06, 0xD6, 0x53, 0x29, 0xA5, 0x5B, 0xC9, 0x5C, 0x33, 0xDF, 0xAD,
-0x2E, 0x00, 0xFE, 0x97, 0x74, 0x3B, 0xE8, 0x5C, 0xFA, 0xDE, 0xDE, 0x56, 0x4D, 0x7D, 0x50, 0x4D,
-0x00, 0x84, 0x65, 0x57, 0x4C, 0x41, 0x62, 0xB7, 0x03, 0x8B, 0x47, 0x4F, 0xB7, 0x25, 0x88, 0x9A,
-0x82, 0x68, 0x45, 0x6D, 0x05, 0xF9, 0xD6, 0x68, 0x4A, 0x3F, 0x1F, 0xB1, 0x61, 0x8D, 0x3E, 0xF8,
-0x1E, 0xF1, 0xA6, 0x7F, 0xA1, 0xA3, 0x67, 0x6F, 0xB5, 0xDC, 0x16, 0xD5, 0x03, 0xE0, 0xE7, 0x8B,
-0xE2, 0xBC, 0xBE, 0xEB, 0x5C, 0x54, 0x9E, 0x05, 0xA6, 0xA5, 0xD6, 0x98, 0x3A, 0x03, 0x95, 0xE6,
-0x23, 0xCE, 0x83, 0x59, 0x36, 0x07, 0x18, 0x0B, 0xCB, 0x1B, 0x5C, 0x84, 0xCA, 0xD7, 0x51, 0x26,
-0xA5, 0x8E, 0x5B, 0xA5, 0x73, 0xDB, 0xD8, 0x0F, 0xED, 0x03, 0x77, 0x36, 0xB1, 0x09, 0x9B, 0xAB,
-0x65, 0x9A, 0x56, 0x0F, 0x80, 0x65, 0x57, 0x4C, 0x45, 0x62, 0x5F, 0x06, 0xBE, 0x8C, 0x60, 0x8D,
-0xBA, 0x11, 0x32, 0x17, 0x99, 0x3C, 0x91, 0x96, 0xD3, 0x72, 0x01, 0xB0, 0x71, 0xFA, 0x2F, 0x04,
-0xDB, 0x7C, 0xEF, 0x3C, 0x60, 0x8A, 0xEF, 0x15, 0xCD, 0xF5, 0x29, 0x95, 0xC0, 0x7D, 0xA9, 0xAE,
-0x8A, 0x7A, 0x0F, 0xE2, 0xC4, 0xBE, 0xC6, 0x8D, 0x2B, 0xF7, 0x54, 0x23, 0xB6, 0x50, 0xDE, 0xF2,
-0x83, 0x48, 0x66, 0xDC, 0xCA, 0xCE, 0xC0, 0x19, 0x60, 0x3D, 0x0F, 0x1C, 0x3F, 0xA6, 0x7B, 0x09,
-0x84, 0x28, 0xF0, 0xA9, 0x6C, 0x00, 0x7C, 0x91, 0xDD, 0x65, 0xF1, 0xF0, 0xCB, 0xAD, 0x34, 0x73,
-0x1E, 0xB6, 0x5C, 0x83, 0xA7, 0x9F, 0x40, 0xE5, 0x44, 0x84, 0x36, 0xA0, 0xA9, 0x6C, 0xA8, 0x45,
-0x77, 0xE3, 0x78, 0x97, 0xF2, 0xC6, 0xC1, 0x2D, 0xD5, 0x30, 0x4B, 0xAB, 0x03, 0x80, 0xB1, 0x7C,
-0xEC, 0x96, 0xEB, 0x10, 0xFD, 0x57, 0xF0, 0x7D, 0xF9, 0xC9, 0x66, 0xE4, 0xAC, 0x96, 0x26, 0x7E,
-0x42, 0x03, 0x90, 0xD9, 0xF1, 0xA1, 0x45, 0x71, 0xA6, 0xBE, 0x39, 0x0D, 0x27, 0xDE, 0x0E, 0xCC,
-0x05, 0xCE, 0xF1, 0xB9, 0x42, 0x68, 0x1E, 0x75, 0xF8, 0x85, 0xD9, 0x04, 0x49, 0xEA, 0x18, 0xB3,
-0xF4, 0x56, 0xEC, 0xC4, 0x52, 0x3A, 0x7B, 0x22, 0xB7, 0x88, 0xAA, 0x03, 0xC0, 0x23, 0xB3, 0x8F,
-0x23, 0x11, 0x5F, 0x02, 0xCC, 0xC9, 0x24, 0x7E, 0xA9, 0xF1, 0xA8, 0x22, 0x34, 0x1A, 0xCB, 0x01,
-0xF9, 0x90, 0x32, 0x0E, 0xBE, 0x25, 0x73, 0x26, 0x30, 0x49, 0x8C, 0xDB, 0xE3, 0x73, 0xC0, 0x45,
-0xA8, 0xBC, 0x0F, 0xA1, 0x15, 0xCD, 0xE6, 0x0A, 0x11, 0x50, 0x2D, 0x70, 0x50, 0x16, 0x5D, 0x8B,
-0xED, 0x7C, 0x8E, 0xCE, 0x67, 0x76, 0x05, 0x31, 0x7F, 0xA9, 0xCF, 0xA3, 0x07, 0xC0, 0x17, 0x3F,
-0x83, 0x67, 0x81, 0xAC, 0x1F, 0x09, 0x16, 0x1E, 0x55, 0xEA, 0x84, 0x42, 0xF5, 0xCF, 0xB5, 0x82,
-0x0C, 0xDD, 0xD6, 0xCF, 0xB4, 0x99, 0x78, 0xBA, 0xF0, 0xF4, 0x12, 0x97, 0x2E, 0xC6, 0x1E, 0x9E,
-0xCC, 0xBC, 0xFA, 0x9D, 0x29, 0xC4, 0xDD, 0x59, 0xA2, 0xB2, 0x40, 0x2D, 0x35, 0x73, 0x9C, 0x0C,
-0x19, 0x5C, 0x51, 0xF8, 0xE3, 0x7B, 0x40, 0x2F, 0x26, 0x96, 0xD8, 0x12, 0x75, 0x34, 0x2D, 0x7A,
-0x00, 0x1E, 0x59, 0xD8, 0x4C, 0xF3, 0x5E, 0xC3, 0xFA, 0x3F, 0x46, 0x49, 0x64, 0xAD, 0x29, 0x8C,
-0xD2, 0x0D, 0x27, 0x1A, 0xB2, 0x43, 0x92, 0xE6, 0xBC, 0xB1, 0x6B, 0xF2, 0xF9, 0xB8, 0x1A, 0x43,
-0x63, 0xDB, 0x99, 0x32, 0xBC, 0x9F, 0xFE, 0xE6, 0xC1, 0x02, 0xC4, 0x12, 0xBA, 0x3B, 0xE2, 0x78,
-0xCE, 0xC9, 0x78, 0xEE, 0x2D, 0x20, 0x7F, 0x85, 0x70, 0x12, 0xD0, 0x92, 0x0A, 0x7D, 0x26, 0xC3,
-0x9E, 0x99, 0x4D, 0x18, 0xC4, 0xD3, 0x05, 0x0C, 0x1D, 0x58, 0xCD, 0x67, 0x37, 0x98, 0xC8, 0x5A,
-0x64, 0x2D, 0x7A, 0x00, 0xBA, 0x3B, 0x26, 0xE3, 0x0E, 0xDF, 0x01, 0x7A, 0x6F, 0x81, 0x70, 0x62,
-0xE5, 0x4A, 0xA0, 0x50, 0x4C, 0x18, 0xFD, 0x2A, 0xE8, 0x1F, 0x41, 0x1E, 0x04, 0xEF, 0xA7, 0x78,
-0xCE, 0xDB, 0x34, 0xB5, 0x0D, 0xB0, 0xB5, 0xC7, 0xC9, 0xCB, 0x15, 0x46, 0x44, 0x3D, 0x3C, 0xB7,
-0x8D, 0x16, 0x2E, 0x46, 0xB9, 0x1D, 0x7C, 0x51, 0x65, 0xB8, 0x22, 0x81, 0x60, 0x8F, 0xCE, 0xDF,
-0x0F, 0x6B, 0xEA, 0x62, 0xBC, 0xE1, 0x1F, 0xF2, 0x99, 0xB5, 0x26, 0xC6, 0x1C, 0x59, 0x8B, 0x1E,
-0x80, 0xC7, 0xAE, 0x3A, 0x86, 0xB8, 0xFB, 0x03, 0x54, 0x3A, 0x52, 0x7A, 0x37, 0x5B, 0xF4, 0x87,
-0xD9, 0xE1, 0x41, 0xCB, 0x0B, 0x8A, 0x09, 0x27, 0x9D, 0x6A, 0x7D, 0xA8, 0xFE, 0x94, 0x18, 0xDF,
-0xC7, 0xE5, 0x37, 0x0C, 0x1E, 0xB5, 0x9F, 0xD6, 0x43, 0xC3, 0x05, 0x45, 0x88, 0xE1, 0xA2, 0xDD,
-0x2D, 0x26, 0x42, 0x77, 0x3B, 0xEA, 0x2B, 0x6E, 0x63, 0xBD, 0x99, 0xF0, 0xA8, 0x89, 0x4B, 0x1B,
-0xAE, 0x78, 0x14, 0xF1, 0xEE, 0x62, 0xFE, 0xEA, 0x77, 0x82, 0xA6, 0x57, 0xCA, 0xF3, 0xE8, 0x01,
-0x58, 0x3A, 0xEF, 0x24, 0x2C, 0x67, 0x25, 0xC8, 0x05, 0x81, 0x13, 0x49, 0x83, 0x91, 0xFA, 0xB7,
-0x10, 0x36, 0x63, 0xFE, 0x5E, 0x2C, 0x2B, 0xC2, 0xC4, 0x84, 0x8F, 0x8C, 0x6B, 0xF2, 0x23, 0x8C,
-0x5B, 0x79, 0x27, 0xE8, 0x83, 0x38, 0xBA, 0x82, 0xE6, 0xE6, 0xDD, 0xEC, 0xDD, 0x3E, 0xC8, 0xA2,
-0xCD, 0x4E, 0xC1, 0xD3, 0xAD, 0x6F, 0xC5, 0x35, 0x7F, 0x64, 0x24, 0x58, 0xB3, 0x58, 0x84, 0x33,
-0xD5, 0x58, 0x50, 0xCA, 0xCF, 0xF0, 0xEC, 0x05, 0x2C, 0x58, 0xB1, 0x33, 0x70, 0x5D, 0x25, 0x74,
-0x88, 0x1E, 0x80, 0x27, 0xAE, 0x3C, 0x19, 0x74, 0x3D, 0xCA, 0xC9, 0x79, 0x2D, 0xA0, 0x5C, 0x6A,
-0x16, 0xE1, 0x88, 0x82, 0x80, 0x08, 0x5B, 0xB4, 0x50, 0x5A, 0x4A, 0x4E, 0x50, 0x3E, 0x63, 0x0C,
-0x03, 0xC6, 0x41, 0x2C, 0x79, 0x09, 0x9C, 0x7F, 0x66, 0xA8, 0xFF, 0x55, 0x06, 0x4E, 0x3D, 0xC0,
-0xCE, 0x13, 0x46, 0x94, 0x76, 0x01, 0x8F, 0x67, 0xD2, 0xA0, 0x38, 0xDA, 0xB7, 0xA0, 0x84, 0x8F,
-0x32, 0x6C, 0x2F, 0xE2, 0x86, 0x95, 0x7F, 0x2C, 0x81, 0xBE, 0x81, 0x5D, 0xA3, 0x07, 0xA0, 0x7B,
-0xCE, 0x07, 0x71, 0xAD, 0x8D, 0x28, 0xC7, 0x16, 0xFB, 0x7A, 0x45, 0x92, 0xA8, 0x52, 0x5F, 0x90,
-0xA8, 0x89, 0xFD, 0xBE, 0x8D, 0xB2, 0x0C, 0xB1, 0x96, 0x60, 0xC7, 0xFF, 0xE0, 0xE7, 0x10, 0x75,
-0xF4, 0x78, 0x05, 0xB9, 0xC2, 0x44, 0xF3, 0xF6, 0x7C, 0x74, 0x38, 0x6A, 0xF7, 0x74, 0xF4, 0x00,
-0x2C, 0xBB, 0xE2, 0x14, 0xC4, 0x7E, 0x11, 0x64, 0x7A, 0x1E, 0x6B, 0x22, 0x4B, 0x01, 0x57, 0x00,
-0x42, 0x70, 0x56, 0x44, 0xE0, 0xDE, 0x1B, 0xED, 0x70, 0x10, 0xE4, 0x97, 0x78, 0xEE, 0xB7, 0x70,
-0x0F, 0x6F, 0x64, 0xC2, 0x51, 0xFB, 0xE8, 0xEC, 0x31, 0x66, 0x6C, 0x4D, 0x52, 0x1A, 0xA3, 0x07,
-0x20, 0x83, 0x03, 0xF2, 0x12, 0x38, 0x88, 0xEA, 0x41, 0xCF, 0x93, 0x9A, 0xBD, 0x70, 0x66, 0x5C,
-0xB1, 0xBC, 0xA0, 0xC2, 0xA0, 0x18, 0x7B, 0xC8, 0x43, 0x79, 0x13, 0xD1, 0xD5, 0x88, 0xF3, 0x20,
-0x56, 0xEB, 0x0E, 0x3A, 0x7A, 0x06, 0xAA, 0xE5, 0x05, 0x4D, 0x4F, 0x25, 0x7A, 0x00, 0x96, 0xCD,
-0xFB, 0x00, 0x96, 0xBB, 0x21, 0x4B, 0x07, 0x14, 0x58, 0x78, 0x3E, 0x5A, 0x07, 0xD2, 0x3F, 0x39,
-0xE3, 0x8A, 0x00, 0x28, 0xF8, 0x0D, 0xDF, 0xDC, 0x34, 0x3B, 0x5F, 0x8D, 0xCB, 0xE1, 0x15, 0x5F,
-0x3C, 0xA9, 0xB7, 0x8E, 0xBE, 0xB7, 0xF6, 0x54, 0x2B, 0x26, 0x10, 0x3D, 0x00, 0xBE, 0x15, 0xE4,
-0x9A, 0x00, 0xCC, 0xF9, 0xE1, 0xA5, 0x40, 0xC8, 0x9E, 0x49, 0x02, 0x0D, 0x60, 0xE9, 0x4B, 0x58,
-0xC3, 0xD7, 0xD0, 0xB9, 0x76, 0xB7, 0xFF, 0xA6, 0xC9, 0x0D, 0x0D, 0x93, 0x19, 0x17, 0xF2, 0x33,
-0xA9, 0x6E, 0x46, 0x1F, 0x38, 0x28, 0x3B, 0x10, 0x9E, 0xC7, 0x71, 0x7F, 0xC4, 0x34, 0xF7, 0x35,
-0x66, 0xAF, 0x1D, 0x2C, 0x6D, 0x98, 0xE2, 0xBD, 0xA3, 0x07, 0xC0, 0x9C, 0x03, 0x62, 0xDE, 0x8F,
-0x80, 0xAB, 0x32, 0xD9, 0x2C, 0x4B, 0xA0, 0x06, 0x6E, 0xF3, 0x9C, 0x49, 0x1B, 0xA5, 0xA9, 0xEC,
-0x05, 0xD6, 0xE3, 0xE9, 0xE3, 0xBE, 0xAC, 0xBE, 0xE1, 0xA2, 0x91, 0x20, 0x49, 0xCA, 0x7A, 0x89,
-0x10, 0x80, 0x3C, 0x53, 0x4B, 0x27, 0xFA, 0x3E, 0x4E, 0xAC, 0xE9, 0x4E, 0x3A, 0x7B, 0x8C, 0x5B,
-0x3A, 0xB2, 0x16, 0x3D, 0x00, 0xE6, 0x24, 0xEC, 0x0C, 0xDD, 0x8D, 0xF0, 0x95, 0x50, 0xD9, 0x6E,
-0x85, 0xC1, 0x30, 0x72, 0xF9, 0x10, 0xCA, 0x6F, 0x41, 0x97, 0xE3, 0xC9, 0xB3, 0x78, 0xFD, 0xDB,
-0x79, 0xDF, 0xD0, 0x20, 0x33, 0x37, 0xB8, 0x59, 0xB2, 0x39, 0x1F, 0x00, 0xA5, 0x82, 0x5C, 0xD4,
-0x64, 0x33, 0x6E, 0x3A, 0xEE, 0xA5, 0x85, 0xEF, 0xD3, 0xDE, 0xDB, 0x17, 0x19, 0xF5, 0xCB, 0xF6,
-0x91, 0x17, 0x9B, 0x41, 0x77, 0xC7, 0x04, 0x9C, 0xC1, 0x4E, 0x44, 0x96, 0xA4, 0x3C, 0x8E, 0xA3,
-0xE7, 0xA2, 0x90, 0x13, 0x1F, 0x46, 0x79, 0x07, 0xD1, 0x75, 0x08, 0x2B, 0xB0, 0x87, 0x37, 0xD2,
-0xC6, 0x01, 0x36, 0x15, 0x31, 0x01, 0x33, 0xD3, 0xD3, 0x53, 0x4A, 0x38, 0x14, 0xFD, 0x53, 0xEE,
-0x71, 0x33, 0xAF, 0x00, 0x93, 0x67, 0x00, 0xE4, 0x46, 0xA6, 0x0C, 0xAE, 0x6A, 0x7C, 0x11, 0x64,
-0x72, 0x80, 0x4E, 0x9F, 0xFA, 0x61, 0xF0, 0x9E, 0x49, 0x45, 0xA6, 0xC6, 0x5A, 0xA3, 0x46, 0xCD,
-0x65, 0xF3, 0x9E, 0x59, 0x7F, 0x1F, 0xA2, 0x5B, 0x51, 0x56, 0xE0, 0xC9, 0x1A, 0x9A, 0x9A, 0x7E,
-0x1F, 0x78, 0x62, 0x4D, 0x8F, 0x9C, 0x07, 0x80, 0x40, 0xB0, 0x4B, 0x38, 0x10, 0x02, 0xEF, 0x62,
-0xB9, 0x9F, 0xE4, 0xDA, 0x0B, 0x5E, 0x1D, 0x15, 0x7B, 0x81, 0x1F, 0x08, 0xD7, 0x21, 0x7A, 0x11,
-0x64, 0x8C, 0xC4, 0xEE, 0x4F, 0x9D, 0x80, 0x6B, 0xF5, 0xA2, 0xF2, 0xE7, 0xF9, 0xA6, 0x91, 0xB1,
-0x76, 0x93, 0x02, 0x68, 0x9C, 0x67, 0xEB, 0xC0, 0x79, 0x8A, 0x01, 0xF7, 0x45, 0xA4, 0xBF, 0x8F,
-0xDF, 0xCD, 0x1C, 0xCA, 0x7B, 0xE0, 0xE9, 0xC2, 0xE2, 0xB4, 0x59, 0x6D, 0xC4, 0x12, 0xD3, 0xD9,
-0xEF, 0xEE, 0xE4, 0xA6, 0xD5, 0x26, 0x7D, 0xA4, 0x5A, 0x4A, 0x38, 0x63, 0xEA, 0x6A, 0x22, 0x7B,
-0x0B, 0x98, 0xDF, 0x6B, 0x0E, 0x6C, 0x91, 0xB6, 0x6A, 0x00, 0x00, 0x4B, 0x67, 0x4D, 0xC2, 0x8E,
-0xDF, 0x81, 0xCA, 0xBD, 0x26, 0x0B, 0x2E, 0x73, 0xB3, 0x89, 0xE0, 0xAA, 0x72, 0x00, 0x91, 0x57,
-0x50, 0x6F, 0x0D, 0x96, 0xB3, 0x8A, 0x43, 0xB1, 0x9D, 0x9C, 0x72, 0xA0, 0x9F, 0x8B, 0x0B, 0x64,
-0x27, 0x9B, 0x1D, 0x7E, 0xD0, 0x3E, 0x16, 0x37, 0xF6, 0x09, 0xF0, 0xAE, 0x44, 0x65, 0x3A, 0xAE,
-0x7D, 0xED, 0xA8, 0x5F, 0xA6, 0x52, 0x25, 0x9C, 0x76, 0x93, 0xA7, 0x26, 0x9A, 0xC5, 0x1C, 0xC6,
-0x12, 0xF2, 0xF4, 0x0E, 0xF6, 0x1D, 0x78, 0x94, 0x2F, 0x46, 0x9F, 0x23, 0x54, 0x1D, 0x00, 0x4C,
-0x48, 0xB0, 0x6D, 0xD7, 0x85, 0x08, 0xAB, 0x05, 0x99, 0xE4, 0x4B, 0x1C, 0xA1, 0x5F, 0x55, 0x77,
-0xA1, 0xF2, 0x02, 0x98, 0xFC, 0x50, 0x6F, 0x13, 0x83, 0x7D, 0x07, 0x59, 0xB8, 0x61, 0x30, 0xEF,
-0x61, 0xC7, 0xF8, 0x61, 0x0E, 0x0D, 0x4F, 0x24, 0xE1, 0x7C, 0x08, 0xB1, 0x2E, 0x43, 0xE5, 0x9A,
-0x91, 0xF8, 0xD6, 0x09, 0xC9, 0x02, 0x0C, 0xDD, 0x86, 0x48, 0x76, 0x89, 0x52, 0xF4, 0x66, 0x68,
-0x6A, 0xA7, 0xAB, 0xA9, 0x1D, 0xF8, 0x6B, 0xEC, 0xC4, 0x2B, 0x51, 0x07, 0x63, 0xCC, 0x07, 0xAA,
-0x03, 0x80, 0xB1, 0x5F, 0x1E, 0xBF, 0x6A, 0x3A, 0x31, 0xF7, 0xDF, 0x10, 0x2E, 0x04, 0xD9, 0x82,
-0xE8, 0x33, 0xA8, 0xD5, 0x43, 0x8B, 0xF7, 0x2E, 0x93, 0x8A, 0xEC, 0x76, 0xA3, 0xC4, 0x87, 0x0F,
-0x1F, 0x8F, 0xD8, 0x7F, 0x81, 0x70, 0x2D, 0x2A, 0x1F, 0x06, 0x3F, 0xD5, 0xC4, 0x04, 0x77, 0x0A,
-0xD7, 0x88, 0x45, 0x09, 0xC0, 0x91, 0xC0, 0x91, 0x49, 0xD8, 0xFD, 0x77, 0xEC, 0xC1, 0xBB, 0xE9,
-0x7C, 0x2E, 0x52, 0xF3, 0x33, 0xD3, 0x44, 0x8F, 0x54, 0xA6, 0x8D, 0x0E, 0xE6, 0xE7, 0xEA, 0xF4,
-0xFF, 0x29, 0xCA, 0xD1, 0xF4, 0xBB, 0xAF, 0xF8, 0xB2, 0xBD, 0xD8, 0x6E, 0x37, 0x81, 0x10, 0x77,
-0xE8, 0x2C, 0xE0, 0x72, 0x94, 0xAB, 0x11, 0x8E, 0xF3, 0x77, 0x7B, 0xFE, 0x3A, 0xB1, 0xB2, 0x92,
-0x73, 0x83, 0x16, 0x9A, 0xC7, 0x72, 0xDA, 0x87, 0x6A, 0x3B, 0xF1, 0xC4, 0x8B, 0xEF, 0xBD, 0xBC,
-0x20, 0x5F, 0x19, 0x77, 0x24, 0x77, 0x6C, 0xBE, 0xAA, 0xC4, 0x74, 0xC0, 0xBC, 0x4D, 0x4F, 0x44,
-0x4C, 0xEC, 0xC0, 0x32, 0x41, 0xF3, 0x73, 0x10, 0x26, 0xFA, 0xBB, 0x3D, 0x19, 0x04, 0x29, 0xD4,
-0x2A, 0x07, 0x20, 0x38, 0x3C, 0x6A, 0xCE, 0x1A, 0x0F, 0x63, 0x0F, 0xDC, 0x4D, 0xC7, 0x73, 0xEF,
-0xC1, 0xCC, 0xB8, 0xFC, 0xA4, 0x13, 0x1E, 0x5A, 0x14, 0x23, 0xBE, 0x63, 0x0A, 0x4D, 0xB1, 0x53,
-0xB1, 0xAD, 0xAB, 0x51, 0x9D, 0x07, 0x62, 0x7C, 0xEE, 0x26, 0x71, 0x37, 0x7F, 0x71, 0xDE, 0xD8,
-0xAD, 0x59, 0x3E, 0x00, 0xA1, 0x0E, 0x08, 0x20, 0xA2, 0x6F, 0xA9, 0xE3, 0x5D, 0xC1, 0xE1, 0x9D,
-0x5B, 0xAB, 0xE5, 0x07, 0xAA, 0x9E, 0x0E, 0xC8, 0x25, 0xBE, 0x31, 0x1F, 0xCF, 0xEC, 0x68, 0x81,
-0xC1, 0xE3, 0x70, 0xC5, 0xF8, 0x88, 0xFE, 0x1E, 0xE5, 0x54, 0x3F, 0xFE, 0x2A, 0x34, 0x85, 0x3A,
-0x31, 0x67, 0x8E, 0x59, 0xBC, 0x4E, 0xD8, 0x04, 0xD7, 0xCB, 0x6A, 0xA3, 0xD8, 0x98, 0xEC, 0x68,
-0xE1, 0x66, 0x86, 0xFA, 0x7F, 0xC2, 0x0D, 0xEB, 0x0E, 0x95, 0x35, 0x58, 0xC8, 0x97, 0xAA, 0xA3,
-0x84, 0x73, 0x3F, 0x6E, 0xF4, 0x81, 0x33, 0x7C, 0x0B, 0x78, 0xB7, 0x0A, 0x32, 0x5D, 0x95, 0x56,
-0x3F, 0x5D, 0xB1, 0xD0, 0x6E, 0x4C, 0xCF, 0x2A, 0x87, 0x90, 0x19, 0xDD, 0x23, 0xCB, 0x8E, 0xCE,
-0x31, 0x39, 0x4D, 0x72, 0x90, 0x09, 0x55, 0xAE, 0x44, 0xF5, 0x96, 0xFF, 0x1F, 0xF5, 0x01, 0x06,
-0x0C, 0xDF, 0x2C, 0x7D, 0xF3, 0x2C, 0x24, 0x6E, 0x12, 0x75, 0x8B, 0x46, 0xCA, 0x42, 0xFA, 0x2D,
-0xCA, 0x17, 0x41, 0x19, 0x85, 0x92, 0xB9, 0xFB, 0x44, 0x50, 0x55, 0xE4, 0x75, 0x1C, 0xEF, 0x72,
-0xB6, 0xD7, 0xA6, 0x6A, 0xB2, 0x36, 0x1C, 0xE0, 0x83, 0x30, 0xA7, 0x85, 0x49, 0x72, 0x89, 0xA8,
-0x2C, 0x55, 0x7C, 0x45, 0x5B, 0x49, 0x8B, 0x8C, 0x03, 0xB2, 0x27, 0xA1, 0xBB, 0xB1, 0xBC, 0xCB,
-0xB1, 0x26, 0x98, 0x02, 0xEE, 0x9A, 0x14, 0xEA, 0xD5, 0x0E, 0x00, 0xBF, 0x30, 0xFB, 0x92, 0x49,
-0x38, 0x2D, 0x8B, 0x41, 0x4C, 0xCD, 0x40, 0x56, 0xCE, 0x68, 0x18, 0xB9, 0x5D, 0x54, 0x04, 0x85,
-0x3D, 0x07, 0x14, 0x16, 0x7B, 0x87, 0xF1, 0xF4, 0x6F, 0x88, 0x27, 0x56, 0xD5, 0xB2, 0x7A, 0xBE,
-0x76, 0x00, 0x98, 0xAD, 0x66, 0xEA, 0xC5, 0xCE, 0xDC, 0x74, 0x0C, 0x4E, 0xEC, 0x39, 0x90, 0xB3,
-0x33, 0x0F, 0x82, 0xA1, 0x8C, 0x93, 0x74, 0xA7, 0x4A, 0x83, 0xF2, 0x99, 0xA7, 0xA0, 0xA4, 0x9E,
-0x71, 0x11, 0x59, 0x41, 0x33, 0x8B, 0xB8, 0xF2, 0xA9, 0xFD, 0xD5, 0x0E, 0x43, 0x66, 0xDB, 0x13,
-0x95, 0x08, 0x82, 0x72, 0xDE, 0x35, 0x09, 0x50, 0x6F, 0x4F, 0x39, 0x17, 0xF1, 0x1D, 0x5C, 0x53,
-0xCB, 0x19, 0xC2, 0x0F, 0x49, 0x96, 0x73, 0x57, 0x44, 0xA1, 0x8F, 0x09, 0x3B, 0x40, 0x3E, 0x8E,
-0x1D, 0xDF, 0x51, 0x0D, 0x77, 0x43, 0xB1, 0x35, 0xD6, 0x96, 0x03, 0xD2, 0x33, 0x49, 0xC6, 0x0C,
-0xBA, 0x40, 0xBE, 0x54, 0xF4, 0x62, 0x8E, 0xC2, 0x6C, 0x11, 0x89, 0x0E, 0x48, 0x0D, 0x3F, 0x84,
-0xF0, 0x59, 0x66, 0x1C, 0xDB, 0xC3, 0x05, 0x4B, 0x6A, 0x52, 0x1B, 0x5C, 0x5F, 0x0E, 0xF0, 0x45,
-0x91, 0x39, 0x17, 0xCC, 0x3E, 0x06, 0x27, 0xBE, 0x71, 0x24, 0xE5, 0xEF, 0x48, 0x02, 0x57, 0x58,
-0x76, 0x28, 0x22, 0x82, 0x72, 0xAF, 0x2A, 0x28, 0x88, 0x61, 0xB2, 0x26, 0xCC, 0x98, 0x3D, 0x9B,
-0x19, 0x94, 0x4B, 0x59, 0x58, 0x5B, 0xD1, 0x93, 0x29, 0x05, 0xC3, 0x2E, 0x3B, 0xDA, 0x7E, 0x26,
-0x70, 0x73, 0xDA, 0xA4, 0xCF, 0x63, 0xCB, 0x83, 0x45, 0x6F, 0x49, 0xC9, 0x67, 0x36, 0x06, 0xE5,
-0x86, 0x86, 0x9E, 0xA9, 0x0E, 0x20, 0xD6, 0xA7, 0xF8, 0xCD, 0x9F, 0xAD, 0x8F, 0x3A, 0xE1, 0x2A,
-0xEC, 0x14, 0xEA, 0x23, 0x82, 0xCC, 0xEC, 0x92, 0xD7, 0x92, 0x4D, 0xC5, 0x19, 0xDA, 0x88, 0x30,
-0xA3, 0xA4, 0xD3, 0x70, 0x11, 0x00, 0xC4, 0x2B, 0x7E, 0x59, 0x47, 0x06, 0x61, 0x4C, 0xD6, 0xC3,
-0x26, 0xEC, 0xFD, 0x97, 0x56, 0xBB, 0x16, 0xB8, 0xF1, 0x74, 0x40, 0x7A, 0x46, 0x46, 0x14, 0x9D,
-0x31, 0xF7, 0x56, 0x3C, 0xEB, 0xDB, 0x25, 0xDD, 0x9A, 0x12, 0x92, 0x03, 0xC6, 0x88, 0x9F, 0xAC,
-0x3F, 0xA8, 0x89, 0x43, 0x74, 0x72, 0x5D, 0xEF, 0xEA, 0x5A, 0x5A, 0x3D, 0x63, 0x0F, 0x7F, 0x61,
-0x79, 0xA5, 0x5A, 0xFD, 0x92, 0x69, 0x2C, 0x9B, 0x46, 0x3C, 0x8F, 0xEF, 0x2F, 0x81, 0x0B, 0xCA,
-0xB7, 0x82, 0x7C, 0x10, 0xC4, 0xF8, 0xF9, 0xB7, 0x62, 0x1F, 0xFA, 0x4B, 0x3A, 0xFF, 0x23, 0x79,
-0xF3, 0x62, 0x9D, 0x5A, 0xFD, 0x44, 0x50, 0x7A, 0xC1, 0xA6, 0xBA, 0xF1, 0x89, 0x5F, 0x3C, 0x84,
-0xB0, 0x30, 0x48, 0x17, 0xF8, 0xAF, 0x24, 0x77, 0x71, 0x51, 0x00, 0x82, 0xCF, 0x14, 0x32, 0x8C,
-0x7A, 0xF7, 0x71, 0x7D, 0xEF, 0xD7, 0x82, 0x13, 0x22, 0xAA, 0x8B, 0x4C, 0xFD, 0x01, 0x30, 0xEB,
-0x5B, 0x76, 0xE5, 0xF9, 0x88, 0xF7, 0x9F, 0x45, 0xEF, 0x92, 0xC8, 0xA6, 0x6A, 0x25, 0x1C, 0x60,
-0xB2, 0xEB, 0xF6, 0xA1, 0xCE, 0x05, 0x5C, 0xBF, 0x66, 0x7B, 0x75, 0xC9, 0x1B, 0x3C, 0x7A, 0x63,
-0x00, 0x90, 0x0C, 0xE2, 0xBF, 0x80, 0xCA, 0x87, 0x02, 0xEF, 0x11, 0x4A, 0xCE, 0xD8, 0xE4, 0x86,
-0xCE, 0x1E, 0x73, 0x6D, 0xA5, 0xB9, 0xE1, 0x24, 0x59, 0xD5, 0x32, 0xB6, 0x1D, 0x39, 0x45, 0x9B,
-0xEA, 0x99, 0x97, 0xE8, 0xF3, 0x2E, 0x19, 0xCD, 0xAA, 0x08, 0xA6, 0x53, 0xD5, 0x7A, 0x34, 0x06,
-0x00, 0xFE, 0xB5, 0x95, 0x73, 0xEF, 0x47, 0xE4, 0x32, 0x14, 0x7B, 0x4C, 0xA4, 0x3A, 0xED, 0x96,
-0x1E, 0x25, 0xA2, 0xBE, 0x81, 0xED, 0xFC, 0xED, 0x68, 0xD9, 0xA8, 0xEF, 0xEE, 0xEE, 0xBF, 0x1E,
-0xEC, 0xDB, 0x90, 0x02, 0x85, 0x81, 0xA6, 0x04, 0x35, 0x59, 0x8A, 0xEA, 0x20, 0xDA, 0xCD, 0xA7,
-0x7B, 0x0D, 0x58, 0x75, 0x6F, 0x8D, 0x01, 0x80, 0x21, 0x83, 0x29, 0x80, 0x38, 0xAE, 0x2D, 0x4E,
-0xDF, 0x60, 0xF0, 0x9C, 0x26, 0x26, 0x4C, 0x81, 0xC5, 0x50, 0x86, 0xDB, 0x40, 0xF8, 0xF9, 0xA2,
-0x18, 0xDB, 0xF7, 0x26, 0x02, 0xDF, 0x9F, 0x98, 0x30, 0x70, 0x9A, 0x77, 0x6B, 0xE2, 0xED, 0x0C,
-0x42, 0x38, 0x78, 0xB1, 0x41, 0x23, 0x8C, 0x3F, 0xAF, 0x88, 0x02, 0xE3, 0x00, 0x54, 0x44, 0xBE,
-0xCA, 0x5F, 0x6E, 0x1C, 0x00, 0x8C, 0x1E, 0x78, 0xB2, 0xFD, 0x24, 0x6C, 0x6D, 0xC1, 0xC9, 0xC9,
-0x1C, 0xAD, 0x7C, 0x9D, 0xC9, 0x11, 0x5C, 0x51, 0x12, 0xDE, 0xC1, 0xD1, 0x4B, 0xBF, 0xA3, 0x1A,
-0xB7, 0x82, 0x71, 0x1A, 0x07, 0x80, 0x6E, 0x6C, 0x9C, 0xF6, 0xA5, 0xBE, 0x9B, 0x59, 0x35, 0x79,
-0x83, 0x6E, 0x90, 0x41, 0x9F, 0xF9, 0x3C, 0xB7, 0x6F, 0xDE, 0x67, 0x62, 0xBC, 0x9D, 0x8F, 0x33,
-0x7F, 0x95, 0xB9, 0xBB, 0xAE, 0x21, 0x5A, 0xE3, 0x00, 0x60, 0xC8, 0xB1, 0xBC, 0xFD, 0x01, 0x84,
-0x9B, 0xD2, 0x69, 0xED, 0x91, 0x53, 0xC8, 0x5C, 0x39, 0xA0, 0xDC, 0xCF, 0xFC, 0x55, 0xF7, 0x44,
-0x3E, 0x76, 0x99, 0x03, 0x36, 0x16, 0x00, 0x4F, 0xCC, 0xBD, 0x07, 0xC4, 0xFC, 0x06, 0x40, 0xF6,
-0x1D, 0x13, 0x19, 0x8B, 0x4B, 0x7A, 0x12, 0x02, 0xCE, 0xAF, 0x05, 0x9E, 0x0B, 0x0C, 0x28, 0xBA,
-0x98, 0xF9, 0xBD, 0xDF, 0x2D, 0x93, 0x5E, 0x91, 0xBF, 0xD6, 0x68, 0x00, 0x7C, 0x01, 0x95, 0xAF,
-0x8E, 0x02, 0x90, 0xBE, 0xC7, 0xCD, 0x2C, 0x3B, 0x5F, 0x26, 0x5B, 0xEE, 0xDF, 0x82, 0xF2, 0x81,
-0x44, 0x07, 0x46, 0x8A, 0xB5, 0xEF, 0xE4, 0xFA, 0xDE, 0x27, 0x23, 0xA7, 0x64, 0x99, 0x03, 0x36,
-0x16, 0x00, 0x8F, 0x5C, 0x39, 0x05, 0xDB, 0x9D, 0x4A, 0x93, 0x5D, 0x2C, 0x2D, 0xB1, 0xCC, 0xA5,
-0x1A, 0xEB, 0xDF, 0xF5, 0x98, 0x2C, 0xEF, 0x44, 0x5D, 0x66, 0x54, 0xFE, 0x84, 0xAA, 0x95, 0x1D,
-0x5D, 0xFE, 0x8C, 0x84, 0x2E, 0xA3, 0x7A, 0xBB, 0xCA, 0x1F, 0xA1, 0xE8, 0x9B, 0x23, 0xE3, 0x76,
-0xF9, 0xBC, 0x14, 0xC4, 0x2B, 0x55, 0xFA, 0xFE, 0xD8, 0x61, 0x1B, 0x8B, 0x03, 0x6A, 0xB6, 0xEC,
-0xC6, 0xF9, 0x50, 0x63, 0x01, 0xB0, 0x7C, 0xCE, 0x59, 0x08, 0x1F, 0x0B, 0xE5, 0x96, 0x2E, 0x87,
-0x86, 0xA6, 0xDA, 0x65, 0x48, 0x9F, 0xE7, 0xC6, 0xA7, 0x7F, 0x5F, 0xCE, 0xEB, 0xD5, 0x78, 0xA7,
-0xC1, 0x00, 0x68, 0xBF, 0x69, 0xE4, 0xCA, 0x00, 0x73, 0xD1, 0x53, 0x41, 0x2B, 0x28, 0x97, 0x08,
-0xE9, 0x05, 0x84, 0x93, 0x29, 0x3A, 0x80, 0xA7, 0x5F, 0xE0, 0x33, 0xAB, 0x9F, 0xAE, 0x06, 0x31,
-0xCB, 0x19, 0xB3, 0xB1, 0x00, 0x78, 0xA2, 0xFD, 0x8B, 0xA8, 0xDE, 0x0F, 0xD2, 0x5C, 0xCE, 0x62,
-0x02, 0xDF, 0x31, 0x59, 0xCF, 0x2A, 0x37, 0x30, 0xFF, 0xA9, 0x9F, 0x04, 0xF6, 0xAD, 0x51, 0x87,
-0xC6, 0x02, 0x60, 0x79, 0xFB, 0x2D, 0xA0, 0xDF, 0x89, 0x12, 0x80, 0xAC, 0x23, 0xC1, 0x38, 0x00,
-0x01, 0xDB, 0x2A, 0x17, 0x80, 0xA0, 0x03, 0x57, 0xA9, 0xBB, 0xD4, 0xFC, 0x82, 0x92, 0x8C, 0x73,
-0x40, 0x61, 0xB2, 0x3D, 0xD9, 0x7E, 0x0B, 0x5E, 0x06, 0x07, 0x44, 0x0D, 0xC0, 0x38, 0x07, 0x54,
-0xCE, 0x01, 0x15, 0x61, 0xE2, 0x57, 0xBE, 0xE8, 0x02, 0xAE, 0xEB, 0x5D, 0x51, 0x2A, 0xF3, 0x54,
-0xAB, 0x7F, 0x63, 0xE9, 0x80, 0xA5, 0xED, 0xD7, 0x60, 0xE9, 0xA3, 0x11, 0xFE, 0xD0, 0x43, 0x2E,
-0xDD, 0xFA, 0xB0, 0xB5, 0x9D, 0x6B, 0x7B, 0xCD, 0xA5, 0xB2, 0x0D, 0xD1, 0x1A, 0x0B, 0x80, 0xE5,
-0x73, 0x4D, 0xF5, 0x8C, 0x89, 0x0D, 0x9B, 0x3A, 0xB2, 0x53, 0x7C, 0x73, 0x34, 0xCC, 0x96, 0xCF,
-0xB9, 0x93, 0x3A, 0x47, 0xF1, 0x1A, 0x0B, 0xD5, 0x5C, 0xB6, 0xFA, 0xBF, 0x28, 0x2F, 0xD2, 0x6C,
-0xDD, 0xC5, 0xBC, 0x95, 0xEF, 0x36, 0x04, 0xF5, 0xAB, 0x56, 0xA8, 0x5D, 0xEE, 0xEA, 0x4C, 0xFD,
-0xC0, 0xE9, 0x9B, 0xCD, 0x75, 0xC7, 0xC7, 0x22, 0xF6, 0x23, 0xA8, 0x9A, 0xBB, 0x26, 0x82, 0x7E,
-0xD6, 0x30, 0xE8, 0x6B, 0x2E, 0xE8, 0x7F, 0x61, 0xB9, 0x37, 0xE3, 0x59, 0xBB, 0x6B, 0x51, 0xF7,
-0x15, 0x34, 0xA1, 0xCC, 0xE7, 0x8D, 0xC5, 0x01, 0xE9, 0x99, 0x99, 0x9A, 0xB2, 0x89, 0x7F, 0xF8,
-0x47, 0xD0, 0x2F, 0x09, 0xD2, 0x1C, 0xEE, 0x90, 0x55, 0x60, 0xD9, 0x62, 0x7E, 0x2D, 0xCF, 0xFB,
-0x26, 0xDB, 0xFA, 0xBE, 0x51, 0x8D, 0xEB, 0xE7, 0x4B, 0x21, 0x76, 0xBE, 0xBE, 0x8D, 0x09, 0x80,
-0x99, 0xE9, 0xD2, 0xF6, 0xB3, 0xB1, 0x78, 0x2E, 0x55, 0xD4, 0x97, 0x75, 0xE1, 0x87, 0xBF, 0x90,
-0x7C, 0xA2, 0x29, 0xFD, 0xB7, 0xD1, 0x67, 0xFE, 0x7D, 0xE8, 0xBB, 0xB0, 0x9C, 0xCB, 0xB8, 0x6E,
-0xCD, 0xAF, 0x2B, 0x25, 0x56, 0x35, 0xDE, 0x6F, 0x5C, 0x00, 0x4C, 0x51, 0xDF, 0x44, 0xEB, 0x4E,
-0x94, 0xAF, 0xA4, 0x7E, 0x61, 0x75, 0x0C, 0xD1, 0x03, 0xDD, 0x10, 0xFE, 0xAF, 0x21, 0xE9, 0x77,
-0x68, 0xD3, 0x6F, 0x32, 0x27, 0x75, 0xB5, 0x4D, 0x35, 0xA8, 0x58, 0xC1, 0x98, 0x8D, 0x0B, 0x80,
-0xCF, 0x05, 0xF3, 0x4E, 0xC2, 0x76, 0x1F, 0xF0, 0xB3, 0xE0, 0x32, 0x15, 0x72, 0x21, 0xC5, 0x9C,
-0xFD, 0xF7, 0x21, 0x30, 0x77, 0x47, 0x7B, 0x37, 0xD1, 0xD9, 0x38, 0xCE, 0xB7, 0x5C, 0xAC, 0x1A,
-0x1B, 0x00, 0xBF, 0xA8, 0xEF, 0xE5, 0x19, 0xB8, 0x18, 0xFF, 0xD0, 0x27, 0x51, 0x8C, 0x8F, 0xE8,
-0xC8, 0x9C, 0xF3, 0x8B, 0x21, 0x93, 0xFB, 0x69, 0x92, 0xAE, 0x7E, 0x46, 0x8C, 0xBF, 0x63, 0xEB,
-0x79, 0xAF, 0xD5, 0xAB, 0xF8, 0x22, 0x0C, 0x63, 0x34, 0x36, 0x00, 0x66, 0x05, 0x3E, 0x08, 0x9B,
-0x3F, 0x80, 0x63, 0x2D, 0x1C, 0xB9, 0x3A, 0xEC, 0xD6, 0x11, 0x33, 0xB5, 0xAD, 0xC0, 0x0D, 0x2A,
-0x26, 0x54, 0x6C, 0x12, 0x5A, 0x0E, 0xA3, 0x3C, 0x86, 0x65, 0xFD, 0x00, 0x2B, 0xF6, 0x46, 0xAD,
-0x8B, 0xEE, 0xC2, 0x10, 0xBD, 0xF1, 0xAD, 0xA0, 0x7C, 0xAB, 0x58, 0x35, 0x77, 0x22, 0x7D, 0x9C,
-0x83, 0xC5, 0x55, 0x88, 0x5C, 0xED, 0x5F, 0x83, 0x73, 0xC4, 0x44, 0x35, 0x37, 0x9B, 0xEC, 0x45,
-0x59, 0x8D, 0xB2, 0x12, 0x9C, 0xCD, 0xCC, 0x5F, 0xB3, 0xAF, 0x9E, 0x85, 0x17, 0x61, 0x81, 0x68,
-0x7C, 0x0E, 0xC8, 0x5C, 0x49, 0xFA, 0x8A, 0x9B, 0x56, 0xE7, 0x28, 0xEC, 0xA6, 0x0F, 0xE2, 0xE9,
-0x71, 0xA8, 0x28, 0x71, 0xDD, 0x49, 0x2C, 0xF6, 0x3B, 0x0E, 0x1D, 0xDC, 0xCB, 0x82, 0x75, 0xE6,
-0xA2, 0x8D, 0x8A, 0x2C, 0xD7, 0xB0, 0xC4, 0x8B, 0xA2, 0xDF, 0x7B, 0x0B, 0x80, 0x28, 0x56, 0xDC,
-0x60, 0x63, 0x8C, 0x03, 0x50, 0x67, 0x40, 0xC6, 0x01, 0x18, 0x07, 0xA0, 0xCE, 0x14, 0xA8, 0xF3,
-0xE7, 0xFF, 0x0F, 0xB7, 0x80, 0x16, 0xCA, 0xD9, 0x27, 0x5C, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x49,
-0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
-};
\ No newline at end of file
diff --git a/src/www/setupPage.html b/src/www/setupPage.html
index 64a531b..9e1273f 100644
--- a/src/www/setupPage.html
+++ b/src/www/setupPage.html
@@ -5,439 +5,556 @@
BLLED Setup
-
+
+
Firmware version: ??.??.??
βΉοΈPlaceholder
+
+
+
+
+
- document.querySelectorAll("details.collapse").forEach((detail) => {
- detail.addEventListener("toggle", function () {
- if (detail.open) {
- document.querySelectorAll("details.collapse").forEach((other) => {
- if (other !== detail) other.removeAttribute("open");
- });
+
+
+
diff --git a/src/www/setupPageOld.html b/src/www/setupPageOld.html
index 031c72f..9031f9b 100644
--- a/src/www/setupPageOld.html
+++ b/src/www/setupPageOld.html
@@ -3,8 +3,8 @@
-
-
+
+
BLLED Setup
+
@@ -147,12 +13,11 @@