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