WLED/usermods/wizlights/wizlights.h
ChuckMash 099d2fd03d
WiZ Lights usermod - Adding more options and features (#2638)
* Update wizlights.h

adds new features and options for wizlights usermod

* Update wizlights.h

Change how IPs are numbered.
Non-programmers incorrectly start counting at 1

* Update wizlights.h

updated default cold white enhanced white setting to a lower value.

* Update wizlights.h

added logic for connection check before UDP sending.
Seems more important for ESP32

* Update readme.md
2022-05-03 12:18:21 +02:00

155 lines
5.4 KiB
C++

#pragma once
#include "wled.h"
#include <WiFiUdp.h>
// Maximum number of lights supported
#define MAX_WIZ_LIGHTS 15
WiFiUDP UDP;
class WizLightsUsermod : public Usermod {
private:
unsigned long lastTime = 0;
long updateInterval;
long sendDelay;
long forceUpdateMinutes;
bool forceUpdate;
bool useEnhancedWhite;
long warmWhite;
long coldWhite;
IPAddress lightsIP[MAX_WIZ_LIGHTS]; // Stores Light IP addresses
bool lightsValid[MAX_WIZ_LIGHTS]; // Stores Light IP address validity
uint32_t colorsSent[MAX_WIZ_LIGHTS]; // Stores last color sent for each light
public:
// Send JSON blob to WiZ Light over UDP
// RGB or C/W white
// TODO:
// Better utilize WLED existing white mixing logic
void wizSendColor(IPAddress ip, uint32_t color) {
UDP.beginPacket(ip, 38899);
// If no LED color, turn light off. Note wiz light setting for "Off fade-out" will be applied by the light itself.
if (color == 0) {
UDP.print("{\"method\":\"setPilot\",\"params\":{\"state\":false}}");
// If color is WHITE, try and use the lights WHITE LEDs instead of mixing RGB LEDs
} else if (color == 16777215 && useEnhancedWhite){
// set cold white light only
if (coldWhite > 0 && warmWhite == 0){
UDP.print("{\"method\":\"setPilot\",\"params\":{\"c\":"); UDP.print(coldWhite) ;UDP.print("}}");}
// set warm white light only
if (warmWhite > 0 && coldWhite == 0){
UDP.print("{\"method\":\"setPilot\",\"params\":{\"w\":"); UDP.print(warmWhite) ;UDP.print("}}");}
// set combination of warm and cold white light
if (coldWhite > 0 && warmWhite > 0){
UDP.print("{\"method\":\"setPilot\",\"params\":{\"c\":"); UDP.print(coldWhite) ;UDP.print(",\"w\":"); UDP.print(warmWhite); UDP.print("}}");}
// Send color as RGB
} else {
UDP.print("{\"method\":\"setPilot\",\"params\":{\"r\":");
UDP.print(R(color));
UDP.print(",\"g\":");
UDP.print(G(color));
UDP.print(",\"b\":");
UDP.print(B(color));
UDP.print("}}");
}
UDP.endPacket();
}
// TODO: Check millis() rollover
void loop() {
// Make sure we are connected first
if (!WLED_CONNECTED) return;
unsigned long ellapsedTime = millis() - lastTime;
if (ellapsedTime > updateInterval) {
bool update = false;
for (uint8_t i = 0; i < MAX_WIZ_LIGHTS; i++) {
if (!lightsValid[i]) { continue; }
uint32_t newColor = strip.getPixelColor(i);
if (forceUpdate || (newColor != colorsSent[i]) || (ellapsedTime > forceUpdateMinutes*60000)){
wizSendColor(lightsIP[i], newColor);
colorsSent[i] = newColor;
update = true;
delay(sendDelay);
}
}
if (update) lastTime = millis();
}
}
void addToConfig(JsonObject& root)
{
JsonObject top = root.createNestedObject("wizLightsUsermod");
top["Interval (ms)"] = updateInterval;
top["Send Delay (ms)"] = sendDelay;
top["Use Enhanced White *"] = useEnhancedWhite;
top["* Warm White Value (0-255)"] = warmWhite;
top["* Cold White Value (0-255)"] = coldWhite;
top["Always Force Update"] = forceUpdate;
top["Force Update Every x Minutes"] = forceUpdateMinutes;
for (uint8_t i = 0; i < MAX_WIZ_LIGHTS; i++) {
top[getJsonLabel(i)] = lightsIP[i].toString();
}
}
bool readFromConfig(JsonObject& root)
{
JsonObject top = root["wizLightsUsermod"];
bool configComplete = !top.isNull();
configComplete &= getJsonValue(top["Interval (ms)"], updateInterval, 1000); // How frequently to update the wiz lights
configComplete &= getJsonValue(top["Send Delay (ms)"], sendDelay, 0); // Optional delay after sending each UDP message
configComplete &= getJsonValue(top["Use Enhanced White *"], useEnhancedWhite, false); // When color is white use wiz white LEDs instead of mixing RGB
configComplete &= getJsonValue(top["* Warm White Value (0-255)"], warmWhite, 0); // Warm White LED value for Enhanced White
configComplete &= getJsonValue(top["* Cold White Value (0-255)"], coldWhite, 50); // Cold White LED value for Enhanced White
configComplete &= getJsonValue(top["Always Force Update"], forceUpdate, false); // Update wiz light every loop, even if color value has not changed
configComplete &= getJsonValue(top["Force Update Every x Minutes"], forceUpdateMinutes, 5); // Update wiz light if color value has not changed, every x minutes
// Read list of IPs
String tempIp;
for (uint8_t i = 0; i < MAX_WIZ_LIGHTS; i++) {
configComplete &= getJsonValue(top[getJsonLabel(i)], tempIp, "0.0.0.0");
lightsValid[i] = lightsIP[i].fromString(tempIp);
// If the IP is not valid, force the value to be empty
if (!lightsValid[i]){lightsIP[i].fromString("0.0.0.0");}
}
return configComplete;
}
// Create label for the usermod page (I cannot make it work with JSON arrays...)
String getJsonLabel(uint8_t i) {return "WiZ Light IP #" + String(i+1);}
uint16_t getId(){return USERMOD_ID_WIZLIGHTS;}
};