Add usermode to control Wiz lights (#2595)
* Add usermode to control Wiz lights (#1) * Fix inclusion in usermods list Co-authored-by: Christian Schwinne <dev.aircoookie@gmail.com>
This commit is contained in:
parent
a517f0df1d
commit
22c3ac5be3
13
usermods/wizlights/readme.md
Normal file
13
usermods/wizlights/readme.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Controlling Wiz lights
|
||||
|
||||
This usermod allows the control of [WiZ](https://www.wizconnected.com/en/consumer/) lights that are in the same network as the WLED controller.
|
||||
|
||||
The mod takes the colors from the first few pixels and sends them to the lights.
|
||||
|
||||
## Configuration
|
||||
|
||||
First, enter how often the data will be sent to the lights (in ms).
|
||||
|
||||
Then enter the IPs for the lights to be controlled, in order. There is currently a limit of 10 devices that can be controled, but that number
|
||||
can be easily changed by updating _MAX_WIZ_LIGHTS_.
|
||||
|
142
usermods/wizlights/wizlights.h
Normal file
142
usermods/wizlights/wizlights.h
Normal file
@ -0,0 +1,142 @@
|
||||
#pragma once
|
||||
|
||||
#include "wled.h"
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
// Maximum number of lights supported
|
||||
#define MAX_WIZ_LIGHTS 10
|
||||
|
||||
// UDP object, to send messages
|
||||
WiFiUDP UDP;
|
||||
|
||||
// Function to send a color to a light
|
||||
void sendColor(IPAddress ip, uint32_t color) {
|
||||
UDP.beginPacket(ip, 38899);
|
||||
if (color == 0) {
|
||||
UDP.print("{\"method\":\"setPilot\",\"params\":{\"state\":false}}");
|
||||
} else {
|
||||
UDP.print("{\"method\":\"setPilot\",\"params\":{\"state\":true, \"r\":");
|
||||
UDP.print(R(color));
|
||||
UDP.print(",\"g\":");
|
||||
UDP.print(G(color));
|
||||
UDP.print(",\"b\":");
|
||||
UDP.print(B(color));
|
||||
UDP.print("}}");
|
||||
}
|
||||
UDP.endPacket();
|
||||
}
|
||||
|
||||
// Create label for the usermode page (I cannot make it work with JSON arrays...)
|
||||
String getJsonLabel(uint8_t i) {
|
||||
return "ip_light_" + String(i);
|
||||
}
|
||||
|
||||
class WizLightsUsermod : public Usermod {
|
||||
private:
|
||||
// Keep track of the last time the lights were updated
|
||||
unsigned long lastTime = 0;
|
||||
|
||||
// Specify how often WLED sends data to the Wiz lights
|
||||
long updateInterval;
|
||||
|
||||
// Save the IP of the lights
|
||||
IPAddress lightsIP[MAX_WIZ_LIGHTS];
|
||||
bool lightsValid[MAX_WIZ_LIGHTS];
|
||||
|
||||
// Variable that keeps track of RBG values for the lights
|
||||
uint32_t colorsSent[MAX_WIZ_LIGHTS];
|
||||
|
||||
public:
|
||||
//Functions called by WLED
|
||||
|
||||
/*
|
||||
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||
*/
|
||||
void loop() {
|
||||
// Calculate how long since the last update
|
||||
unsigned long ellapsedTime = millis() - lastTime;
|
||||
|
||||
if (ellapsedTime > updateInterval) {
|
||||
// Keep track of whether we are updating any of the lights
|
||||
bool update = false;
|
||||
|
||||
// Loop through the lights
|
||||
for (uint8_t i = 0; i < MAX_WIZ_LIGHTS; i++) {
|
||||
// Check if we have a valid IP
|
||||
if (!lightsValid[i]) { continue; }
|
||||
|
||||
// Get the first colors in the strip
|
||||
uint32_t new_color = strip.getPixelColor(i);
|
||||
|
||||
// Check if the color has changed from the last one sent
|
||||
// Force an update every 5 minutes, in case the colors don't change
|
||||
// (the lights could have been reset by turning off and on)
|
||||
if ((new_color != colorsSent[i]) | (ellapsedTime > 5*60000)) {
|
||||
// It has changed, send the new color to the light
|
||||
update = true;
|
||||
sendColor(lightsIP[i], new_color);
|
||||
colorsSent[i] = new_color;
|
||||
}
|
||||
}
|
||||
|
||||
// We sent an update, wait until we do this again
|
||||
if (update) {
|
||||
lastTime = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||
* If you want to force saving the current state, use serializeConfig() in your loop().
|
||||
*/
|
||||
void addToConfig(JsonObject& root)
|
||||
{
|
||||
JsonObject top = root.createNestedObject("wizLightsUsermod");
|
||||
top["interval_ms"] = updateInterval;
|
||||
for (uint8_t i = 0; i < MAX_WIZ_LIGHTS; i++) {
|
||||
top[getJsonLabel(i)] = lightsIP[i].toString();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||
* This is called by WLED when settings are loaded (currently this only happens immediately after boot, or after saving on the Usermod Settings page)
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root)
|
||||
{
|
||||
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
|
||||
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
|
||||
|
||||
JsonObject top = root["wizLightsUsermod"];
|
||||
|
||||
bool configComplete = !top.isNull();
|
||||
|
||||
// Read interval to update the lights
|
||||
configComplete &= getJsonValue(top["interval_ms"], updateInterval, 1000);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId()
|
||||
{
|
||||
return USERMOD_ID_WIZLIGHTS;
|
||||
}
|
||||
};
|
@ -72,6 +72,7 @@
|
||||
#define USERMOD_ID_QUINLED_AN_PENTA 23 //Usermod "quinled-an-penta.h"
|
||||
#define USERMOD_ID_SSDR 24 //Usermod "usermod_v2_seven_segment_display_reloaded.h"
|
||||
#define USERMOD_ID_CRONIXIE 25 //Usermod "usermod_cronixie.h"
|
||||
#define USERMOD_ID_WIZLIGHTS 26 //Usermod "wizlights.h"
|
||||
|
||||
//Access point behavior
|
||||
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
||||
|
@ -112,6 +112,10 @@
|
||||
#include "../usermods/quinled-an-penta/quinled-an-penta.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_WIZLIGHTS
|
||||
#include "../usermods/wizlights/wizlights.h"
|
||||
#endif
|
||||
|
||||
void registerUsermods()
|
||||
{
|
||||
/*
|
||||
@ -211,4 +215,8 @@ void registerUsermods()
|
||||
#ifdef QUINLED_AN_PENTA
|
||||
usermods.add(new QuinLEDAnPentaUsermod());
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_WIZLIGHTS
|
||||
usermods.add(new WizLightsUsermod());
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user