mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Migrate e131 to use socket instead of WiFiUDP arduino library (#4832)
This commit is contained in:
		| @@ -4,6 +4,7 @@ from esphome.components.light.types import AddressableLightEffect | |||||||
| from esphome.components.light.effects import register_addressable_effect | from esphome.components.light.effects import register_addressable_effect | ||||||
| from esphome.const import CONF_ID, CONF_NAME, CONF_METHOD, CONF_CHANNELS | from esphome.const import CONF_ID, CONF_NAME, CONF_METHOD, CONF_CHANNELS | ||||||
|  |  | ||||||
|  | AUTO_LOAD = ["socket"] | ||||||
| DEPENDENCIES = ["network"] | DEPENDENCIES = ["network"] | ||||||
|  |  | ||||||
| e131_ns = cg.esphome_ns.namespace("e131") | e131_ns = cg.esphome_ns.namespace("e131") | ||||||
| @@ -23,16 +24,11 @@ CHANNELS = { | |||||||
| CONF_UNIVERSE = "universe" | CONF_UNIVERSE = "universe" | ||||||
| CONF_E131_ID = "e131_id" | CONF_E131_ID = "e131_id" | ||||||
|  |  | ||||||
| CONFIG_SCHEMA = cv.All( | CONFIG_SCHEMA = cv.Schema( | ||||||
|     cv.Schema( |  | ||||||
|     { |     { | ||||||
|         cv.GenerateID(): cv.declare_id(E131Component), |         cv.GenerateID(): cv.declare_id(E131Component), | ||||||
|             cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of( |         cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of(*METHODS, upper=True), | ||||||
|                 *METHODS, upper=True |  | ||||||
|             ), |  | ||||||
|     } |     } | ||||||
|     ), |  | ||||||
|     cv.only_with_arduino, |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,18 +1,7 @@ | |||||||
| #ifdef USE_ARDUINO |  | ||||||
|  |  | ||||||
| #include "e131.h" | #include "e131.h" | ||||||
| #include "e131_addressable_light_effect.h" | #include "e131_addressable_light_effect.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
| #ifdef USE_ESP32 |  | ||||||
| #include <WiFi.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #ifdef USE_ESP8266 |  | ||||||
| #include <ESP8266WiFi.h> |  | ||||||
| #include <WiFiUdp.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace e131 { | namespace e131 { | ||||||
|  |  | ||||||
| @@ -22,17 +11,41 @@ static const int PORT = 5568; | |||||||
| E131Component::E131Component() {} | E131Component::E131Component() {} | ||||||
|  |  | ||||||
| E131Component::~E131Component() { | E131Component::~E131Component() { | ||||||
|   if (udp_) { |   if (this->socket_) { | ||||||
|     udp_->stop(); |     this->socket_->close(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void E131Component::setup() { | void E131Component::setup() { | ||||||
|   udp_ = make_unique<WiFiUDP>(); |   this->socket_ = socket::socket_ip(SOCK_DGRAM, IPPROTO_IP); | ||||||
|  |  | ||||||
|   if (!udp_->begin(PORT)) { |   int enable = 1; | ||||||
|     ESP_LOGE(TAG, "Cannot bind E131 to %d.", PORT); |   int err = this->socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); | ||||||
|     mark_failed(); |   if (err != 0) { | ||||||
|  |     ESP_LOGW(TAG, "Socket unable to set reuseaddr: errno %d", err); | ||||||
|  |     // we can still continue | ||||||
|  |   } | ||||||
|  |   err = this->socket_->setblocking(false); | ||||||
|  |   if (err != 0) { | ||||||
|  |     ESP_LOGW(TAG, "Socket unable to set nonblocking mode: errno %d", err); | ||||||
|  |     this->mark_failed(); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   struct sockaddr_storage server; | ||||||
|  |  | ||||||
|  |   socklen_t sl = socket::set_sockaddr_any((struct sockaddr *) &server, sizeof(server), PORT); | ||||||
|  |   if (sl == 0) { | ||||||
|  |     ESP_LOGW(TAG, "Socket unable to set sockaddr: errno %d", errno); | ||||||
|  |     this->mark_failed(); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   server.ss_family = AF_INET; | ||||||
|  |  | ||||||
|  |   err = this->socket_->bind((struct sockaddr *) &server, sizeof(server)); | ||||||
|  |   if (err != 0) { | ||||||
|  |     ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno); | ||||||
|  |     this->mark_failed(); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -43,23 +56,23 @@ void E131Component::loop() { | |||||||
|   std::vector<uint8_t> payload; |   std::vector<uint8_t> payload; | ||||||
|   E131Packet packet; |   E131Packet packet; | ||||||
|   int universe = 0; |   int universe = 0; | ||||||
|  |   uint8_t buf[1460]; | ||||||
|  |  | ||||||
|   while (uint16_t packet_size = udp_->parsePacket()) { |   ssize_t len = this->socket_->read(buf, sizeof(buf)); | ||||||
|     payload.resize(packet_size); |   if (len == -1) { | ||||||
|  |     return; | ||||||
|     if (!udp_->read(&payload[0], payload.size())) { |  | ||||||
|       continue; |  | ||||||
|   } |   } | ||||||
|  |   payload.resize(len); | ||||||
|  |   memmove(&payload[0], buf, len); | ||||||
|  |  | ||||||
|     if (!packet_(payload, universe, packet)) { |   if (!this->packet_(payload, universe, packet)) { | ||||||
|     ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size()); |     ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size()); | ||||||
|       continue; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|     if (!process_(universe, packet)) { |   if (!this->process_(universe, packet)) { | ||||||
|     ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count); |     ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count); | ||||||
|   } |   } | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void E131Component::add_effect(E131AddressableLightEffect *light_effect) { | void E131Component::add_effect(E131AddressableLightEffect *light_effect) { | ||||||
| @@ -106,5 +119,3 @@ bool E131Component::process_(int universe, const E131Packet &packet) { | |||||||
|  |  | ||||||
| }  // namespace e131 | }  // namespace e131 | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|  |  | ||||||
| #endif  // USE_ARDUINO |  | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #ifdef USE_ARDUINO | #include "esphome/components/socket/socket.h" | ||||||
|  |  | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
|  |  | ||||||
| #include <map> | #include <map> | ||||||
| @@ -9,8 +8,6 @@ | |||||||
| #include <set> | #include <set> | ||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
| class UDP; |  | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace e131 { | namespace e131 { | ||||||
|  |  | ||||||
| @@ -47,7 +44,7 @@ class E131Component : public esphome::Component { | |||||||
|   void leave_(int universe); |   void leave_(int universe); | ||||||
|  |  | ||||||
|   E131ListenMethod listen_method_{E131_MULTICAST}; |   E131ListenMethod listen_method_{E131_MULTICAST}; | ||||||
|   std::unique_ptr<UDP> udp_; |   std::unique_ptr<socket::Socket> socket_; | ||||||
|   std::set<E131AddressableLightEffect *> light_effects_; |   std::set<E131AddressableLightEffect *> light_effects_; | ||||||
|   std::map<int, int> universe_consumers_; |   std::map<int, int> universe_consumers_; | ||||||
|   std::map<int, E131Packet> universe_packets_; |   std::map<int, E131Packet> universe_packets_; | ||||||
| @@ -55,5 +52,3 @@ class E131Component : public esphome::Component { | |||||||
|  |  | ||||||
| }  // namespace e131 | }  // namespace e131 | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|  |  | ||||||
| #endif  // USE_ARDUINO |  | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| #ifdef USE_ARDUINO |  | ||||||
|  |  | ||||||
| #include "e131.h" |  | ||||||
| #include "e131_addressable_light_effect.h" | #include "e131_addressable_light_effect.h" | ||||||
|  | #include "e131.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| @@ -92,5 +90,3 @@ bool E131AddressableLightEffect::process_(int universe, const E131Packet &packet | |||||||
|  |  | ||||||
| }  // namespace e131 | }  // namespace e131 | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|  |  | ||||||
| #endif  // USE_ARDUINO |  | ||||||
|   | |||||||
| @@ -1,7 +1,5 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #ifdef USE_ARDUINO |  | ||||||
|  |  | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
| #include "esphome/components/light/addressable_light_effect.h" | #include "esphome/components/light/addressable_light_effect.h" | ||||||
|  |  | ||||||
| @@ -44,5 +42,3 @@ class E131AddressableLightEffect : public light::AddressableLightEffect { | |||||||
|  |  | ||||||
| }  // namespace e131 | }  // namespace e131 | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|  |  | ||||||
| #endif  // USE_ARDUINO |  | ||||||
|   | |||||||
| @@ -1,15 +1,13 @@ | |||||||
| #ifdef USE_ARDUINO | #include <cstring> | ||||||
|  |  | ||||||
| #include "e131.h" | #include "e131.h" | ||||||
|  | #include "esphome/components/network/ip_address.h" | ||||||
| #include "esphome/core/log.h" | #include "esphome/core/log.h" | ||||||
| #include "esphome/core/util.h" | #include "esphome/core/util.h" | ||||||
| #include "esphome/components/network/ip_address.h" |  | ||||||
| #include <cstring> |  | ||||||
|  |  | ||||||
| #include <lwip/init.h> |  | ||||||
| #include <lwip/ip_addr.h> |  | ||||||
| #include <lwip/ip4_addr.h> |  | ||||||
| #include <lwip/igmp.h> | #include <lwip/igmp.h> | ||||||
|  | #include <lwip/init.h> | ||||||
|  | #include <lwip/ip4_addr.h> | ||||||
|  | #include <lwip/ip_addr.h> | ||||||
|  |  | ||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace e131 { | namespace e131 { | ||||||
| @@ -62,7 +60,7 @@ const size_t E131_MIN_PACKET_SIZE = reinterpret_cast<size_t>(&((E131RawPacket *) | |||||||
| bool E131Component::join_igmp_groups_() { | bool E131Component::join_igmp_groups_() { | ||||||
|   if (listen_method_ != E131_MULTICAST) |   if (listen_method_ != E131_MULTICAST) | ||||||
|     return false; |     return false; | ||||||
|   if (!udp_) |   if (this->socket_ == nullptr) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   for (auto universe : universe_consumers_) { |   for (auto universe : universe_consumers_) { | ||||||
| @@ -140,5 +138,3 @@ bool E131Component::packet_(const std::vector<uint8_t> &data, int &universe, E13 | |||||||
|  |  | ||||||
| }  // namespace e131 | }  // namespace e131 | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|  |  | ||||||
| #endif  // USE_ARDUINO |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user