Skip to content

feat: add ESP-IDF framework support by migrating to ESPHome socket API#13

Open
ablyler wants to merge 1 commit intocbpowell:masterfrom
ablyler:feature/esp-idf-support
Open

feat: add ESP-IDF framework support by migrating to ESPHome socket API#13
ablyler wants to merge 1 commit intocbpowell:masterfrom
ablyler:feature/esp-idf-support

Conversation

@ablyler
Copy link
Contributor

@ablyler ablyler commented Nov 9, 2025

Replace Arduino-specific AsyncUDP library with ESPHome's cross-platform socket API to enable compatibility with both Arduino and ESP-IDF frameworks.

Changes:

  • Replace AsyncUDP/ESPAsyncUDP with socket::socket_ip() for UDP communication
  • Convert from callback-based packet handling (onPacket) to polling in loop()
  • Add framework-specific IP address formatting for lwIP (Arduino) and BSD sockets (ESP-IDF)
  • Remove ESPAsyncUDP and ESP32 Async UDP library dependencies
  • Add loop() override to poll for incoming UDP packets
  • Maintain backward compatibility with existing ESPSense functionality

This allows the component to work with ESP-IDF framework while maintaining full support for Arduino framework on ESP8266 and ESP32.

Fixes compilation errors when using framework: { type: esp-idf } in ESPHome.

Replace Arduino-specific AsyncUDP library with ESPHome's cross-platform
socket API to enable compatibility with both Arduino and ESP-IDF frameworks.

Changes:
- Replace AsyncUDP/ESPAsyncUDP with socket::socket_ip() for UDP communication
- Convert from callback-based packet handling (onPacket) to polling in loop()
- Add framework-specific IP address formatting for lwIP (Arduino) and BSD sockets (ESP-IDF)
- Remove ESPAsyncUDP and ESP32 Async UDP library dependencies
- Add loop() override to poll for incoming UDP packets
- Maintain backward compatibility with existing ESPSense functionality

This allows the component to work with ESP-IDF framework while maintaining
full support for Arduino framework on ESP8266 and ESP32.

Fixes compilation errors when using framework: { type: esp-idf } in ESPHome.

Signed-off-by: Andy Blyler <andy@blyler.cc>
Copilot AI review requested due to automatic review settings November 9, 2025 14:37
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR migrates the ESPSense component from using platform-specific AsyncUDP libraries to ESPHome's unified socket API. This allows the component to work across different platforms without conditional library dependencies.

  • Replaced AsyncUDP with ESPHome's socket API for unified cross-platform UDP handling
  • Implemented manual UDP socket setup, binding, and packet processing
  • Added comprehensive IP address formatting logic to handle different socket implementations

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
components/espsense/espsense.h Migrated from AsyncUDP to ESPHome socket API with manual socket setup, non-blocking I/O, and cross-platform IP address handling
components/espsense/init.py Removed platform-specific AsyncUDP library dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +147 to +150
if (len > REQ_SIZE) {
ESP_LOGD("ESPSense", "Packet is oversized, ignoring");
return;
}
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

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

This validation is duplicated in both loop() and parse_packet(). The check in loop() (lines 147-150) can be removed since the same validation already occurs in parse_packet() (lines 221-225), eliminating redundant code.

Suggested change
if (len > REQ_SIZE) {
ESP_LOGD("ESPSense", "Packet is oversized, ignoring");
return;
}

Copilot uses AI. Check for mistakes.
Comment on lines +158 to +179
#ifdef USE_SOCKET_IMPL_LWIP_TCP
// lwIP structure - access bytes directly
snprintf(remote_ip_str, sizeof(remote_ip_str), "%d.%d.%d.%d",
ip_bytes[0], ip_bytes[1], ip_bytes[2], ip_bytes[3]);
#else
// BSD sockets - sin_addr.s_addr is uint32_t in network byte order
uint32_t ip_addr;
#ifdef USE_SOCKET_IMPL_BSD_SOCKETS
ip_addr = addr_in->sin_addr.s_addr;
// ntohl should be available via socket headers
ip_addr = ntohl(ip_addr);
#else
// Fallback: access as bytes
memcpy(&ip_addr, &addr_in->sin_addr.s_addr, sizeof(uint32_t));
// Manual byte swap for network to host
ip_addr = ((ip_addr & 0xFF000000) >> 24) | ((ip_addr & 0x00FF0000) >> 8) |
((ip_addr & 0x0000FF00) << 8) | ((ip_addr & 0x000000FF) << 24);
#endif
snprintf(remote_ip_str, sizeof(remote_ip_str), "%d.%d.%d.%d",
(ip_addr >> 24) & 0xFF, (ip_addr >> 16) & 0xFF,
(ip_addr >> 8) & 0xFF, ip_addr & 0xFF);
#endif
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

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

This complex nested conditional logic for IP address formatting is difficult to follow and maintain. Consider extracting this into a separate helper function (e.g., format_ip_address()) to improve readability and testability.

Copilot uses AI. Check for mistakes.
Comment on lines +157 to +158
uint8_t *ip_bytes = (uint8_t *)&addr_in->sin_addr;
#ifdef USE_SOCKET_IMPL_LWIP_TCP
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

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

The variable ip_bytes is declared but only used in the USE_SOCKET_IMPL_LWIP_TCP branch (lines 160-161). Move this declaration inside that conditional block to limit its scope and improve code clarity.

Suggested change
uint8_t *ip_bytes = (uint8_t *)&addr_in->sin_addr;
#ifdef USE_SOCKET_IMPL_LWIP_TCP
#ifdef USE_SOCKET_IMPL_LWIP_TCP
uint8_t *ip_bytes = (uint8_t *)&addr_in->sin_addr;

Copilot uses AI. Check for mistakes.
@cbpowell
Copy link
Owner

Hey thanks for this! Sorry for the delay, just haven’t had a chance to look at it yet. I’ll aim to next week.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants