Skip to content

🚀 ESP-IDF V5#4838

Draft
netmindz wants to merge 74 commits intomainfrom
V5
Draft

🚀 ESP-IDF V5#4838
netmindz wants to merge 74 commits intomainfrom
V5

Conversation

@netmindz
Copy link
Member

@netmindz netmindz commented Aug 14, 2025

Update the code to handle at least being able to compile against V5


Edit (softhack007): espressif has "silently" changed a lot of APIs, and - in many cases - replacements are not behaving the same way as before. We are lucky that a few "legacy APIs" are still available, like the "V4" I2S driver. So even when "it compiles", there may be a lot more adaptations needed before "it really works".


Helpful information and migration guidance

coding guides

We should make sure that the "V5" branch will still compile for "V4" as a backup solution.
When adding code that only works in the new framework, it should be conditionally compiled, like in the examples below

  • "V5" code that is not specific to new boards
      #if defined(ESP_IDF_VERSION) && (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
      ledcAttach(pwmPin, 25000, 8);  // New API: ledcAttach(pin, freq, resolution)
      #else
      ledcSetup(pwmChannel, 25000, 8);
      // attach the channel to the GPIO to be controlled
      ledcAttachPin(pwmPin, pwmChannel);
      #endif
  • "V5" code only for esp32-P4 or esp32-C6:
 #if defined(CONFIG_IDF_TARGET_ESP32C6)
    // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/peripherals/gpio.html
    // strapping pins: 4, 5, 8, 9
    if (gpio > 11 && gpio < 14) return false;     // 12-13 USB-JTAG
    if (gpio > 23 && gpio < 31) return false;     // 24-30 SPI FLASH
#elif defined(CONFIG_IDF_TARGET_ESP32P4)
    // strapping pins: 34,35,36,37,38
    if (             gpio <   2) return false;     // NC
    if (gpio > 13 && gpio <  20) return false;     // ESP-Hosted WiFi pins
    if (gpio > 23 && gpio <  26) return false;     // USB Pins
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
  // .... existing code
#else
  // .... existing code
#endif

related

Summary by CodeRabbit

  • New Features

    • Expanded ESP32 IDF v5+ support for PWM/LEDC, RMT/I2S, Ethernet init, and SHA‑1 compatibility shims.
  • Bug Fixes

    • Consolidated network interface for consistent IP/MAC reporting across UI, discovery, services and displays.
    • Safer DMX/RDM handling with improved callbacks, null checks and stability.
    • Updated usermods/displays to use the consolidated network interface.
  • Chores

    • Updated build manifest, environment mappings, package/dependency versions and Python requirements.
  • Refactor

    • Renamed/reorganized network API symbols and converted a preprocessor macro to a typed constexpr.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 14, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)

Walkthrough

Refactors build and platform compatibility for ESP32/ESP-IDF v5: gates NeoEsp32RmtHI compilation by WLED_USE_SHARED_RMT, renames Network → WLEDNetwork across the codebase, updates LEDC/ETH/UDP/MDNS/NTP APIs for IDF v5, adds SHA-1 shim, DMX RDM personality changes, and updates platformio/requirements.

Changes

