Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7973fd8
Revert disable OTA & optional Arduino OTA
blazoncek Jun 25, 2025
796494e
Tweaks in OTA UI
blazoncek Jun 26, 2025
6a5dcb3
More OTA UI tweaks
blazoncek Jun 26, 2025
a24420a
Fix #4268
blazoncek Jun 29, 2025
e7157e5
Add mDNS resolution for network bus
blazoncek Jun 28, 2025
79b3bc2
Add mDNS support for MQTT server
blazoncek Jul 12, 2025
24f2306
Strip .local from mDNS resolution
blazoncek Jul 15, 2025
07e303b
Remove anything behind .local and ignore case
blazoncek Jul 15, 2025
ecc3eae
Revert status message change
blazoncek Jul 16, 2025
9e4675e
Update AsyncWebServer and AsyncTCP
willmmiles Jul 31, 2025
e374c7a
Update to AsyncTCP 3.4.7
willmmiles Aug 2, 2025
bfe5cd5
Merge pull request #4748 from wled/aOTA
blazoncek Aug 2, 2025
374d906
Merge pull request #4768 from wled/fix-4268
blazoncek Aug 2, 2025
93e011d
Merge pull request #4769 from wled/fix-4671
blazoncek Aug 2, 2025
f74d145
Downtune AsyncTCP stack size
willmmiles Aug 4, 2025
e3653ba
Segment fixes (#4811)
DedeHai Aug 7, 2025
3f90366
Merge pull request #4796 from willmmiles/asynctcp-update
willmmiles Aug 9, 2025
297d5ce
Use esp32_idf_V4.build_flags and esp32_idf_V4.lib_deps for all V4 builds
netmindz Aug 14, 2025
c8d8ab0
ARDUINO_USB_CDC_ON_BOOT should not be in common esp32_idf_V4
netmindz Aug 14, 2025
caf3c7a
Remove old V3 IDF
netmindz Aug 14, 2025
c33e303
Fix eth build, update lib_deps for v4
netmindz Aug 14, 2025
b8b59b2
Make rainbow effects more colorful (#3681)
TripleWhy Aug 15, 2025
c9c442a
Bootloop detection & recovery (#4793)
DedeHai Aug 15, 2025
f4d89c4
add IDF V3 support for bootloop detection
DedeHai Aug 16, 2025
af2d46c
Set VERSION
netmindz Aug 16, 2025
7285efe
Merge pull request #4836 from netmindz/V4-cleanup
netmindz Aug 16, 2025
7865985
Make version information consistent across update interfaces
Arcitec Aug 17, 2025
dcc1fbc
Merge pull request #4846 from Arcitec/improve-version-info
netmindz Aug 19, 2025
3b5c6ca
Fix bootloop if config is reset (#4852)
willmmiles Aug 20, 2025
624042d
Initial plan
Copilot Aug 20, 2025
890860e
Initial plan
Copilot Aug 20, 2025
cd8ddb8
Fix GitHub workflow secret access from forked PRs
Copilot Aug 20, 2025
7943b00
Add comprehensive GitHub Copilot instructions for WLED development
Copilot Aug 20, 2025
dee581f
Merge pull request #4858 from wled/copilot/fix-4857
netmindz Aug 20, 2025
1fb9eb7
Merge pull request #4856 from wled/copilot/fix-4855
netmindz Aug 20, 2025
5fa901c
Fix operation of length 1 strips, such as PWM LEDs
willmmiles Aug 28, 2025
c92f0a9
Merge pull request #4878 from willmmiles/fix-pwm
netmindz Aug 28, 2025
4155a6b
Initial plan
Copilot Aug 28, 2025
708baf1
Fix pr-merge.yaml to include PR title and link in Discord notifications
Copilot Aug 28, 2025
f15c1fb
Merge pull request #4880 from wled/copilot/fix-4879
netmindz Aug 28, 2025
cfad0b8
bugfix to prevent "almost infinite" loops in palette blend (#4841)
DedeHai Aug 28, 2025
8aeb9e1
bugfix in PS pointer alignment
DedeHai Aug 28, 2025
d5d7fde
use video scaling instead of NPB luminance & new ABL (#4798)
DedeHai Aug 29, 2025
da7f107
fix POV Display usermod (#4427)
Liliputech Aug 29, 2025
8c51dc3
Merge remote-tracking branch 'origin/main' into unify-hostname
milhnl Aug 31, 2025
dd96076
Replace some mDNS enabled checks aftere merge
milhnl Aug 31, 2025
ce53fca
Restore legacy behaviour for fallback hostname
milhnl Aug 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# WLED - ESP32/ESP8266 LED Controller Firmware

WLED is a fast and feature-rich implementation of an ESP32 and ESP8266 webserver to control NeoPixel (WS2812B, WS2811, SK6812) LEDs and SPI-based chipsets. The project consists of C++ firmware for microcontrollers and a modern web interface.

Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.

## Working Effectively

### Initial Setup
- Install Node.js 20+ (specified in `.nvmrc`): Check your version with `node --version`
- Install dependencies: `npm install` (takes ~5 seconds)
- Install PlatformIO for hardware builds: `pip install -r requirements.txt` (takes ~60 seconds)

### Build and Test Workflow
- **ALWAYS build web UI first**: `npm run build` -- takes 3 seconds. NEVER CANCEL.
- **Run tests**: `npm test` -- takes 40 seconds. NEVER CANCEL. Set timeout to 2+ minutes.
- **Development mode**: `npm run dev` -- monitors file changes and auto-rebuilds web UI
- **Hardware firmware build**: `pio run -e [environment]` -- takes 15+ minutes. NEVER CANCEL. Set timeout to 30+ minutes.

### Build Process Details
The build has two main phases:
1. **Web UI Generation** (`npm run build`):
- Processes files in `wled00/data/` (HTML, CSS, JS)
- Minifies and compresses web content
- Generates `wled00/html_*.h` files with embedded web content
- **CRITICAL**: Must be done before any hardware build

2. **Hardware Compilation** (`pio run`):
- Compiles C++ firmware for various ESP32/ESP8266 targets
- Common environments: `nodemcuv2`, `esp32dev`, `esp8266_2m`
- List all targets: `pio run --list-targets`

## Validation and Testing

### Web UI Testing
- **ALWAYS validate web UI changes manually**:
- Start local server: `cd wled00/data && python3 -m http.server 8080`
- Open `http://localhost:8080/index.htm` in browser
- Test basic functionality: color picker, effects, settings pages
- **Check for JavaScript errors** in browser console

### Code Validation
- **No automated linting configured** - follow existing code style in files you edit
- **Code style**: Use tabs for web files (.html/.css/.js), spaces (2 per level) for C++ files
- **C++ formatting available**: `clang-format` is installed but not in CI
- **Always run tests before finishing**: `npm test`

### Manual Testing Scenarios
After making changes to web UI, always test:
- **Load main interface**: Verify index.htm loads without errors
- **Navigation**: Test switching between main page and settings pages
- **Color controls**: Verify color picker and brightness controls work
- **Effects**: Test effect selection and parameter changes
- **Settings**: Test form submission and validation

## Common Tasks

### Repository Structure
```
wled00/ # Main firmware source (C++)
├── data/ # Web interface files
│ ├── index.htm # Main UI
│ ├── settings*.htm # Settings pages
│ └── *.js/*.css # Frontend resources
├── *.cpp/*.h # Firmware source files
└── html_*.h # Generated embedded web files (DO NOT EDIT)
tools/ # Build tools (Node.js)
├── cdata.js # Web UI build script
└── cdata-test.js # Test suite
platformio.ini # Hardware build configuration
package.json # Node.js dependencies and scripts
.github/workflows/ # CI/CD pipelines
```

### Key Files and Their Purpose
- `wled00/data/index.htm` - Main web interface
- `wled00/data/settings*.htm` - Configuration pages
- `tools/cdata.js` - Converts web files to C++ headers
- `wled00/wled.h` - Main firmware configuration
- `platformio.ini` - Hardware build targets and settings

### Development Workflow
1. **For web UI changes**:
- Edit files in `wled00/data/`
- Run `npm run build` to regenerate headers
- Test with local HTTP server
- Run `npm test` to validate build system

2. **For firmware changes**:
- Edit files in `wled00/` (but NOT `html_*.h` files)
- Ensure web UI is built first (`npm run build`)
- Build firmware: `pio run -e [target]`
- Flash to device: `pio run -e [target] --target upload`

3. **For both web and firmware**:
- Always build web UI first
- Test web interface manually
- Build and test firmware if making firmware changes

## Build Timing and Timeouts

- **Web UI build**: 3 seconds - Set timeout to 30 seconds minimum
- **Test suite**: 40 seconds - Set timeout to 2 minutes minimum
- **Hardware builds**: 15+ minutes - Set timeout to 30+ minutes minimum
- **NEVER CANCEL long-running builds** - PlatformIO downloads and compilation can take significant time

## Troubleshooting

### Common Issues
- **Build fails with missing html_*.h**: Run `npm run build` first
- **Web UI looks broken**: Check browser console for JavaScript errors
- **PlatformIO network errors**: Try again, downloads can be flaky
- **Node.js version issues**: Ensure Node.js 20+ is installed (check `.nvmrc`)

### When Things Go Wrong
- **Clear generated files**: `rm -f wled00/html_*.h` then rebuild
- **Force web UI rebuild**: `npm run build -- --force` or `npm run build -- -f`
- **Clean PlatformIO cache**: `pio run --target clean`
- **Reinstall dependencies**: `rm -rf node_modules && npm install`

## Important Notes

- **DO NOT edit `wled00/html_*.h` files** - they are auto-generated
- **Always commit both source files AND generated html_*.h files**
- **Web UI must be built before firmware compilation**
- **Test web interface manually after any web UI changes**
- **Use VS Code with PlatformIO extension for best development experience**
- **Hardware builds require appropriate ESP32/ESP8266 development board**

## CI/CD Pipeline
The GitHub Actions workflow:
1. Installs Node.js and Python dependencies
2. Runs `npm test` to validate build system
3. Builds web UI with `npm run build`
4. Compiles firmware for multiple hardware targets
5. Uploads build artifacts

Match this workflow in your local development to ensure CI success.
5 changes: 4 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ jobs:
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm ci
- run: |
npm ci
VERSION=`date +%y%m%d0`
sed -i -r -e "s/define VERSION .+/define VERSION $VERSION/" wled00/wled.h
- name: Cache PlatformIO
uses: actions/cache@v4
with:
Expand Down
19 changes: 12 additions & 7 deletions .github/workflows/pr-merge.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: Notify Discord on PR Merge
on:
workflow_dispatch:
pull_request:
pull_request_target:
types: [closed]

jobs:
notify:
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true
steps:
- name: Get User Permission
id: checkAccess
Expand All @@ -23,11 +24,15 @@
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
echo "Job originally triggered by ${{ github.actor }}"
exit 1
- name: Checkout code
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }} # This is dangerous without the first access check
- name: Send Discord notification
# if: github.event.pull_request.merged == true
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_URL: ${{ github.event.pull_request.html_url }}
ACTOR: ${{ github.actor }}
run: |
curl -H "Content-Type: application/json" -d '{"content": "Pull Request ${{ github.event.pull_request.number }} merged by ${{ github.actor }}"}' ${{ secrets.DISCORD_WEBHOOK_BETA_TESTERS }}
jq -n \
--arg content "Pull Request #${PR_NUMBER} \"${PR_TITLE}\" merged by ${ACTOR}
${PR_URL}" \
'{content: $content}' \
| curl -H "Content-Type: application/json" -d @- ${{ secrets.DISCORD_WEBHOOK_BETA_TESTERS }}
76 changes: 19 additions & 57 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# ------------------------------------------------------------------------------

# CI/release binaries
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, nodemcuv2_compat, esp8266_2m_compat, esp01_1m_full_compat, esp32dev, esp32dev_V4, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, esp32_wrover, usermods
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, nodemcuv2_compat, esp8266_2m_compat, esp01_1m_full_compat, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, esp32_wrover, usermods

src_dir = ./wled00
data_dir = ./wled00/data
Expand Down Expand Up @@ -142,7 +142,7 @@ lib_deps =
IRremoteESP8266 @ 2.8.2
makuna/NeoPixelBus @ 2.8.3
#https://github.com/makuna/NeoPixelBus.git#CoreShaderBeta
https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.4.0
https://github.com/Aircoookie/ESPAsyncWebServer.git#v2.4.2
# for I2C interface
;Wire
# ESP-NOW library
Expand Down Expand Up @@ -234,45 +234,36 @@ lib_deps_compat =

[esp32_all_variants]
lib_deps =
willmmiles/AsyncTCP @ 1.3.1
esp32async/AsyncTCP @ 3.4.7
bitbank2/AnimatedGIF@^1.4.7
https://github.com/Aircoookie/GifDecoder#bc3af18
build_flags =
-D CONFIG_ASYNC_TCP_USE_WDT=0
-D CONFIG_ASYNC_TCP_STACK_SIZE=8192
-D WLED_ENABLE_GIF

[esp32]
#platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.3/platform-espressif32-2.0.2.3.zip
platform = [email protected]
platform_packages = framework-arduinoespressif32 @ https://github.com/Aircoookie/arduino-esp32.git#1.0.6.4
platform = ${esp32_idf_V4.platform}
platform_packages =
build_unflags = ${common.build_unflags}
build_flags = -g
-DARDUINO_ARCH_ESP32
#-DCONFIG_LITTLEFS_FOR_IDF_3_2
#use LITTLEFS library by lorol in ESP32 core 1.x.x instead of built-in in 2.x.x
-D LOROL_LITTLEFS
; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
${esp32_all_variants.build_flags}
build_flags = ${esp32_idf_V4.build_flags}
lib_deps = ${esp32_idf_V4.lib_deps}

tiny_partitions = tools/WLED_ESP32_2MB_noOTA.csv
default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
extended_partitions = tools/WLED_ESP32_4MB_700k_FS.csv
big_partitions = tools/WLED_ESP32_4MB_256KB_FS.csv ;; 1.8MB firmware, 256KB filesystem, coredump support
large_partitions = tools/WLED_ESP32_8MB.csv
extreme_partitions = tools/WLED_ESP32_16MB_9MB_FS.csv
lib_deps =
https://github.com/lorol/LITTLEFS.git
${esp32_all_variants.lib_deps}
${env.lib_deps}

board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
# additional build flags for audioreactive - must be applied globally
AR_build_flags = ;; -fsingle-precision-constant ;; forces ArduinoFFT to use float math (2x faster)
AR_lib_deps = ;; for pre-usermod-library platformio_override compatibility


[esp32_idf_V4]
;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
;; very similar to the normal ESP32 flags, but omitting Lorol LittleFS, as littlefs is included in the new framework already.
;; build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
;;
;; please note that you can NOT update existing ESP32 installs with a "V4" build. Also updating by OTA will not work properly.
;; You need to completely erase your device (esptool erase_flash) first, then install the "V4" build from VSCode+platformio.
Expand All @@ -283,14 +274,12 @@ build_unflags = ${common.build_unflags}
build_flags = -g
-Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one
-DARDUINO_ARCH_ESP32 -DESP32
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
${esp32_all_variants.build_flags}
-D WLED_ENABLE_DMX_INPUT
lib_deps =
${esp32_all_variants.lib_deps}
https://github.com/someweisguy/esp_dmx.git#47db25d
${env.lib_deps}
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs

[esp32s2]
;; generic definitions for all ESP32-S2 boards
Expand All @@ -305,10 +294,9 @@ build_flags = -g
-DARDUINO_USB_MODE=0 ;; this flag is mandatory for ESP32-S2 !
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_all_variants.build_flags}
${esp32_idf_V4.build_flags}
lib_deps =
${esp32_all_variants.lib_deps}
${env.lib_deps}
${esp32_idf_V4.lib_deps}
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs

[esp32c3]
Expand All @@ -323,10 +311,9 @@ build_flags = -g
-DARDUINO_USB_MODE=1 ;; this flag is mandatory for ESP32-C3
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_CDC_ON_BOOT
${esp32_all_variants.build_flags}
${esp32_idf_V4.build_flags}
lib_deps =
${esp32_all_variants.lib_deps}
${env.lib_deps}
${esp32_idf_V4.lib_deps}
board_build.partitions = ${esp32.default_partitions} ;; default partioning for 4MB Flash - can be overridden in build envs
board_build.flash_mode = qio

Expand All @@ -343,10 +330,9 @@ build_flags = -g
-DCO
;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry:
;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT
${esp32_all_variants.build_flags}
${esp32_idf_V4.build_flags}
lib_deps =
${esp32_all_variants.lib_deps}
${env.lib_deps}
${esp32_idf_V4.lib_deps}
board_build.partitions = ${esp32.large_partitions} ;; default partioning for 8MB flash - can be overridden in build envs


Expand Down Expand Up @@ -441,21 +427,11 @@ custom_usermods = audioreactive

[env:esp32dev]
board = esp32dev
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
lib_deps = ${esp32.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}

[env:esp32dev_V4]
board = esp32dev
platform = ${esp32_idf_V4.platform}
build_unflags = ${common.build_unflags}
custom_usermods = audioreactive
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_V4\" #-D WLED_DISABLE_BROWNOUT_DET
-DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3
lib_deps = ${esp32_idf_V4.lib_deps}
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
Expand Down Expand Up @@ -489,34 +465,20 @@ board_upload.maximum_size = 16777216
board_build.f_flash = 80000000L
board_build.flash_mode = dio

;[env:esp32dev_audioreactive]
;board = esp32dev
;platform = ${esp32.platform}
;platform_packages = ${esp32.platform_packages}
;custom_usermods = audioreactive
;build_unflags = ${common.build_unflags}
;build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_audioreactive\" #-D WLED_DISABLE_BROWNOUT_DET
;lib_deps = ${esp32.lib_deps}
;monitor_filters = esp32_exception_decoder
;board_build.partitions = ${esp32.default_partitions}
;; board_build.f_flash = 80000000L
;; board_build.flash_mode = dio

[env:esp32_eth]
board = esp32-poe
platform = ${esp32.platform}
platform_packages = ${esp32.platform_packages}
platform = ${esp32_idf_V4.platform}
upload_speed = 921600
custom_usermods = audioreactive
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=\"ESP32_Ethernet\" -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
; -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only
lib_deps = ${esp32.lib_deps}
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = dio

[env:esp32_wrover]
extends = esp32_idf_V4
platform = ${esp32_idf_V4.platform}
board = ttgo-t7-v14-mini32
board_build.f_flash = 80000000L
board_build.flash_mode = qio
Expand Down
1 change: 0 additions & 1 deletion platformio_override.sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ lib_deps = ${esp8266.lib_deps}
; robtillaart/SHT85@~0.3.3
; ;gmag11/QuickESPNow @ ~0.7.0 # will also load QuickDebug
; https://github.com/blazoncek/QuickESPNow.git#optional-debug ;; exludes debug library
; bitbank2/PNGdec@^1.0.1 ;; used for POV display uncomment following
; ${esp32.AR_lib_deps} ;; needed for USERMOD_AUDIOREACTIVE

build_unflags = ${common.build_unflags}
Expand Down
Loading