Merge pull request #14017 from tony-fav/dev-DDPLightSchemes

DDP Schemes for Light (5) and WS2812 (15) with USE_NETWORK_LIGHT_SCHEMES
This commit is contained in:
Theo Arends 2022-01-07 10:12:47 +01:00 committed by GitHub
commit 84da970ecc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 140 additions and 1 deletions

View File

@ -124,7 +124,11 @@
#define XDRV_04 4
// #define DEBUG_LIGHT
#ifdef USE_NETWORK_LIGHT_SCHEMES
enum LightSchemes { LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_DDP, LS_MAX };
#else
enum LightSchemes { LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX };
#endif
const uint8_t LIGHT_COLOR_SIZE = 25; // Char array scolor size
@ -280,6 +284,11 @@ static uint32_t min3(uint32_t a, uint32_t b, uint32_t c) {
return (a < b && a < c) ? a : (b < c) ? b : c;
}
#ifdef USE_NETWORK_LIGHT_SCHEMES
WiFiUDP ddp_udp;
uint8_t ddp_udp_up = 0;
#endif
//
// LightStateClass
// This class is an abstraction of the current light state.
@ -1615,6 +1624,51 @@ void LightCycleColor(int8_t direction)
light_controller.calcLevels(Light.new_color);
}
#ifdef USE_NETWORK_LIGHT_SCHEMES
void LightListenDDP()
{
// Light channels gets completely controlled over DDP. So, we don't really check other settings.
// To enter this scheme, we are already assured the light is at least RGB
static uint8_t ddp_color[5] = { 0, 0, 0, 0, 0 };
// Can't be trying to initialize UDP too early.
if (TasmotaGlobal.restart_flag || TasmotaGlobal.global_state.network_down) {
light_state.setChannels(ddp_color);
light_controller.calcLevels(Light.new_color);
return;
}
// Start DDP listener, if fail, just set last ddp_color
if (!ddp_udp_up) {
if (!ddp_udp.begin(4048)) {
light_state.setChannels(ddp_color);
light_controller.calcLevels(Light.new_color);
return;
}
ddp_udp_up = 1;
AddLog(LOG_LEVEL_DEBUG_MORE, "DDP: UDP Listener Started: Normal Scheme");
}
// Get the DDP payload over UDP
std::vector<uint8_t> payload;
while (uint16_t packet_size = ddp_udp.parsePacket()) {
payload.resize(packet_size);
if (!ddp_udp.read(&payload[0], payload.size())) {
continue;
}
}
// No verification checks performed against packet besides length
if (payload.size() > 12) {
ddp_color[0] = payload[10];
ddp_color[1] = payload[11];
ddp_color[2] = payload[12];
}
light_state.setChannels(ddp_color);
light_controller.calcLevels(Light.new_color);
}
#endif
void LightSetPower(void)
{
// Light.power = XdrvMailbox.index;
@ -1690,7 +1744,21 @@ void LightAnimate(void)
if (Settings->light_scheme >= LS_MAX) {
power_off = true;
}
#ifdef USE_NETWORK_LIGHT_SCHEMES
if (ddp_udp_up) {
ddp_udp.stop();
ddp_udp_up = 0;
AddLog(LOG_LEVEL_DEBUG_MORE, "DDP: UDP Stopped: Power Off");
}
#endif
} else {
#ifdef USE_NETWORK_LIGHT_SCHEMES
if ((Settings->light_scheme < LS_MAX) && (Settings->light_scheme != LS_DDP) && (ddp_udp_up)) {
ddp_udp.stop();
ddp_udp_up = 0;
AddLog(LOG_LEVEL_DEBUG_MORE, "DDP: UDP Stopped: Normal Scheme not DDP");
}
#endif
switch (Settings->light_scheme) {
case LS_POWER:
light_controller.calcLevels(Light.new_color);
@ -1743,6 +1811,11 @@ void LightAnimate(void)
Light.new_color[2] = changeUIntScale(Light.new_color[2], 0, 255, 0, Settings->light_color[2]);
}
break;
#ifdef USE_NETWORK_LIGHT_SCHEMES
case LS_DDP:
LightListenDDP();
break;
#endif
default:
XlgtCall(FUNC_SET_SCHEME);
}

