mirror of
https://github.com/esphome/esphome.git
synced 2024-11-24 16:08:10 +01:00
Migrate e131 to use socket instead of WiFiUDP arduino library (#4832)
This commit is contained in:
parent
18f4e41550
commit
9e3ecc8372
6 changed files with 58 additions and 68 deletions
|
@ -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(*METHODS, upper=True),
|
||||||
cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of(
|
}
|
||||||
*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,22 +56,22 @@ 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;
|
||||||
|
}
|
||||||
|
payload.resize(len);
|
||||||
|
memmove(&payload[0], buf, len);
|
||||||
|
|
||||||
if (!udp_->read(&payload[0], payload.size())) {
|
if (!this->packet_(payload, universe, packet)) {
|
||||||
continue;
|
ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size());
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!packet_(payload, universe, packet)) {
|
if (!this->process_(universe, packet)) {
|
||||||
ESP_LOGV(TAG, "Invalid packet received of size %zu.", payload.size());
|
ESP_LOGV(TAG, "Ignored packet for %d universe of size %d.", universe, packet.count);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!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 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
|
|
||||||
|
|
Loading…
Reference in a new issue