Cohort / File(s) Summary
NeoEsp32RmtHI guard
lib/NeoESP32RmtHI/include/NeoEsp32RmtHIMethod.h, lib/NeoESP32RmtHI/src/NeoEsp32RmtHIMethod.cpp, lib/NeoESP32RmtHI/src/NeoEsp32RmtHI.S
Wrapped RMT driver headers/source/ASM with #if !defined(WLED_USE_SHARED_RMT) to exclude when shared RMT is used.
Network core rename
wled00/src/dependencies/network/Network.h, wled00/src/dependencies/network/Network.cpp
Renamed NetworkClassWLEDNetworkClass and global NetworkWLEDNetwork; adjusted localMAC handling for ESP32 Ethernet.
Network API propagation
wled00/*, wled00/src/dependencies/e131/ESPAsyncE131.cpp, wled00/src/dependencies/espalexa/Espalexa.h, usermods/*, lib/*, wled00/src/dependencies/network/*
Replaced Network.* references with WLEDNetwork.* across many modules (json, udp, improv, e131, espalexa, usermods, wled.cpp/h, xml, bus_manager, etc.) and updated WLED_CONNECTED macro.
Build/Platform manifest
platformio.ini, requirements.txt
Added ESP-IDF v5 manifest/envs, introduced -D WLED_USE_SHARED_RMT and other build flags, updated library versions and Python/dev deps.
LEDC / PWM modernization
wled00/bus_manager.cpp, usermods/PWM_fan/PWM_fan.cpp
Conditionalized LEDC API for ESP-IDF ≥5: switch ledcSetup/ledcAttachPinledcAttach and ledcDetachPinledcDetach; changed semaphore type to SemaphoreHandle_t.
DMX / RDM updates
wled00/dmx_input.h, wled00/dmx_input.cpp
RDM callbacks changed to receive separate request/response headers; added personalities array and createPersonalities(), switched driver install to use personalities count, added null checks and DMX_CONFIG_DEFAULT usage.
SHA-1 shim
wled00/mbedtls_sha1_shim.cpp, wled00/fcn_declare.h, wled00/util.cpp
Added mbedtls SHA-1 wrappers mapping to Arduino SHA1Builder for ESP32 (IDF ≥5.2.0); guarded computeSHA1/getDeviceId/device fingerprint code for IDF v5+.
Ethernet / ETH API changes
wled00/network.cpp
Reordered ETH.begin() parameters to match updated API (PHY type first, then address, mdc/mdio, power, clock mode) and minor formatting fixes.
NeoPixelBus / bus wrapper shim
wled00/bus_wrapper.h
Added macro remapping for NeoPixelBus RMT/I2S method names on ESP32 and defined new 32-bit host pin constants for ESP32.
NTP / UDP flush handling
wled00/ntp.cpp, wled00/src/dependencies/espalexa/Espalexa.h
Use clear() instead of flush() on ESP-IDF ≥5 where appropriate; adjusted UDP handling and multicast IP sourcing to use WLEDNetwork.localIP().
Misc. API/type modernizations & constants
wled00/const.h, wled00/bus_manager.cpp, wled00/wled.h
Converted macro to constexpr for WLED_MAX_ANALOG_CHANNELS; replaced xSemaphoreHandle with SemaphoreHandle_t; updated WLED_CONNECTED to use WLEDNetwork.isConnected().

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • willmmiles
  • netmindz
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '🚀 ESP-IDF V5' directly and clearly identifies the main objective of the PR: upgrading the codebase to support ESP-IDF v5.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch V5

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@netmindz netmindz changed the title V5 ESP-IDF V5 Aug 14, 2025
@netmindz netmindz mentioned this pull request Aug 15, 2025
@netmindz netmindz requested a review from willmmiles August 16, 2025 11:30
@netmindz
Copy link
Member Author

I'm not sure if renaming Network is the right approach to fix the conflict @willmmiles

@netmindz
Copy link
Member Author

I am also unsure why we are seeing linker errors for things like mbedtls_sha1_starts

@netmindz netmindz added this to the 0.17.0 milestone Aug 16, 2025
@willmmiles
Copy link
Member

I'm not sure if renaming Network is the right approach to fix the conflict @willmmiles

Hm, it looks like it's just a bag of stateless utility functions. Probably it should be a namespace instead of a class. I don't think there's a practical solution to avoid the collision other than renaming, unless the newer core offers these utilities itself. (In fact I'd also suggest pulling them in to wled00/network.cpp , given the use of WLED-specific #defines.)

(Best pratice would've been that the upstream libraries put everything they do in a namespace, eg. Arduino::Network or somesuch, but here we are.)

I am also unsure why we are seeing linker errors for things like mbedtls_sha1_starts

I believe that the Tasmota platform omits mbedtls to save flash space, as they've gone over to BearSSL. Looks like they're still exposing the headers though - I don't know if that's an IDF bug or something wrong with their build process.

AsyncWebServer needs an SHA1 implementation as it is required for WebSockets. It looks like the upstream AWS folks have switched over to IDFv5 functions and vendored in Espressif's implementation when building on IDFv4. I'll see if I can pull those patches.

@sombree

This comment was marked as resolved.

@netmindz

This comment was marked as resolved.

sombree added a commit to sombree/WLED that referenced this pull request Sep 29, 2025
…(ESP-IDF 5.3.4 / arduino-esp32 v3.1.4).

Based on wled#4838.
sombree added a commit to sombree/WLED that referenced this pull request Sep 29, 2025
…(ESP-IDF 5.3.4 / arduino-esp32 v3.1.4).

Based on wled#4838.
@softhack007 softhack007 added major This is a non-trivial major feature and will take some time to implement keep This issue will never become stale/closed automatically magic labels Feb 8, 2026
@netmindz
Copy link
Member Author

netmindz commented Feb 9, 2026

Would be great to get your input on this @troyhacks

@softhack007
Copy link
Member

Status: ⚠️ Deprecated but still functional

heap_caps_get_free_size()          // Deprecated in IDF 5.x
heap_caps_get_largest_free_block()  // Deprecated in IDF 5.x

ESP-IDF V5.3 Recommendation: These still work but may emit deprecation warnings. Consider future migration to:

  • heap_caps_get_info() (returns struct with all heap stats)
  • Or accept the warnings for now (no runtime impact)

@DedeHai do you think we can replace deprecated functions as the rabbit recommends?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@platformio.ini`:
- Around line 540-547: The debug env `[env:esp32dev_debug]` currently overrides
build_unflags and drops inherited unflags from `${esp32_idf_V5.build_unflags}`;
update the `build_unflags` setting in `env:esp32dev_debug` to preserve inherited
unflags by appending or merging `${esp32_idf_V5.build_unflags}` (e.g., include
both the existing `-D WLED_RELEASE_NAME=...` unflag and
`${esp32_idf_V5.build_unflags}`) so you don't re-enable flags previously removed
by the esp32_idf_V5 configuration.

In `@wled00/util.cpp`:
- Around line 1139-1140: The preprocessor guard around computeSHA1() and
getDeviceId() in util.cpp must match the established pattern used in
fcn_declare.h and json.cpp; replace the current simplistic ESP_IDF_VERSION check
with the explicit guard used elsewhere: check for either non-ESP32 builds or
ESP-IDF < 5.0 (i.e., the pattern !defined(ARDUINO_ARCH_ESP32) ||
(ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)) ) so the
declarations/definitions of computeSHA1 and getDeviceId are consistently
enabled/disabled; keep the TODO comment about getDeviceId unavailability on
ESP-IDF v5 intact.
🧹 Nitpick comments (1)
wled00/util.cpp (1)

16-19: Indentation is inconsistent with surrounding includes.

Lines 8-15 have no leading whitespace for #include directives, but lines 16-19 have varying indentation. This creates visual inconsistency within the same #else block.

🧹 Suggested fix to align with surrounding code style
 `#include` "mbedtls/sha1.h"   // for SHA1 on ESP32
 `#include` "esp_efuse.h"
-  `#include` "esp_chip_info.h"
-  `#if` ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
-    `#include` <esp_mac.h>      // V5 requirement
-  `#endif`
+#include "esp_chip_info.h"
+#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
+#include <esp_mac.h>        // V5 requirement
+#endif
 `#endif`

Comment on lines +1139 to +1140
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) // ToDO: find a solution to make this work in V5

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Search for ESP_IDF_VERSION_VAL definitions
rg -n "ESP_IDF_VERSION_VAL" --type-add 'header:*.h' -t header

# Check how ESP_IDF_VERSION is used in headers
rg -n "ESP_IDF_VERSION" wled00/ -t cpp -t header -B 2 -A 2

# Check the actual code around lines 1139-1140
sed -n '1130,1150p' wled00/util.cpp

Repository: wled/WLED

Length of output: 2765


🏁 Script executed:

# Check for version compatibility macros in the codebase
rg -n "defined.*ESP_IDF_VERSION" wled00/

Repository: wled/WLED

Length of output: 730


🏁 Script executed:

# Look for any fallback definitions
rg -n "#define.*ESP_IDF_VERSION" wled00/

Repository: wled/WLED

Length of output: 206


🏁 Script executed:

sed -n '1139,1250p' wled00/util.cpp

Repository: wled/WLED

Length of output: 3556


🏁 Script executed:

# Also check if there's similar code in json.cpp mentioned in results
sed -n '700,715p' wled00/json.cpp

Repository: wled/WLED

Length of output: 858


🏁 Script executed:

# Check fcn_declare.h to see how the same pattern is used there
sed -n '420,440p' wled00/fcn_declare.h

Repository: wled/WLED

Length of output: 1395


🏁 Script executed:

# Check if ESP_IDF_VERSION is defined on ESP8266
rg -n "ESP_IDF_VERSION" --type cpp | grep -i "define\|ifdef" | head -20

# Look at the learning about USB CDC which mentions ARDUINO_USB_CDC_ON_BOOT vs explicit CONFIG_IDF_TARGET checks
# This suggests relying on Arduino framework flags rather than IDF checks
# Check what the standard pattern is
rg -n "ARDUINO_ARCH_ESP32" wled00/ -t cpp | head -10

# Verify if ESP8266 includes or defines ESP_IDF_VERSION
fd "board" . | head -5
rg -n "ESP_IDF_VERSION" . --type-add 'board:*.json' | head -5

Repository: wled/WLED

Length of output: 2218


🏁 Script executed:

# Search for where ESP_IDF_VERSION might be set for ESP8266
rg -n "ESP_IDF_VERSION\s*=" wled00/

# Check if there's version checking in network.cpp that shows the correct pattern
sed -n '230,240p' wled00/network.cpp

Repository: wled/WLED

Length of output: 440


🏁 Script executed:

# Check the exact guard pattern in util.cpp at the beginning
head -20 wled00/util.cpp

# Verify what files include or define ESP_IDF_VERSION
rg -n "include.*esp_idf_version" wled00/ -t cpp

# Check if the guard pattern is consistent across files
rg -B1 "computeSHA1\|getDeviceId" wled00/ -t cpp -t header | grep -E "^[^:]*:`#if`"

Repository: wled/WLED

Length of output: 718


🏁 Script executed:

# Let's verify: Check if ESP_IDF_VERSION is used without defined() check in util.cpp
sed -n '1,30p' wled00/util.cpp | grep -A5 -B5 "ESP_IDF_VERSION"

# Count unsafe vs safe patterns in the codebase
echo "=== Unsafe patterns (no defined() check): ==="
rg "#if ESP_IDF_VERSION" wled00/ -t cpp | grep -v "defined(ESP_IDF_VERSION)"

echo ""
echo "=== Safe patterns (with defined() or platform check): ==="
rg "#if.*defined.*ARDUINO_ARCH.*ESP_IDF_VERSION" wled00/ -t cpp
rg "#if defined(ESP_IDF_VERSION)" wled00/ -t cpp

Repository: wled/WLED

Length of output: 2080


Use the established guard pattern for consistency with declarations and other usage sites.

The guard at line 1139 is missing the explicit platform check used elsewhere in the codebase. The same computeSHA1() and getDeviceId() functions are declared in fcn_declare.h:427 and used in json.cpp:703 with an explicit pattern: #if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)). The guard here should match that pattern for consistency and clarity.

Additionally, getDeviceId() remains unavailable on ESP-IDF v5 due to mbedTLS API changes—the TODO indicates this is known but unresolved.

🛠️ Suggested fix
-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)    // ToDO: find a solution to make this work in V5
+#if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))    // TODO: Update mbedTLS SHA1 API for ESP-IDF v5 support
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) // ToDO: find a solution to make this work in V5
`#if` !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)) // TODO: Update mbedTLS SHA1 API for ESP-IDF v5 support
🤖 Prompt for AI Agents
In `@wled00/util.cpp` around lines 1139 - 1140, The preprocessor guard around
computeSHA1() and getDeviceId() in util.cpp must match the established pattern
used in fcn_declare.h and json.cpp; replace the current simplistic
ESP_IDF_VERSION check with the explicit guard used elsewhere: check for either
non-ESP32 builds or ESP-IDF < 5.0 (i.e., the pattern
!defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
) so the declarations/definitions of computeSHA1 and getDeviceId are
consistently enabled/disabled; keep the TODO comment about getDeviceId
unavailability on ESP-IDF v5 intact.

@troyhacks
Copy link
Contributor

troyhacks commented Feb 10, 2026

Would be great to get your input on this @troyhacks

First off, move I2C to IDF calls. That will solve a lot of headaches right off that bat.

I'll have more as I think about it.

A good test is to comment out Arduino.h and see what breaks. 😁

@softhack007
Copy link
Member

Flash size comparison:

esp32 "V4" esp32 "V5" increase
Flash 1218637 77.5% 1246240 79.2% 27Kb
Ram 78696 24.0% 84084 25.7% 5Kb

coderabbitai[bot]

This comment was marked as resolved.

* remove duplicated -D WLED_DISABLE_INFRARED
* fix indentation in WLED::initConnection()
coderabbitai[bot]

This comment was marked as resolved.

@troyhacks
Copy link
Contributor

@softhack007 now do it with LTO.

@wled wled deleted a comment from coderabbitai bot Feb 11, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@platformio.ini`:
- Around line 505-525: The esp32dev_V4 regression environment contains test-only
build flags (WLED_USE_ETHERNET and the pin overrides RLYPIN and BTNPIN) which
should be removed from the default_envs to avoid skewing V4 regression results;
remove those flags from the [env:esp32dev_V4] build_flags and create a separate
test-only env (e.g., [env:esp32dev_V4_ethernet_test]) that sets -D
WLED_USE_ETHERNET -D RLYPIN=-1 -D BTNPIN=-1 (and any related lib_ignore entries
such as esp_dmx) so the regression env remains standard while the test env
captures the temporary Ethernet/pin overrides.

In `@wled00/bus_manager.cpp`:
- Around line 421-427: The code currently calls ledcAttach(...) under IDF v5
which auto-allocates channels; change this to explicitly bind the expected
channel index (channel = _ledcStart + i) using ledcAttachChannel (or the v5
equivalent that takes a channel argument) so that the assigned channel matches
the code's later assumptions (references: ledcAttach, channel, _ledcStart,
_pins, and the timer reset and direct register writes around lines noted).
Ensure you compute/assign channel = _ledcStart + i before attaching and replace
the ledcAttach(...) call with ledcAttachChannel(channel, _pins[i],
/*...params...*/) so timer reset and PWM duty writes target the correct channel.