View File

@ -37,7 +37,11 @@
#define XLGT_01 1
#ifdef USE_NETWORK_LIGHT_SCHEMES
const uint8_t WS2812_SCHEMES = 10; // Number of WS2812 schemes
#else
const uint8_t WS2812_SCHEMES = 9; // Number of WS2812 schemes
#endif
const char kWs2812Commands[] PROGMEM = "|" // No prefix
D_CMND_LED "|" D_CMND_PIXELS "|" D_CMND_ROTATION "|" D_CMND_WIDTH "|" D_CMND_STEPPIXELS ;
@ -167,7 +171,12 @@ WsColor kwanzaa[3] = { 255,0,0, 0,0,0, 0,255,0 };
WsColor kRainbow[7] = { 255,0,0, 255,128,0, 255,255,0, 0,255,0, 0,0,255, 128,0,255, 255,0,255 };
WsColor kFire[3] = { 255,0,0, 255,102,0, 255,192,0 };
WsColor kStairs[2] = { 0,0,0, 255,255,255 };
#ifdef USE_NETWORK_LIGHT_SCHEMES
ColorScheme kSchemes[WS2812_SCHEMES -2] = { // Skip clock scheme and DDP scheme
#else
ColorScheme kSchemes[WS2812_SCHEMES -1] = { // Skip clock scheme
#endif
kIncandescent, 2,
kRgb, 3,
kChristmas, 2,
@ -492,6 +501,51 @@ void Ws2812Steps(uint32_t schemenr) {
Ws2812StripShow();
}
#ifdef USE_NETWORK_LIGHT_SCHEMES
void Ws2812DDP(void)
{
#if (USE_WS2812_CTYPE > NEO_3LED)
RgbwColor c;
c.W = 0;
#else
RgbColor c;
#endif
c.R = 0;
c.G = 0;
c.B = 0;
// Can't be trying to initialize UDP too early.
if (TasmotaGlobal.restart_flag || TasmotaGlobal.global_state.network_down) return;
// Start DDP listener, if fail, just set last ddp_color
if (!ddp_udp_up) {
if (!ddp_udp.begin(4048)) return;
ddp_udp_up = 1;
AddLog(LOG_LEVEL_DEBUG_MORE, "DDP: UDP Listener Started: WS2812 Scheme");
}
// Get the DDP payload over UDP
std::vector<uint8_t> payload;
while (uint16_t packet_size = ddp_udp.parsePacket()) {
payload.resize(packet_size);
if (!ddp_udp.read(&payload[0], payload.size())) {
continue;
}
}
// No verification checks performed against packet besides length
if (payload.size() > (9+3*Settings->light_pixels)) {
for (uint32_t i = 0; i < Settings->light_pixels; i++) {
c.R = payload[10+3*i];
c.G = payload[11+3*i];
c.B = payload[12+3*i];
strip->SetPixelColor(i, c);
}
Ws2812StripShow();
}
}
#endif
void Ws2812Clear(void)
{
strip->ClearTo(0);
@ -580,7 +634,14 @@ bool Ws2812SetChannels(void)
void Ws2812ShowScheme(void)
{
uint32_t scheme = Settings->light_scheme - Ws2812.scheme_offset;
#ifdef USE_NETWORK_LIGHT_SCHEMES
if ((scheme != 9) && (ddp_udp_up)) {
ddp_udp.stop();
ddp_udp_up = 0;
AddLog(LOG_LEVEL_DEBUG_MORE, "DDP: UDP Stopped: WS2812 Scheme not DDP");
}
#endif
switch (scheme) {
case 0: // Clock
if ((1 == TasmotaGlobal.state_250mS) || (Ws2812.show_next)) {
@ -588,6 +649,11 @@ void Ws2812ShowScheme(void)
Ws2812.show_next = 0;
}
break;
#ifdef USE_NETWORK_LIGHT_SCHEMES
case 9:
Ws2812DDP();
break;
#endif
default:
if(Settings->light_step_pixels > 0){
Ws2812Steps(scheme -1);