diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c89b737..4fa5175 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -45,13 +45,16 @@ jobs:
path: |
~/.platformio/packages
~/.platformio/platforms
+ .ccache
${{ matrix.cache_extra }}
key: pio-${{ matrix.group }}-${{ hashFiles('platformio.ini') }}
restore-keys: |
pio-${{ matrix.group }}-
- - name: Install PlatformIO + esptool
+ - name: Install PlatformIO + esptool + ccache
run: |
+ sudo apt update
+ sudo apt install ccache
python -m pip install --upgrade pip
pip install --upgrade platformio esptool
@@ -62,7 +65,7 @@ jobs:
for env in $ENVS; do
CMD="$CMD -e $env"
done
- eval "$CMD" || (sleep 25 && echo "🔄 Retry for ${{ matrix.group }} (network?)" && eval "$CMD")
+ eval "$CMD"
- name: "Upload Artifacts - ${{ matrix.group }}"
uses: actions/upload-artifact@v7
diff --git a/.gitignore b/.gitignore
index b5273f7..47f9315 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,7 @@ include/web_resources.h
release/
managed_components/
sdkconfig*
+ccache.exe
+.ccache/
+CMakeLists.txt
+dependencies.lock
diff --git a/data/css/settings.css b/data/css/settings.css
index 8ee7812..84ed4e8 100644
--- a/data/css/settings.css
+++ b/data/css/settings.css
@@ -125,3 +125,10 @@ details summary[role="button"]:focus {
opacity: 0.6;
transition: opacity 0.2s ease;
}
+
+#btn-switch-ap {
+ background-color: #eab308;
+ border-color: #eab308;
+ color: #111111;
+ font-weight: bold;
+}
diff --git a/data/gpio.js b/data/gpio.js
index e0e85f7..afc2fb4 100644
--- a/data/gpio.js
+++ b/data/gpio.js
@@ -1,14 +1,16 @@
function setupPinValidator() {
const hardwareLimits = {
- "ESP32-C6": { gpio: [0,1,2,3,4,5,6,7,8,10,15,18,19,20,21,22], spi: {6:5} },
- "ESP32-S3": { gpio: [1,2,4,5,6,7,8,10,16,17,18,48], spi: {11:12} }, // GPIO48 = built-in WS2812B
+ "ESP32-C6": { gpio: [0,1,2,3,4,5,6,7,8,10,15,18,19,20,21,22], spi: {5:4} },
+ "ESP32-S3": { gpio: [1,2,4,5,6,7,8,10,16,17,18,48], spi: {5:4} }, // GPIO48 = built-in WS2812B
"ESP32-C3": { gpio: [0,1,2,3,4,5,6,7,8,10,20,21], spi: {7:6} }, // GPIO08 = built-in WS2812B
- "ESP8266": { gpio: [2], spi: {19:18} },
+ "ESP8266": { gpio: [2], spi: {13:14} },
"ESP32": { gpio: null, spi: {23:18} },
- "ESP32-S2": { gpio: null, spi: {11:7} },
- "ESP32-ETH01": { gpio: [2,4,14], spi: {4:14} },
- "ESP32-C2": { gpio: [0,1,2,3,4,5,6,7,10], spi: {7:6} },
- "ESP32-C5": { gpio: [0,1,2,3,4,5,6,7,8,10,11,27], spi: {7:6} } // GPIO27 = built-in WS2812B
+ "ESP32-S2": { gpio: null, spi: {35:36} },
+ "ESP32-ETH01": { gpio: [2,4], spi: {2:4} },
+ "ESP32-C2": { gpio: [0,1,2,3,4,5,6,7,10], spi: {7:6} },
+ "ESP32-C5": { gpio: [0,1,2,3,4,5,6,7,8,10,11,27], spi: {7:6} }, // GPIO27 = built-in WS2812B
+ "RP2040": { gpio: null, spi: {19:18} },
+ "RP2350": { gpio: null, spi: {19:18} }
};
const arch = (typeof cfgDeviceArchitecture !== 'undefined') ? cfgDeviceArchitecture : "";
diff --git a/data/network.js b/data/network.js
new file mode 100644
index 0000000..c99b7be
--- /dev/null
+++ b/data/network.js
@@ -0,0 +1,52 @@
+function promptSwitchToAP() {
+ const dialog = document.createElement('dialog');
+ dialog.innerHTML = `
+
+ ⚠️ Switch to AP Mode
+ This will reset Hyperk WiFi password and switch to AP after reboot. Are you sure?
+
+
+ `;
+ document.body.appendChild(dialog);
+ dialog.showModal();
+
+ dialog.querySelector('#ap-cancel').addEventListener('click', () => {
+ dialog.close();
+ dialog.remove();
+ });
+
+ dialog.querySelector('#ap-confirm').addEventListener('click', async (e) => {
+ const btn = e.target;
+ btn.setAttribute('aria-busy', 'true');
+
+ try {
+ const params = new URLSearchParams();
+ params.append('reset_wifi', cfgSSID);
+
+ const res = await fetch('/save_config', {
+ method: 'POST',
+ body: params
+ });
+
+ if (res.ok) {
+ const data = await res.json();
+ showToast(data.status === 'reboot');
+ }
+ } catch (err) {
+ alert("Error!");
+ } finally {
+ dialog.close();
+ dialog.remove();
+ }
+ });
+}
+
+function setupNetwork() {
+ const apBtn = document.getElementById('btn-switch-ap');
+ if (apBtn) {
+ apBtn.addEventListener('click', promptSwitchToAP);
+ }
+}
diff --git a/data/settings.html b/data/settings.html
index 5261cf1..2a79ab7 100644
--- a/data/settings.html
+++ b/data/settings.html
@@ -110,7 +110,7 @@
White channel calibration
-
+
Network
+
+
+
@@ -192,6 +195,7 @@ ⚠️ OTA Firmware Flash Procedure
let cfgDeviceArchitecture = "";
let cfgBoardArchitecture = ""
let cfgDeviceVersion = "";
+ let cfgSSID = "";
const loadedScripts = {};
function loadSubScript(scriptName, initFunName) {
@@ -245,6 +249,11 @@ ⚠️ OTA Firmware Flash Procedure
const c = await res.json();
const l = c.config;
+ const SSIDField = l["ssid"];
+ if (SSIDField !== undefined){
+ cfgSSID = SSIDField;
+ }
+
const archField = l["architecture"];
if (archField !== undefined){
cfgDeviceArchitecture = archField;
diff --git a/include/leds.h b/include/leds.h
index da9c17f..b18fad3 100644
--- a/include/leds.h
+++ b/include/leds.h
@@ -4,12 +4,16 @@
#include
#include "config.h"
+#if !(defined(USE_FASTLED) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_RP2350))
+ #define LEDS_NOT_REQUIRE_RESTART
+#endif
+
namespace Leds {
void applyLedConfig();
int getLedsNumber();
- void checkDeleyedRender();
+ void checkDelayedRender();
void renderLed(bool isNewFrame);
- void synchronizeLedsToVolatileStateBeforeDeleyedRender();
+ void synchronizeLedsToVolatileStateBeforeDelayedRender();
template
void setLed(int index, uint8_t r, uint8_t g, uint8_t b);
diff --git a/platformio.ini b/platformio.ini
index ec84a2a..7ed5b00 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -4,6 +4,7 @@ framework = arduino
monitor_speed = 115200
board_build.filesystem = littlefs
extra_scripts =
+ pre:scripts/enable_ccache.py
pre:scripts/get_version.py
pre:scripts/web_embedder.py
post:scripts/collect_firmware.py
diff --git a/readme.md b/readme.md
index e2d93e8..69b6b20 100644
--- a/readme.md
+++ b/readme.md
@@ -1,6 +1,6 @@
# Hyperk
-Hyperk is a minimalist, high-performance uni-platform WiFi LED driver for ESP8266, ESP32 (S2, S3, C3, C6), Raspberry Pi Pico W (RP2040, RP2350). Designed as a lightweight and streamlined component that avoids unnecessary complexity, it delivers low‑latency performance and integrates smoothly with platforms such as HyperHDR, while offering essential home‑automation capabilities through a clean, modern codebase.
+Hyperk is a minimalist, high-performance uni-platform WiFi LED driver for ESP8266, ESP32 (S2, S3, C2, C3, C5, C6), Raspberry Pi Pico W (RP2040, RP2350). Designed as a lightweight and streamlined component that avoids unnecessary complexity, it delivers low‑latency performance and integrates smoothly with platforms such as HyperHDR, while offering essential home‑automation capabilities through a clean, modern codebase.
## Installation
diff --git a/scripts/enable_ccache.py b/scripts/enable_ccache.py
new file mode 100644
index 0000000..c31fdc5
--- /dev/null
+++ b/scripts/enable_ccache.py
@@ -0,0 +1,36 @@
+import os
+import sys
+
+Import("env")
+
+pio_env = env.get("PIOENV", "default")
+ccache_dir = os.path.join(env["PROJECT_DIR"], ".ccache", pio_env)
+os.makedirs(ccache_dir, exist_ok=True)
+
+os.environ["CCACHE_DIR"] = ccache_dir
+env.Append(ENV={"CCACHE_DIR": ccache_dir})
+
+if sys.platform.startswith("win32"):
+ local = os.path.join(env["PROJECT_DIR"], "ccache.exe")
+ ccache_cmd = f'"{local}"' if os.path.exists(local) else "ccache"
+else:
+ ccache_cmd = "ccache"
+
+print(f"\n[ccache] === {pio_env.upper()} ===")
+print(f"[ccache] DIR: {ccache_dir}")
+print(f"[ccache] CMD: {ccache_cmd}")
+
+for var in ("CCCOM", "CXXCOM", "ASCOM"):
+ if var in env:
+ old = env[var]
+ env[var] = f"{ccache_cmd} {old}"
+ print(f"[ccache] Wrapped {var} → {env[var]}")
+
+os.environ.update({
+ "CCACHE_SLOPPINESS": "pch_defines,time_macros,include_file_mtime,include_file_ctime,file_macro,locale",
+ "CCACHE_COMPRESS": "1",
+ "CCACHE_COMPRESSLEVEL": "6",
+ "CCACHE_MAXSIZE": "200M",
+ "CCACHE_BASEDIR": env["PROJECT_DIR"]
+})
+env.Append(ENV=dict(os.environ))
diff --git a/src/leds.cpp b/src/leds.cpp
index 491b3d0..4eced3e 100644
--- a/src/leds.cpp
+++ b/src/leds.cpp
@@ -39,31 +39,35 @@
#include
#if defined(CONFIG_IDF_TARGET_ESP32C6)
- typedef NeoPixelBus DotStar;
+ typedef NeoPixelBus DotStar;
typedef NeoPixelBus NeoPixel;
typedef NeoPixelBus NeoPixelRgbw;
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
- typedef NeoPixelBus DotStar;
+ typedef NeoPixelBus DotStar;
typedef NeoPixelBus NeoPixel;
typedef NeoPixelBus NeoPixelRgbw;
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
- typedef NeoPixelBus DotStar;
+ typedef NeoPixelBus DotStar;
typedef NeoPixelBus NeoPixel;
typedef NeoPixelBus NeoPixelRgbw;
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
- typedef NeoPixelBus DotStar;
+ typedef NeoPixelBus DotStar;
typedef NeoPixelBus NeoPixel;
typedef NeoPixelBus NeoPixelRgbw;
#elif defined(ARDUINO_ARCH_ESP32)
- typedef NeoPixelBus DotStar;
- typedef NeoPixelBus NeoPixel;
- typedef NeoPixelBus NeoPixelRgbw;
+ #if defined(ETH_PHY_TYPE) && (ETH_PHY_TYPE == ETH_PHY_LAN8720)
+ typedef NeoPixelBus DotStar;
+ #else
+ typedef NeoPixelBus DotStar;
+ #endif
+ typedef NeoPixelBus NeoPixel;
+ typedef NeoPixelBus NeoPixelRgbw;
#elif defined(ARDUINO_ARCH_ESP8266)
- typedef NeoPixelBus DotStar;
+ typedef NeoPixelBus DotStar;
typedef NeoPixelBus NeoPixel;
typedef NeoPixelBus NeoPixelRgbw;
#else // Raspberry Pi Pico
- typedef NeoPixelBus DotStar;
+ typedef NeoPixelBus DotStar;
typedef NeoPixelBus NeoPixel;
typedef NeoPixelBus NeoPixelRgbw;
#endif
@@ -86,7 +90,9 @@
//////////////////////////////////////////////////////////////////////////////////////////////////
namespace Leds{
+ bool ledDriverInitialized = false;
volatile bool delayedRender = false;
+ uint16_t briPlus = 256;
int getLedsNumber()
{
@@ -113,7 +119,7 @@ namespace Leds{
return;
if (dotstar != nullptr)
- {dotstar->ClearTo(RgbwColor(0, 0, 0, 31)); dotstar->Show();}
+ {dotstar->ClearTo(RgbColor(0, 0, 0)); dotstar->Show();}
else if (neopixel != nullptr)
{neopixel->ClearTo(RgbColor(0, 0, 0)); neopixel->Show();}
else if (neopixelRgbw != nullptr)
@@ -140,7 +146,7 @@ namespace Leds{
return true;
}
- void synchronizeLedsToVolatileStateBeforeDeleyedRender()
+ void synchronizeLedsToVolatileStateBeforeDelayedRender()
{
if (delayedRender || !canRender())
return;
@@ -150,9 +156,7 @@ namespace Leds{
{
updated = true;
Log::debug("Updating brightness to: ", Volatile::state.brightness);
- #ifdef USE_FASTLED
- FastLED.setBrightness(Volatile::state.brightness);
- #endif
+ briPlus = Volatile::state.brightness + 1;
}
if (Volatile::clearUpdatedPowerOnState())
@@ -172,33 +176,15 @@ namespace Leds{
auto r = (Volatile::state.on) ? Volatile::state.staticColor.red : 0;
auto g = (Volatile::state.on) ? Volatile::state.staticColor.green : 0;
auto b = (Volatile::state.on) ? Volatile::state.staticColor.blue : 0;
+
+ for(int i = 0; i < getLedsNumber(); i++) {
+ if (Volatile::state.brightness != 255)
+ setLed(i, r, g, b);
+ else
+ setLed(i, r, g, b);
+ }
- #ifdef USE_FASTLED
- fill_solid(leds, getLedsNumber(), CRGB(r, g, b));
- FastLED.show();
- #else
- if (dotstar == nullptr && neopixel == nullptr && neopixelRgbw == nullptr)
- return;
-
- if (dotstar != nullptr) {
- RgbwColor col(r, g, b, 31);
- col = col.Dim(Volatile::state.brightness);
- dotstar->ClearTo(col);
- dotstar->Show();
- }
- else if (neopixel != nullptr) {
- RgbColor col(r, g, b);
- col = col.Dim(Volatile::state.brightness);
- neopixel->ClearTo(col);
- neopixel->Show();
- }
- else if (neopixelRgbw != nullptr) {
- RgbwColor col(r, g, b, 0);
- col = col.Dim(Volatile::state.brightness);
- neopixelRgbw->ClearTo(col);
- neopixelRgbw->Show();
- }
- #endif
+ renderLed(true);
}
}
@@ -206,12 +192,17 @@ namespace Leds{
uint8_t calGain, uint8_t calRed, uint8_t calGreen, uint8_t calBlue) {
clearAll();
- #ifdef USE_FASTLED
- if (FastLED.count())
+ #ifndef LEDS_NOT_REQUIRE_RESTART
+ if (ledDriverInitialized)
{
+ if (cfgLedType == LedType::SK6812) {
+ setParamsAndPrepareCalibration(calGain, calRed, calGreen, calBlue);
+ }
return;
}
+ #endif
+ #ifdef USE_FASTLED
if (leds != nullptr)
{
delete[] leds;
@@ -243,10 +234,9 @@ namespace Leds{
if (fastLedsType == LedType::SK6812)
{
+ setParamsAndPrepareCalibration(calGain, calRed, calGreen, calBlue);
virtualLedsNumber = (fastLedsNumber * 4 + 2) / 3;
- const size_t bytesToAllocate = virtualLedsNumber * 3;
- leds = reinterpret_cast(new uint8_t[bytesToAllocate]);
- memset(leds, 0, bytesToAllocate);
+ leds = new CRGB[virtualLedsNumber];
}
else
{
@@ -257,42 +247,42 @@ namespace Leds{
{
switch (cfgLedDataPin) {
#if !defined(CONFIG_IDF_TARGET_ESP32S3)
- case 0: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 0: FastLED.addLeds(leds, virtualLedsNumber); break;
#endif
- case 1: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 2: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 1: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 2: FastLED.addLeds(leds, virtualLedsNumber); break;
#if !defined(CONFIG_IDF_TARGET_ESP32S3)
- case 3: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 3: FastLED.addLeds(leds, virtualLedsNumber); break;
#endif
- case 4: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 5: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 6: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 7: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 4: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 5: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 6: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 7: FastLED.addLeds(leds, virtualLedsNumber); break;
#if !defined(CONFIG_IDF_TARGET_ESP32C2)
- case 8: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 8: FastLED.addLeds(leds, virtualLedsNumber); break;
#endif
- case 10: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 10: FastLED.addLeds(leds, virtualLedsNumber); break;
#if defined(CONFIG_IDF_TARGET_ESP32C6)
- case 15: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 18: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 19: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 20: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 21: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 22: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 15: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 18: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 19: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 20: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 21: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 22: FastLED.addLeds(leds, virtualLedsNumber); break;
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
- case 16: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 17: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 18: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 48: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 16: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 17: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 18: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 48: FastLED.addLeds(leds, virtualLedsNumber); break;
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
- case 20: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 21: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 20: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 21: FastLED.addLeds(leds, virtualLedsNumber); break;
#elif defined(CONFIG_IDF_TARGET_ESP32C5)
- case 11: FastLED.addLeds(leds, virtualLedsNumber); break;
- case 27: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 11: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 27: FastLED.addLeds(leds, virtualLedsNumber); break;
#endif
default:
- FastLED.addLeds(leds, virtualLedsNumber);
+ FastLED.addLeds(leds, virtualLedsNumber);
break;
}
}
@@ -300,20 +290,21 @@ namespace Leds{
{ // SPI (APA102 / SK9822)
switch (cfgLedDataPin) {
#if defined(CONFIG_IDF_TARGET_ESP32S3)
- case 11: FastLED.addLeds(leds, virtualLedsNumber); break;
- #elif defined(CONFIG_IDF_TARGET_ESP32C3)
- case 7: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 5: FastLED.addLeds(leds, virtualLedsNumber); break;
+ #elif defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5)
+ case 7: FastLED.addLeds(leds, virtualLedsNumber); break;
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
- case 6: FastLED.addLeds(leds, virtualLedsNumber); break;
+ case 5: FastLED.addLeds(leds, virtualLedsNumber); break;
#endif
default:
Log::debug("!!! FATAL ERROR: Invalid LED Data Pin. Must use Hardware SPI pins. !!!");
- FastLED.addLeds(leds, virtualLedsNumber);
+ FastLED.addLeds(leds, virtualLedsNumber);
}
}
- FastLED.setBrightness(Volatile::state.brightness);
+ FastLED.setBrightness(255);
+
#else
if (cfgLedType == LedType::WS2812 || cfgLedType == LedType::SK6812)
{ // clockless
@@ -331,16 +322,14 @@ namespace Leds{
}
else
{ // SPI (APA102 / SK9822)
- #if defined(ARDUINO_ARCH_ESP32)
- dotstar = new DotStar(cfgLedNumLeds, cfgLedDataPin, cfgLedClockPin); //23, 18
- #else
- dotstar = new DotStar(cfgLedNumLeds, cfgLedDataPin, cfgLedClockPin); //19, 18
- #endif
+ dotstar = new DotStar(cfgLedNumLeds, cfgLedClockPin, cfgLedDataPin);
dotstar->Begin();
}
#endif
clearAll();
+
+ ledDriverInitialized = true;
}
void applyLedConfig()
@@ -352,42 +341,51 @@ namespace Leds{
Volatile::updateStaticColor(cfg.led.r, cfg.led.g, cfg.led.b);
}
+ inline uint8_t scaleBri(uint8_t v)
+ {
+ return (static_cast(v) * briPlus) >> 8;
+ }
+
template
void setLed(int index, uint8_t r, uint8_t g, uint8_t b)
{
+ if constexpr (applyBrightness) {
+ r = scaleBri(r);
+ g = scaleBri(g);
+ b = scaleBri(b);
+ }
#ifdef USE_FASTLED
+
if (fastLedsType == LedType::SK6812)
{
if (index >= fastLedsNumber) return;
const RgbwColor calibrated = rgb2rgbw(r, g, b);
uint16_t i = index * 4;
- reinterpret_cast(leds)[i] = calibrated.G;
- reinterpret_cast(leds)[i + 1] = calibrated.R;
- reinterpret_cast(leds)[i + 2] = calibrated.B;
- reinterpret_cast(leds)[i + 3] = calibrated.W;
+ auto raw = reinterpret_cast(leds);
+ raw[i] = calibrated.G;
+ raw[i + 1] = calibrated.R;
+ raw[i + 2] = calibrated.B;
+ raw[i + 3] = calibrated.W;
}
else
{
if (index >= fastLedsNumber) return;
- leds[index] = CRGB(r, g, b);
+ leds[index] = CRGB(g, r, b);
}
#else
if (dotstar != nullptr)
{
- RgbwColor col(r, g, b, 31);
- if constexpr (applyBrightness) col = col.Dim(Volatile::state.brightness);
+ RgbColor col(r, g, b);
dotstar->SetPixelColor(index, col);
}
else if (neopixel != nullptr)
{
RgbColor col(r, g, b);
- if constexpr (applyBrightness) col = col.Dim(Volatile::state.brightness);
neopixel->SetPixelColor(index, col);
}
else if (neopixelRgbw != nullptr)
{
RgbwColor col = rgb2rgbw(r, g, b);
- if constexpr (applyBrightness) col = col.Dim(Volatile::state.brightness);
neopixelRgbw->SetPixelColor(index, col);
}
#endif
@@ -396,44 +394,51 @@ namespace Leds{
template
void setLedW(int index, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
{
+ if constexpr (applyBrightness) {
+ r = scaleBri(r);
+ g = scaleBri(g);
+ b = scaleBri(b);
+ w = scaleBri(w);
+ }
+
#ifdef USE_FASTLED
+
+
if (fastLedsType == LedType::SK6812)
{
if (index >= fastLedsNumber) return;
uint16_t i = index * 4;
- reinterpret_cast(leds)[i] = g;
- reinterpret_cast(leds)[i + 1] = r;
- reinterpret_cast(leds)[i + 2] = b;
- reinterpret_cast(leds)[i + 3] = w;
+ auto raw = reinterpret_cast(leds);
+ raw[i] = g;
+ raw[i + 1] = r;
+ raw[i + 2] = b;
+ raw[i + 3] = w;
}
else
{
if (index >= fastLedsNumber) return;
- leds[index] = CRGB(r, g, b);
+ leds[index] = CRGB(g, r, b);
}
#else
if (dotstar != nullptr)
{
- RgbwColor col(r, g, b, min(w, (uint8_t)31));
- if constexpr (applyBrightness) col = col.Dim(Volatile::state.brightness);
+ RgbColor col(r, g, b);
dotstar->SetPixelColor(index, col);
}
else if (neopixel != nullptr)
{
RgbColor col(r, g, b);
- if constexpr (applyBrightness) col = col.Dim(Volatile::state.brightness);
neopixel->SetPixelColor(index, col);
}
else if (neopixelRgbw != nullptr)
{
RgbwColor col(r, g, b, w);
- if constexpr (applyBrightness) col = col.Dim(Volatile::state.brightness);
neopixelRgbw->SetPixelColor(index, col);
}
#endif
}
- void checkDeleyedRender()
+ void checkDelayedRender()
{
if (delayedRender)
{
@@ -491,10 +496,7 @@ namespace Leds{
}
template void setLed(int, uint8_t, uint8_t, uint8_t);
- template void setLedW(int, uint8_t, uint8_t, uint8_t, uint8_t);
-
- #ifndef USE_FASTLED
- template void setLed(int, uint8_t, uint8_t, uint8_t);
- template void setLedW(int, uint8_t, uint8_t, uint8_t, uint8_t);
- #endif
+ template void setLedW(int, uint8_t, uint8_t, uint8_t, uint8_t);
+ template void setLed(int, uint8_t, uint8_t, uint8_t);
+ template void setLedW(int, uint8_t, uint8_t, uint8_t, uint8_t);
}
\ No newline at end of file
diff --git a/src/manager.cpp b/src/manager.cpp
index a34adb7..2c99351 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -61,8 +61,8 @@ void managerLoop()
{
Volatile::checkStreamTimeout();
- Leds::synchronizeLedsToVolatileStateBeforeDeleyedRender();
- Leds::checkDeleyedRender();
+ Leds::synchronizeLedsToVolatileStateBeforeDelayedRender();
+ Leds::checkDelayedRender();
if (_pendingReboot)
{
diff --git a/src/udp_receiver.cpp b/src/udp_receiver.cpp
index 88808ec..933f9ec 100644
--- a/src/udp_receiver.cpp
+++ b/src/udp_receiver.cpp
@@ -59,15 +59,9 @@ void handleDDP(WiFiUDP& udp) {
return;
}
- #ifdef USE_FASTLED
- const bool brightnessControl = false;
- auto setPixel = Leds::setLed;
- auto setPixelW = Leds::setLedW;
- #else
- const bool brightnessControl = (Volatile::state.brightness != 255);
- auto setPixel = brightnessControl ? Leds::setLed : Leds::setLed;
- auto setPixelW = brightnessControl ? Leds::setLedW : Leds::setLedW;
- #endif
+ const bool brightnessControl = (Volatile::state.brightness != 255);
+ auto setPixel = brightnessControl ? Leds::setLed : Leds::setLed;
+ auto setPixelW = brightnessControl ? Leds::setLedW : Leds::setLedW;
uint8_t buffer[packetSize];
uint8_t* endBuffer = &(buffer[0]) + udp.read(buffer, packetSize);
@@ -134,15 +128,9 @@ void handleRealTime(WiFiUDP& udp) {
return;
}
- #ifdef USE_FASTLED
- const bool brightnessControl = false;
- auto setPixel = Leds::setLed;
- auto setPixelW = Leds::setLedW;
- #else
- const bool brightnessControl = (Volatile::state.brightness != 255);
- auto setPixel = brightnessControl ? Leds::setLed : Leds::setLed;
- auto setPixelW = brightnessControl ? Leds::setLedW : Leds::setLedW;
- #endif
+ const bool brightnessControl = (Volatile::state.brightness != 255);
+ auto setPixel = brightnessControl ? Leds::setLed : Leds::setLed;
+ auto setPixelW = brightnessControl ? Leds::setLedW : Leds::setLedW;
uint8_t buffer[packetSize];
uint8_t* endBuffer = &(buffer[0]) + udp.read(buffer, packetSize);
@@ -198,15 +186,9 @@ void handleRAW(WiFiUDP& udp)
return;
}
- #ifdef USE_FASTLED
- const bool brightnessControl = false;
- auto setPixel = Leds::setLed;
- auto setPixelW = Leds::setLedW;
- #else
- const bool brightnessControl = (Volatile::state.brightness != 255);
- auto setPixel = brightnessControl ? Leds::setLed : Leds::setLed;
- auto setPixelW = brightnessControl ? Leds::setLedW : Leds::setLedW;
- #endif
+ const bool brightnessControl = (Volatile::state.brightness != 255);
+ auto setPixel = brightnessControl ? Leds::setLed : Leds::setLed;
+ auto setPixelW = brightnessControl ? Leds::setLedW : Leds::setLedW;
uint8_t buffer[packetSize];
uint8_t* endBuffer = &(buffer[0]) + udp.read(buffer, packetSize);
diff --git a/src/web_server.cpp b/src/web_server.cpp
index c71a203..b29c604 100644
--- a/src/web_server.cpp
+++ b/src/web_server.cpp
@@ -160,12 +160,28 @@ void setupWebServer(AsyncWebServer& server) {
server.on("/save_config", HTTP_POST, [](AsyncWebServerRequest *request) {
AppConfig cfg = Config::cfg;
bool needsRestart = false;
+
+ if (request->hasParam("reset_wifi", true)) {
+ String ssid = request->getParam("reset_wifi", true)->value();
+
+ if (cfg.wifi.ssid.equalsIgnoreCase(ssid)) {
+ cfg.wifi.ssid = "";
+ cfg.wifi.password = "";
+ Config::saveConfig(cfg);
+ managerScheduleReboot(1000);
+ request->send(200, mime_application_json, "{\"status\":\"reboot\"}");
+ } else {
+ request->send(403, mime_application_json, "{\"status\":\"error\"}");
+ }
+
+ return;
+ }
if (request->hasParam("type", true)) {
uint8_t t = request->getParam("type", true)->value().toInt();
if (t != (uint8_t)cfg.led.type)
{
- #ifdef USE_FASTLED
+ #ifndef LEDS_NOT_REQUIRE_RESTART
needsRestart = true;
#endif
@@ -176,7 +192,7 @@ void setupWebServer(AsyncWebServer& server) {
uint8_t p = request->getParam("dataPin", true)->value().toInt();
if (p != cfg.led.dataPin)
{
- #ifdef USE_FASTLED
+ #ifndef LEDS_NOT_REQUIRE_RESTART
needsRestart = true;
#endif
@@ -187,7 +203,7 @@ void setupWebServer(AsyncWebServer& server) {
uint8_t p = request->getParam("clockPin", true)->value().toInt();
if (p != cfg.led.clockPin)
{
- #ifdef USE_FASTLED
+ #ifndef LEDS_NOT_REQUIRE_RESTART
needsRestart = true;
#endif
@@ -198,7 +214,7 @@ void setupWebServer(AsyncWebServer& server) {
uint16_t n = request->getParam("numLeds", true)->value().toInt();
if (n != cfg.led.numLeds && n <= MAX_LEDS)
{
- #ifdef USE_FASTLED
+ #ifndef LEDS_NOT_REQUIRE_RESTART
needsRestart = true;
#endif
@@ -289,6 +305,8 @@ void setupWebServer(AsyncWebServer& server) {
led["deviceName"] = cfg.deviceName;
led["extraMdnsTag"] = cfg.extraMdnsTag;
+ led["ssid"] = cfg.wifi.ssid;
+
serializeJson(doc, *response);
request->send(response);
});
diff --git a/version b/version
index e9c21cd..95cdb8d 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.0.2-alpha.6
+0.0.2-beta