Comment on lines +505 to +525
[env:esp32dev_V4]
;; uses V4 framework - for checking that the code still builds in V4
board = esp32dev
platform = ${esp32_idf_V4.platform}
platform_packages = ${esp32_idf_V4.platform_packages}
build_unflags = ${common.build_unflags}
custom_usermods = audioreactive
build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32\" #-D WLED_DISABLE_BROWNOUT_DET
-D WLED_ENABLE_DMX_INPUT ;; TODO: fix lots of compile errors in dmx_input.cpp
custom_usermods = ${common.default_usermods}
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
-D WLED_DISABLE_INFRARED ;; TODO: remove once we have updated for V5
-D WLED_USE_SHARED_RMT ;; TODO: disabled NeoEsp32RmtMethodIsr
-D WLED_USE_ETHERNET -D RLYPIN=-1 -D BTNPIN=-1 ;; TODO: this is just for testing - remove before merging to main
lib_deps = ${esp32_idf_V4.lib_deps}
lib_ignore =
NeoESP32RmtHI ;; TODO: disabled NeoEsp32RmtMethodIsr
esp_dmx ;; TODO: fix lots of compile errors in dmx_input.cpp
monitor_filters = esp32_exception_decoder
board_build.partitions = ${esp32.default_partitions}
board_build.flash_mode = dio

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove the testing-only Ethernet flags before merge.

WLED_USE_ETHERNET plus pin overrides are marked TODO-only in the V4 regression env, but this env is in default_envs. That can skew V4 regression results away from the standard build. Consider moving these flags to an override or a dedicated test env.

Do you want me to draft a minimal test-only env block or open a tracking issue for this cleanup?

🤖 Prompt for AI Agents
In `@platformio.ini` around lines 505 - 525, The esp32dev_V4 regression
environment contains test-only build flags (WLED_USE_ETHERNET and the pin
overrides RLYPIN and BTNPIN) which should be removed from the default_envs to
avoid skewing V4 regression results; remove those flags from the
[env:esp32dev_V4] build_flags and create a separate test-only env (e.g.,
[env:esp32dev_V4_ethernet_test]) that sets -D WLED_USE_ETHERNET -D RLYPIN=-1 -D
BTNPIN=-1 (and any related lib_ignore entries such as esp_dmx) so the regression
env remains standard while the test env captures the temporary Ethernet/pin
overrides.

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@wled00/json.cpp`:
- Around line 703-705: The conditional compilation around root[F("deviceId")] =
getDeviceId() causes deviceId to be omitted on ESP32 IDF v5+, so restore a
stable deviceId field in the JSON by either removing the `#if` guard so
root[F("deviceId")] is always set (calling getDeviceId()), or implement a
v5-safe alternative (e.g., getDeviceIdV5() or a fallback value) and assign it to
root[F("deviceId")] when ESP_IDF_VERSION >= 5; ensure you update the code paths
around getDeviceId and the preprocessor condition so downstream consumers always
see a deviceId field (even if it is an explicit fallback/placeholder).

Comment on lines +703 to +705
#if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)) // ToDO: find a solution to make this work in V5
root[F("deviceId")] = getDeviceId();
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

deviceId omitted on ESP32 IDF v5+.

This drops a previously exposed field in info. Please confirm downstream consumers tolerate it or provide an alternative when the V5 SHA1 path is ready.

🤖 Prompt for AI Agents
In `@wled00/json.cpp` around lines 703 - 705, The conditional compilation around
root[F("deviceId")] = getDeviceId() causes deviceId to be omitted on ESP32 IDF
v5+, so restore a stable deviceId field in the JSON by either removing the `#if`
guard so root[F("deviceId")] is always set (calling getDeviceId()), or implement
a v5-safe alternative (e.g., getDeviceIdV5() or a fallback value) and assign it
to root[F("deviceId")] when ESP_IDF_VERSION >= 5; ensure you update the code
paths around getDeviceId and the preprocessor condition so downstream consumers
always see a deviceId field (even if it is an explicit fallback/placeholder).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (5)
platformio.ini (4)

130-130: WLED_USE_SHARED_RMT still defined in [common] and [esp32_idf_V5].

Line 130 defines it in [common].build_flags (applies to all platforms, including ESP8266 where it's meaningless), and line 336 defines it again in [esp32_idf_V5].build_flags. Since all ESP32 V5 environments inherit from [esp32_idf_V5], the definition in [common] is redundant and should be removed to keep it scoped to ESP32 only.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platformio.ini` at line 130, Remove the redundant global definition of
WLED_USE_SHARED_RMT from the [common].build_flags and ensure the only occurrence
remains in [esp32_idf_V5].build_flags so the flag is scoped to ESP32 V5
environments; update the build_flags in the [common] section (remove the -D
WLED_USE_SHARED_RMT entry) and keep the existing -D WLED_USE_SHARED_RMT in the
[esp32_idf_V5] section to avoid applying the flag to non-ESP32 targets like
ESP8266.

599-611: [env:esp32_wrover] extends esp32_idf_V5 but overrides build_unflags with ${common.build_unflags}.

Using extends = esp32_idf_V5 gives this env all V5 base settings, but line 606 then overrides build_unflags back to ${common.build_unflags}, dropping V5-specific unflags. This should use ${esp32_idf_V5.build_unflags} for consistency with the other V5-based environments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platformio.ini` around lines 599 - 611, The env "[env:esp32_wrover]"
currently extends esp32_idf_V5 but replaces build_unflags with
${common.build_unflags}, which removes the V5-specific unflags; update the
build_unflags entry in the [env:esp32_wrover] block to use
${esp32_idf_V5.build_unflags} instead of ${common.build_unflags} so it inherits
the V5 unflags while keeping the common defaults intact (modify the
build_unflags symbol in that env).

526-537: build_unflags should use V5-specific unflags.

[env:esp32dev] uses ${esp32_idf_V5.platform} and ${esp32_idf_V5.build_flags} but inherits ${common.build_unflags} instead of ${esp32_idf_V5.build_unflags}. This drops the -Wno-volatile unflag (line 329) needed for C files in V5 builds. The same issue applies to esp32dev_debug (line 544), esp32dev_8M (line 555), esp32dev_16M (line 571), esp32_eth (line 588), esp32_wrover (line 606), and usermods (line 782).

Proposed fix for esp32dev (apply similarly to other envs)
-build_unflags = ${common.build_unflags}
+build_unflags = ${esp32_idf_V5.build_unflags}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platformio.ini` around lines 526 - 537, The env [env:esp32dev] (and the other
V5-based envs esp32dev_debug, esp32dev_8M, esp32dev_16M, esp32_eth,
esp32_wrover, usermods) incorrectly reference ${common.build_unflags} which
omits the V5-specific unflags; update the build_unflags assignment in each of
those env blocks to use ${esp32_idf_V5.build_unflags} instead of
${common.build_unflags} so the V5-only unflag (e.g. -Wno-volatile) is included
for C files when building with esp32_idf_V5.

505-524: ⚠️ Potential issue | 🟡 Minor

V4 regression env still carries testing-only Ethernet flags.

Line 517 has -D WLED_USE_ETHERNET -D RLYPIN=-1 -D BTNPIN=-1 with a TODO comment. Since esp32dev_V4 is in default_envs (line 23), this testing configuration will be included in CI/release builds, which could produce misleading regression results. These should be removed or moved to a separate test environment before merge.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platformio.ini` around lines 505 - 524, The esp32dev_V4 environment includes
testing-only build flags (-D WLED_USE_ETHERNET, -D RLYPIN=-1, -D BTNPIN=-1)
which are pulled into CI because env:esp32dev_V4 is listed in default_envs;
remove these flags from the env:esp32dev_V4 block (or move them into a new
dedicated test env) and ensure default_envs no longer includes that test-only
env so CI/release builds use a clean V4 regression config; update the TODO
comment to reflect the moved/removed flags.
wled00/util.cpp (1)

1139-1140: Guard pattern inconsistency with fcn_declare.h — already flagged.

The guard at line 1139 uses #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) but fcn_declare.h and json.cpp use the safer pattern #if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)). If ESP_IDF_VERSION_VAL is not defined on ESP8266, this line would cause a preprocessor error.

Proposed fix
-#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)    // ToDO: find a solution to make this work in V5
+#if !defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))    // TODO: find a solution to make this work in V5
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wled00/util.cpp` around lines 1139 - 1140, The preprocessor guard in util.cpp
using "#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)" can error on
platforms where ESP_IDF_VERSION_VAL isn't defined; update the guard to the same
safe pattern used in fcn_declare.h and json.cpp by changing it to the combined
check that first tests ARDUINO_ARCH_ESP32 (e.g., use the pattern
"!defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0,
0))") so the preprocessor won't evaluate ESP_IDF_VERSION_VAL on non-ESP32 builds
and the block around util.cpp's conditional compiles consistently with
fcn_declare.h and json.cpp.
🧹 Nitpick comments (2)
platformio.ini (2)

13-39: Commented-out and duplicate entries in default_envs create confusion.

Lines 30-31 comment out esp32s3dev_16MB_opi and esp32s3dev_8MB_opi, but then lines 35-36 also list them (line 35 commented, line 36 uncommented). The esp32s3_4M_qspi appears twice (lines 32 and 38), both commented. This duplication makes it hard to tell which envs are intentionally active.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platformio.ini` around lines 13 - 39, The default_envs list contains
duplicate and contradictory commented/uncommented entries causing confusion;
clean it up by consolidating and uncommenting only the intended environment
names (e.g., default_envs, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi,
esp32s3_4M_qspi, nodemcuv2_160, esp32dev_V4, etc.), remove duplicate commented
lines and ensure each env appears exactly once with the correct comment state
and any TODO notes moved inline next to that single entry so it's clear which
envs are active vs intentionally disabled.

322-346: [esp32_idf_V5] section looks well-structured — good migration foundation.

The V5 section cleanly separates platform, flags, and dependencies. The TODO comments are clear about temporary workarounds. The ESP32_ARDUINO_NO_RGB_BUILTIN flag (line 340) is correctly included per softhack007's recommendation to avoid RMT driver conflicts.

One concern: line 343 uses an unpinned branch reference for esp_dmx:

https://github.com/netmindz/esp_dmx/#esp-idf-v5-fixes

This should be pinned to a commit hash for reproducible builds, consistent with how NeoPixelBus is pinned on line 273. Branch references can break if the branch is rebased or force-pushed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platformio.ini` around lines 322 - 346, The esp_dmx dependency in the
[esp32_idf_V5] env uses an unpinned branch URL
(https://github.com/netmindz/esp_dmx/#esp-idf-v5-fixes) which risks
non-reproducible builds; update the lib_deps entry for esp_dmx to pin to a
specific commit SHA (replace the branch fragment with the repo@<commit-sha> or
use the /commit/<sha> URL format) so builds are deterministic—use the
NeoPixelBus pinning pattern already used elsewhere (NeoPixelBus entry) as the
template when editing the [esp32_idf_V5] lib_deps line.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@platformio.ini`:
- Line 270: Update the AsyncTCP dependency from 3.4.6 to 3.4.7 in the dependency
declaration (change the line containing "esp32async/AsyncTCP @ 3.4.6"); this
upgrades to the release that restores correct AsyncClient::abort() dispose
semantics and prevents the memory leak when dispose callbacks are not triggered.
Ensure any lockfiles or platform-specific dependency pins are also updated so
the build uses AsyncTCP v3.4.7.

In `@wled00/bus_manager.cpp`:
- Around line 416-423: The code directly manipulates LEDC internals
(LEDC.channel_group[gr].channel[ch].duty.duty and
LEDC.channel_group[gr].channel[ch].hpoint.hpoint) to implement dithering, which
is incompatible with ESP-IDF v5; replace that direct struct access with a
compatibility-safe approach: add an `#if/`#else guard on ESP_IDF_VERSION so that
for v5 and newer you either (a) disable hardware dithering and fall back to
no-dither or a software-dither implementation that updates duty via public APIs
(e.g., ledc_set_duty/ledc_set_duty_and_update or Arduino ledcWrite equivalents)
or (b) use any new HAL/API if available, and for older versions keep the
existing direct approach; update any callers around ledcAttachChannel/ledcDetach
to use the guarded behavior and remove direct references to
LEDC.channel_group[...] so the code compiles and behaves correctly across
ESP-IDF versions.

---

Duplicate comments:
In `@platformio.ini`:
- Line 130: Remove the redundant global definition of WLED_USE_SHARED_RMT from
the [common].build_flags and ensure the only occurrence remains in
[esp32_idf_V5].build_flags so the flag is scoped to ESP32 V5 environments;
update the build_flags in the [common] section (remove the -D
WLED_USE_SHARED_RMT entry) and keep the existing -D WLED_USE_SHARED_RMT in the
[esp32_idf_V5] section to avoid applying the flag to non-ESP32 targets like
ESP8266.
- Around line 599-611: The env "[env:esp32_wrover]" currently extends
esp32_idf_V5 but replaces build_unflags with ${common.build_unflags}, which
removes the V5-specific unflags; update the build_unflags entry in the
[env:esp32_wrover] block to use ${esp32_idf_V5.build_unflags} instead of
${common.build_unflags} so it inherits the V5 unflags while keeping the common
defaults intact (modify the build_unflags symbol in that env).
- Around line 526-537: The env [env:esp32dev] (and the other V5-based envs
esp32dev_debug, esp32dev_8M, esp32dev_16M, esp32_eth, esp32_wrover, usermods)
incorrectly reference ${common.build_unflags} which omits the V5-specific
unflags; update the build_unflags assignment in each of those env blocks to use
${esp32_idf_V5.build_unflags} instead of ${common.build_unflags} so the V5-only
unflag (e.g. -Wno-volatile) is included for C files when building with
esp32_idf_V5.
- Around line 505-524: The esp32dev_V4 environment includes testing-only build
flags (-D WLED_USE_ETHERNET, -D RLYPIN=-1, -D BTNPIN=-1) which are pulled into
CI because env:esp32dev_V4 is listed in default_envs; remove these flags from
the env:esp32dev_V4 block (or move them into a new dedicated test env) and
ensure default_envs no longer includes that test-only env so CI/release builds
use a clean V4 regression config; update the TODO comment to reflect the
moved/removed flags.

In `@wled00/util.cpp`:
- Around line 1139-1140: The preprocessor guard in util.cpp using "#if
ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)" can error on platforms where
ESP_IDF_VERSION_VAL isn't defined; update the guard to the same safe pattern
used in fcn_declare.h and json.cpp by changing it to the combined check that
first tests ARDUINO_ARCH_ESP32 (e.g., use the pattern
"!defined(ARDUINO_ARCH_ESP32) || (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0,
0))") so the preprocessor won't evaluate ESP_IDF_VERSION_VAL on non-ESP32 builds
and the block around util.cpp's conditional compiles consistently with
fcn_declare.h and json.cpp.

---

Nitpick comments:
In `@platformio.ini`:
- Around line 13-39: The default_envs list contains duplicate and contradictory
commented/uncommented entries causing confusion; clean it up by consolidating
and uncommenting only the intended environment names (e.g., default_envs,
esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, nodemcuv2_160,
esp32dev_V4, etc.), remove duplicate commented lines and ensure each env appears
exactly once with the correct comment state and any TODO notes moved inline next
to that single entry so it's clear which envs are active vs intentionally
disabled.
- Around line 322-346: The esp_dmx dependency in the [esp32_idf_V5] env uses an
unpinned branch URL (https://github.com/netmindz/esp_dmx/#esp-idf-v5-fixes)
which risks non-reproducible builds; update the lib_deps entry for esp_dmx to
pin to a specific commit SHA (replace the branch fragment with the
repo@<commit-sha> or use the /commit/<sha> URL format) so builds are
deterministic—use the NeoPixelBus pinning pattern already used elsewhere
(NeoPixelBus entry) as the template when editing the [esp32_idf_V5] lib_deps
line.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9297775 and 908e17b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (16)
  • package.json
  • platformio.ini
  • wled00/bus_manager.cpp
  • wled00/e131.cpp
  • wled00/fcn_declare.h
  • wled00/improv.cpp
  • wled00/json.cpp
  • wled00/network.cpp
  • wled00/ntp.cpp
  • wled00/src/dependencies/espalexa/Espalexa.h
  • wled00/udp.cpp
  • wled00/util.cpp
  • wled00/wled.cpp
  • wled00/wled.h
  • wled00/wled_server.cpp
  • wled00/xml.cpp
🚧 Files skipped from review as they are similar to previous changes (4)
  • wled00/e131.cpp
  • wled00/udp.cpp
  • wled00/wled.cpp
  • wled00/json.cpp

[esp32_all_variants]
lib_deps =
esp32async/AsyncTCP @ 3.4.7
esp32async/AsyncTCP @ 3.4.6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

AsyncTCP 3.4.6 3.4.7 changelog memory bug ESP32

💡 Result:

  • AsyncTCP v3.4.7 (released Aug 2, 2025): Fixes a memory leak introduced in v3.4.6; release notes explicitly say “Please do not use v3.4.6.” The fix is “Restore abort dispose semantics” (PR Updated readme #82). When calling AsyncClient::abort(), it again enqueues an error event (as it did before PR #79), which prevents leaks caused by missing dispose callbacks. [1][2]
  • AsyncTCP v3.4.6 (released Jul 30, 2025): main change is “Error/closing stability” (PR limit led power consumption (using estimation) #79)—this is the change that v3.4.7 identifies as having introduced the memory leak. [3][1]

Sources: [1] [2] [3]


🏁 Script executed:

# Search for any references in WLED codebase about AsyncTCP versions or issues
rg -i "asynctcp|3\.4\.[67]" --type md --type txt

Repository: wled/WLED

Length of output: 276


AsyncTCP 3.4.6 must be upgraded to 3.4.7 — this version contains a documented memory leak introduced in PR #79.

The official AsyncTCP v3.4.7 release (Aug 2, 2025) explicitly states: "Please do not use v3.4.6." The leak occurs when AsyncClient::abort() is called and dispose callbacks are not triggered. v3.4.7 restores the abort dispose semantics to prevent this. Shipping with 3.4.6 risks memory exhaustion on ESP32 devices.

Fix
-  esp32async/AsyncTCP @ 3.4.6
+  esp32async/AsyncTCP @ 3.4.7
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
esp32async/AsyncTCP @ 3.4.6
esp32async/AsyncTCP @ 3.4.7
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@platformio.ini` at line 270, Update the AsyncTCP dependency from 3.4.6 to
3.4.7 in the dependency declaration (change the line containing
"esp32async/AsyncTCP @ 3.4.6"); this upgrades to the release that restores
correct AsyncClient::abort() dispose semantics and prevents the memory leak when
dispose callbacks are not triggered. Ensure any lockfiles or platform-specific
dependency pins are also updated so the build uses AsyncTCP v3.4.7.

Comment on lines 416 to +423
unsigned channel = _ledcStart + i;
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0)
ledcSetup(channel, _frequency, _depth - (dithering*4)); // with dithering _frequency doesn't really matter as resolution is 8 bit
ledcAttachPin(_pins[i], channel);
#else
ledcAttachChannel(_pins[i], _frequency, _depth - (dithering*4), channel);
// LEDC timer reset credit @dedehai
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Get the specific lines mentioned in the review
sed -n '410,430p' wled00/bus_manager.cpp
echo "---"
sed -n '580,600p' wled00/bus_manager.cpp

Repository: wled/WLED

Length of output: 1661


🏁 Script executed:

# Search for ledcAttachChannel and ledcDetach usage patterns in the file
rg -n "ledcAttachChannel|ledcDetach" wled00/bus_manager.cpp -B 2 -A 2

Repository: wled/WLED

Length of output: 529


🏁 Script executed:

# Check if there are any direct LEDC struct accesses like LEDC.channel_group
rg -n "LEDC\." wled00/bus_manager.cpp

Repository: wled/WLED

Length of output: 360


🌐 Web query:

Arduino-ESP32 v3 ledcAttachChannel function signature parameters

💡 Result:

In Arduino-ESP32 v3.x, the function signature is:
bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, int8_t channel); [1]

Parameters [1]:

  • pin (uint8_t): GPIO to output PWM on
  • freq (uint32_t): PWM frequency (Hz)
  • resolution (uint8_t): duty resolution in bits (typically 1–14, 1–20 on ESP32)
  • channel (int8_t): LEDC channel number to use (manual assignment)

Notes: if the channel is already configured, the passed freq and resolution are ignored; multiple pins attached to the same channel share the same duty cycle. [1]


🌐 Web query:

Arduino-ESP32 v3 ledcDetach function documentation

💡 Result:

In Arduino-ESP32 v3.x, the LEDC “detach” API is:

  • Signature: bool ledcDetach(uint8_t pin);
  • Purpose: Detaches the specified GPIO pin from the LEDC (PWM) peripheral.
  • Return value: true on success, false on error. [1]

Migration note (2.x → 3.0): ledcDetachPin was renamed to ledcDetach, and the API generally moved from channel-based calls toward pin-based calls. [2]

Sources: [1], [2]


🏁 Script executed:

# Find the function containing lines 549-550
sed -n '540,560p' wled00/bus_manager.cpp | head -30

Repository: wled/WLED

Length of output: 1196


🏁 Script executed:

# Get broader context around lines 549-550
sed -n '535,560p' wled00/bus_manager.cpp

Repository: wled/WLED

Length of output: 1315


Critical: Direct LEDC struct access (lines 549–550) incompatible with ESP-IDF v5.

While the ledcAttachChannel and ledcDetach API signatures at lines 416–423 and 587–591 are correctly aligned with Arduino-ESP32 v3, the implementation has a blocking issue: lines 549–550 directly access LEDC struct internals (LEDC.channel_group[gr].channel[ch].duty.duty and LEDC.channel_group[gr].channel[ch].hpoint.hpoint) to implement dithering. This approach is not supported in ESP-IDF v5, where the framework manages LEDC channels internally and no public HAL API exposes dithering control. The current comment states "no HAL exposed function for dithering" — this design dependency must be resolved before ESP-IDF v5 support is viable.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wled00/bus_manager.cpp` around lines 416 - 423, The code directly manipulates
LEDC internals (LEDC.channel_group[gr].channel[ch].duty.duty and
LEDC.channel_group[gr].channel[ch].hpoint.hpoint) to implement dithering, which
is incompatible with ESP-IDF v5; replace that direct struct access with a
compatibility-safe approach: add an `#if/`#else guard on ESP_IDF_VERSION so that
for v5 and newer you either (a) disable hardware dithering and fall back to
no-dither or a software-dither implementation that updates duty via public APIs
(e.g., ledc_set_duty/ledc_set_duty_and_update or Arduino ledcWrite equivalents)
or (b) use any new HAL/API if available, and for older versions keep the
existing direct approach; update any callers around ledcAttachChannel/ledcDetach
to use the guarded behavior and remove direct references to
LEDC.channel_group[...] so the code compiles and behaves correctly across
ESP-IDF versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement keep This issue will never become stale/closed automatically magic major This is a non-trivial major feature and will take some time to implement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants