-Coming soon! Not yet implemented!
-
+Poll Hue light every ms:
Then, receive On/Off, Brightness, and Color
-After device color update, ignore Hue updates for minutes
-Hue status: Internal ESP error! -->
+
+Hue status: Internal ESP Error!
@@ -333,7 +331,7 @@ HTTP traffic is not encrypted. An attacker in the same network could intercept f
Enable ArduinoOTA:
About
-WLED version 0.5.0
+WLED version 0.5.1
(c) 2016-2018 Christian Schwinne Licensed under the MIT license
Uses libraries:
diff --git a/wled00/wled00.ino b/wled00/wled00.ino
index 148122787..1350114a4 100644
--- a/wled00/wled00.ino
+++ b/wled00/wled00.ino
@@ -3,7 +3,7 @@
*/
/*
* @title WLED project sketch
- * @version 0.5.0
+ * @version 0.5.1
* @author Christian Schwinne
*/
@@ -12,10 +12,12 @@
#include
#include
#include "src/dependencies/webserver/WebServer.h"
+#include
#else
#include
#include
#include
+#include
#endif
#include
#include
@@ -30,8 +32,8 @@
#include "WS2812FX.h"
//version in format yymmddb (b = daily build)
-#define VERSION 1802251
-const String versionString = "0.5.0";
+#define VERSION 1802273
+const String versionString = "0.5.1";
//AP and OTA default passwords (change them!)
String appass = "wled1234";
@@ -152,6 +154,22 @@ unsigned long countdownTime = 1514764800L;
double transitionResolution = 0.011;
+//hue
+long hueLastRequestSent = 0;
+bool huePollingEnabled = false, hueAttempt = false;
+uint16_t huePollIntervalMs = 2500;
+uint32_t huePollIntervalMsTemp = 2500;
+String hueApiKey = "api";
+uint8_t huePollLightId = 1;
+IPAddress hueIP = (0,0,0,0);
+bool notifyHue = true;
+bool hueApplyOnOff = true, hueApplyBri = true, hueApplyColor = true;
+String hueError = "Inactive";
+uint16_t hueFailCount = 0;
+float hueXLast=0, hueYLast=0;
+uint16_t hueHueLast=0, hueCtLast=0;
+uint8_t hueSatLast=0, hueBriLast=0;
+
//Internal vars
byte col[]{0, 0, 0};
byte col_old[]{0, 0, 0};
@@ -241,20 +259,13 @@ WebServer server(80);
#else
ESP8266WebServer server(80);
#endif
+HTTPClient hueClient;
ESP8266HTTPUpdateServer httpUpdater;
WiFiUDP notifierUdp;
WiFiUDP ntpUdp;
WS2812FX strip = WS2812FX(LEDCOUNT);
-//eeprom Version code, enables default settings instead of 0 init on update
-#define EEPVER 4
-//0 -> old version, default
-//1 -> 0.4p 1711272 and up
-//2 -> 0.4p 1711302 and up
-//3 -> 0.4 1712121 and up
-//4 -> 0.5.0 and up
-
#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x)
@@ -333,6 +344,7 @@ void loop() {
handleAlexa();
if (!arlsTimeout) //block stuff if WARLS is enabled
{
+ handleHue();
handleNightlight();
#ifdef USEOVERLAYS
handleOverlays();
diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino
index b3e9d3e98..e75c3b2df 100644
--- a/wled00/wled01_eeprom.ino
+++ b/wled00/wled01_eeprom.ino
@@ -1,8 +1,18 @@
/*
* Methods to handle saving and loading to non-volatile memory
+ * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map
*/
-#define EEPSIZE 2048
+#define EEPSIZE 3072
+
+//eeprom Version code, enables default settings instead of 0 init on update
+#define EEPVER 5
+//0 -> old version, default
+//1 -> 0.4p 1711272 and up
+//2 -> 0.4p 1711302 and up
+//3 -> 0.4 1712121 and up
+//4 -> 0.5.0 and up
+//5 -> 0.5.1 and up
void clearEEPROM()
{
@@ -143,6 +153,24 @@ void saveSettingsToEEPROM()
{
EEPROM.write(i, cssFont.charAt(i-950));
}
+
+ EEPROM.write(2048, huePollingEnabled);
+ //EEPROM.write(2049, hueUpdatingEnabled);
+ for (int i = 2050; i < 2054; ++i)
+ {
+ EEPROM.write(i, hueIP[i-2050]);
+ }
+ for (int i = 2054; i < 2100; ++i)
+ {
+ EEPROM.write(i, hueApiKey.charAt(i-2054));
+ }
+ EEPROM.write(2100, (huePollIntervalMs >> 0) & 0xFF);
+ EEPROM.write(2101, (huePollIntervalMs >> 8) & 0xFF);
+ EEPROM.write(2102, notifyHue);
+ EEPROM.write(2103, hueApplyOnOff);
+ EEPROM.write(2104, hueApplyBri);
+ EEPROM.write(2105, hueApplyColor);
+ EEPROM.write(2106, huePollLightId);
EEPROM.commit();
}
@@ -297,6 +325,26 @@ void loadSettingsFromEEPROM(bool first)
receiveNotificationEffects = receiveNotificationBrightness;
}
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
+ if (lastEEPROMversion > 4) {
+ huePollingEnabled = EEPROM.read(2048);
+ //hueUpdatingEnabled = EEPROM.read(2049);
+ for (int i = 2050; i < 2054; ++i)
+ {
+ hueIP[i-2050] = EEPROM.read(i);
+ }
+ hueApiKey = "";
+ for (int i = 2054; i < 2100; ++i)
+ {
+ if (EEPROM.read(i) == 0) break;
+ hueApiKey += char(EEPROM.read(i));
+ }
+ huePollIntervalMs = ((EEPROM.read(2100) << 0) & 0xFF) + ((EEPROM.read(2101) << 8) & 0xFF00);
+ notifyHue = EEPROM.read(2102);
+ hueApplyOnOff = EEPROM.read(2103);
+ hueApplyBri = EEPROM.read(2104);
+ hueApplyColor = EEPROM.read(2105);
+ huePollLightId = EEPROM.read(2106);
+ }
bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393);
@@ -315,6 +363,9 @@ void loadSettingsFromEEPROM(bool first)
//custom macro memory (16 slots/ each 64byte)
//1024-2047 reserved
+
+ //user MOD memory
+ //2944 - 3071 reserved
useHSB = useHSBDefault;
diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino
index 5cbff75dc..e7d5d0042 100644
--- a/wled00/wled02_xml.ino
+++ b/wled00/wled02_xml.ino
@@ -187,9 +187,21 @@ String getSettings(uint8_t subPage)
resp += ds + "NRCFX" + c + receiveNotificationEffects +";";
resp += ds + "NSDIR" + c + notifyDirectDefault +";";
resp += ds + "NSBTN" + c + notifyButton +";";
+ resp += ds + "NSHUE" + c + notifyHue +";";
resp += ds + "ALEXA" + c + alexaEnabled +";";
resp += ds + "AINVN" + v + "\"" + alexaInvocationName + "\";";
resp += ds + "NSALX" + c + alexaNotify +";";
+ resp += ds + "HUIP0" + v + hueIP[0] +";";
+ resp += ds + "HUIP1" + v + hueIP[1] +";";
+ resp += ds + "HUIP2" + v + hueIP[2] +";";
+ resp += ds + "HUIP3" + v + hueIP[3] +";";
+ resp += ds + "HUELI" + v + huePollLightId +";";
+ resp += ds + "HUEPI" + v + huePollIntervalMs +";";
+ resp += ds + "HUEPL" + c + huePollingEnabled +";";
+ resp += ds + "HURIO" + c + hueApplyOnOff +";";
+ resp += ds + "HURBR" + c + hueApplyBri +";";
+ resp += ds + "HURCL" + c + hueApplyColor +";";
+ resp += dg + "(\"hms\")[0]" + ih + "\"" + hueError + "\";";
}
if (subPage == 5)
diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino
index 76ee6999f..56ca9d749 100644
--- a/wled00/wled03_set.ino
+++ b/wled00/wled03_set.ino
@@ -281,6 +281,37 @@ void handleSettingsSet(uint8_t subPage)
alexaEnabled = server.hasArg("ALEXA");
if (server.hasArg("AINVN")) alexaInvocationName = server.arg("AINVN");
alexaNotify = server.hasArg("NSALX");
+ notifyHue = server.hasArg("NSHUE");
+ for (int i=0;i<4;i++){
+ String a = "HUIP"+String(i);
+ if (server.hasArg(a))
+ {
+ int j = server.arg(a).toInt();
+ if (j >= 0 && j <= 255) hueIP[i] = j;
+ }
+ }
+ if (server.hasArg("HUELI"))
+ {
+ int i = server.arg("HUELI").toInt();
+ if (i > 0) huePollLightId = i;
+ }
+ if (server.hasArg("HUEPI"))
+ {
+ int i = server.arg("HUEPI").toInt();
+ if (i > 50) huePollIntervalMs = i;
+ }
+ hueApplyOnOff = server.hasArg("HURIO");
+ hueApplyBri = server.hasArg("HURBR");
+ hueApplyColor = server.hasArg("HURCL");
+ if (server.hasArg("HUEPL"))
+ {
+ if (!huePollingEnabled) hueAttempt = true;
+ if (!setupHue()) hueAttempt = true;
+ } else
+ {
+ huePollingEnabled = false;
+ hueError = "Inactive";
+ }
}
//TIME
@@ -358,6 +389,19 @@ boolean handleSet(String req)
if (pos > 0) {
bri = req.substring(pos + 3).toInt();
}
+
+ //set hue
+ pos = req.indexOf("HU=");
+ if (pos > 0) {
+ uint16_t temphue = req.substring(pos + 3).toInt();
+ uint8_t tempsat = 255;
+ pos = req.indexOf("SA=");
+ if (pos > 0) {
+ tempsat = req.substring(pos + 3).toInt();
+ }
+ colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? col_sec:col);
+ }
+
//set red value
pos = req.indexOf("&R=");
if (pos > 0) {
@@ -480,6 +524,19 @@ boolean handleSet(String req)
effectUpdated = true;
}
}
+
+ //set hue polling light: 0 -off
+ pos = req.indexOf("HP=");
+ if (pos > 0) {
+ int id = req.substring(pos + 3).toInt();
+ if (id > 0)
+ {
+ if (id < 100) huePollLightId = id;
+ setupHue();
+ } else {
+ huePollingEnabled = false;
+ }
+ }
//set default control mode (0 - RGB, 1 - HSB)
pos = req.indexOf("MD=");
diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino
index b58513432..3776ee71a 100644
--- a/wled00/wled05_init.ino
+++ b/wled00/wled05_init.ino
@@ -55,6 +55,13 @@ void wledInit()
DEBUG_PRINTLN("");
DEBUG_PRINT("Connected! IP address: ");
DEBUG_PRINTLN(WiFi.localIP());
+
+ if (hueIP[0] == 0)
+ {
+ hueIP[0] = WiFi.localIP()[0];
+ hueIP[1] = WiFi.localIP()[1];
+ hueIP[2] = WiFi.localIP()[2];
+ }
// Set up mDNS responder:
if (cmdns != NULL && !onlyAP && !MDNS.begin(cmdns.c_str())) {
@@ -147,7 +154,13 @@ void wledInit()
server.on("/settings/sync", HTTP_POST, [](){
handleSettingsSet(4);
- serveMessage(200,"Sync settings saved.","Redirecting...",1);
+ if (hueAttempt)
+ {
+ serveMessage(200,"Hue setup result",hueError,253);
+ } else {
+ serveMessage(200,"Sync settings saved.","Redirecting...",1);
+ }
+ hueAttempt = false;
});
server.on("/settings/time", HTTP_POST, [](){
diff --git a/wled00/wled06_usermod.ino b/wled00/wled06_usermod.ino
index 54fe5d539..f60d2e4ff 100644
--- a/wled00/wled06_usermod.ino
+++ b/wled00/wled06_usermod.ino
@@ -1,6 +1,7 @@
/*
* This file allows you to add own functionality to WLED more easily
- *
+ * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
+ * EEPROM bytes 2944 to 3071 are reserved for your custom use case.
*/
void userBeginPreConnection()
diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino
index 5d2256d3c..f82a618b2 100644
--- a/wled00/wled07_notify.ino
+++ b/wled00/wled07_notify.ino
@@ -13,6 +13,7 @@ void notify(uint8_t callMode)
case 2: if (!notifyButton) return; break;
case 4: if (!notifyDirect) return; break;
case 6: if (!notifyDirect) return; break; //fx change
+ case 7: if (!notifyHue) return; break;
default: return;
}
byte udpOut[WLEDPACKETSIZE];
diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino
index d5ff1ca95..0dd5fdcee 100644
--- a/wled00/wled08_led.ino
+++ b/wled00/wled08_led.ino
@@ -51,7 +51,7 @@ bool colorChanged()
void colorUpdated(int callMode)
{
- //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (no not.) (NN)6: fx changed
+ //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (NN)6: fx changed 7: hue
if (!colorChanged())
{
if (callMode == 6) notify(6);
diff --git a/wled00/wled14_colors.ino b/wled00/wled14_colors.ino
index 52a6e98fd..eb2d60d92 100644
--- a/wled00/wled14_colors.ino
+++ b/wled00/wled14_colors.ino
@@ -3,25 +3,118 @@
*/
void colorCTtoRGB(uint16_t mired, uint8_t* rgb) //white spectrum to rgb
{
-
+ //this is only an approximation using WS2812B with gamma correction enabled
+ if (mired > 475)
+ {
+ rgb[0]=255;rgb[1]=199;rgb[2]=92;//500
+ } else if (mired > 425)
+ {
+ rgb[0]=255;rgb[1]=213;rgb[2]=118;//450
+ } else if (mired > 375)
+ {
+ rgb[0]=255;rgb[1]=216;rgb[2]=118;//400
+ } else if (mired > 325)
+ {
+ rgb[0]=255;rgb[1]=234;rgb[2]=140;//350
+ } else if (mired > 275)
+ {
+ rgb[0]=255;rgb[1]=243;rgb[2]=160;//300
+ } else if (mired > 225)
+ {
+ rgb[0]=250;rgb[1]=255;rgb[2]=188;//250
+ } else if (mired > 175)
+ {
+ rgb[0]=247;rgb[1]=255;rgb[2]=215;//200
+ } else
+ {
+ rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
+ }
}
-void colorHSBtoRGB(uint16_t hue, uint8_t sat, uint8_t bri, uint8_t* rgb) //hue, sat, bri to rgb
+void colorHStoRGB(uint16_t hue, uint8_t sat, uint8_t* rgb) //hue, sat to rgb
{
-
+ float h = ((float)hue)/65535.0;
+ float s = ((float)sat)/255.0;
+ uint8_t i = floor(h*6);
+ float f = h * 6-i;
+ float p = 255 * (1-s);
+ float q = 255 * (1-f*s);
+ float t = 255 * (1-(1-f)*s);
+ switch (i%6) {
+ case 0: rgb[0]=255,rgb[1]=t,rgb[2]=p;break;
+ case 1: rgb[0]=q,rgb[1]=255,rgb[2]=p;break;
+ case 2: rgb[0]=p,rgb[1]=255,rgb[2]=t;break;
+ case 3: rgb[0]=p,rgb[1]=q,rgb[2]=255;break;
+ case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
+ case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
+ }
}
void colorXYtoRGB(float x, float y, uint8_t* rgb) //coordinates to rgb (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
{
float z = 1.0f - x - y;
- //float Y = 1.0f; // Brightness, we handle this separately
float X = (1.0f / y) * x;
float Z = (1.0f / y) * z;
- rgb[0] = (int)(X * 1.656492f - 0.354851f - Z * 0.255038f);
- rgb[1] = (int)(-X * 0.707196f + 1.655397f + Z * 0.036152f);
- rgb[2] = (int)(X * 0.051713f - 0.121364f + Z * 1.011530f);
+ float r = (int)255*(X * 1.656492f - 0.354851f - Z * 0.255038f);
+ float g = (int)255*(-X * 0.707196f + 1.655397f + Z * 0.036152f);
+ float b = (int)255*(X * 0.051713f - 0.121364f + Z * 1.011530f);
+ if (r > b && r > g && r > 1.0f) {
+ // red is too big
+ g = g / r;
+ b = b / r;
+ r = 1.0f;
+ } else if (g > b && g > r && g > 1.0f) {
+ // green is too big
+ r = r / g;
+ b = b / g;
+ g = 1.0f;
+ } else if (b > r && b > g && b > 1.0f) {
+ // blue is too big
+ r = r / b;
+ g = g / b;
+ b = 1.0f;
+ }
+ // Apply gamma correction
+ r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * pow(r, (1.0f / 2.4f)) - 0.055f;
+ g = g <= 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * pow(g, (1.0f / 2.4f)) - 0.055f;
+ b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * pow(b, (1.0f / 2.4f)) - 0.055f;
+
+ if (r > b && r > g) {
+ // red is biggest
+ if (r > 1.0f) {
+ g = g / r;
+ b = b / r;
+ r = 1.0f;
+ }
+ }
+ else if (g > b && g > r) {
+ // green is biggest
+ if (g > 1.0f) {
+ r = r / g;
+ b = b / g;
+ g = 1.0f;
+ }
+ }
+ else if (b > r && b > g) {
+ // blue is biggest
+ if (b > 1.0f) {
+ r = r / b;
+ g = g / b;
+ b = 1.0f;
+ }
+ }
+ rgb[0] = 255.0*r;
+ rgb[1] = 255.0*g;
+ rgb[2] = 255.0*b;
}
-void colorRGBtoXY(uint8_t* rgb, float* xy){} //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
+void colorRGBtoXY(uint8_t* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
+{
+ float X = rgb[0] * 0.664511f + rgb[1] * 0.154324f + rgb[2] * 0.162028f;
+ float Y = rgb[0] * 0.283881f + rgb[1] * 0.668433f + rgb[2] * 0.047685f;
+ float Z = rgb[0] * 0.000088f + rgb[1] * 0.072310f + rgb[2] * 0.986039f;
+ xy[0] = X / (X + Y + Z);
+ xy[1] = Y / (X + Y + Z);
+}
void colorRGBtoRGBW(uint8_t* rgb, uint8_t* rgbw){} //rgb to rgbw, not imlemented yet
diff --git a/wled00/wled15_hue.ino b/wled00/wled15_hue.ino
index 388ce0c8d..1c10faa77 100644
--- a/wled00/wled15_hue.ino
+++ b/wled00/wled15_hue.ino
@@ -1,4 +1,207 @@
/*
* Sync to Philips hue lights
*/
-void foo(){}
+
+void handleHue()
+{
+ if (huePollingEnabled && WiFi.status() == WL_CONNECTED)
+ {
+ if (millis() - hueLastRequestSent > huePollIntervalMsTemp)
+ {
+ sendHuePoll(false);
+ }
+ }
+}
+
+bool setupHue()
+{
+ if (WiFi.status() == WL_CONNECTED) //setup needed
+ {
+ if (hueApiKey.length()>20) //api key is probably ok
+ {
+ if (sendHuePoll(false))
+ {
+ huePollingEnabled = true;
+ return true;
+ }
+ if (hueError.charAt(0) == 'R' || hueError.charAt(0) == 'I') return false; //can't connect
+ delay(20);
+ }
+ sendHuePoll(true); //new API key
+ if (hueError.charAt(0) != 'C') return false; //still some error
+ delay(20);
+ if (sendHuePoll(false))
+ {
+ huePollingEnabled = true;
+ return true;
+ }
+ return false;
+ }
+ else return false;
+ return true;
+}
+
+bool sendHuePoll(bool sAuth)
+{
+ bool st;
+ hueClient.setReuse(true);
+ hueClient.setTimeout(250);
+ String hueURL = "http://";
+ hueURL += hueIP.toString();
+ hueURL += "/api/";
+ if (!sAuth) {
+ hueURL += hueApiKey;
+ hueURL += "/lights/" + String(huePollLightId);
+ }
+ hueClient.begin(hueURL);
+ int httpCode = (sAuth)? hueClient.POST("{\"devicetype\":\"wled#esp\"}"):hueClient.GET();
+ //TODO this request may block operation for ages
+
+ if (httpCode>0){
+ st = handleHueResponse(hueClient.getString(),sAuth);
+ } else {
+ hueError = "Request timed out";
+ st = false;
+ }
+ if (!st){ //error
+ if (hueFailCount<7) huePollIntervalMsTemp*=2; // only poll every 5min when unable to connect
+ hueFailCount++;
+ if (hueFailCount > 150) huePollingEnabled = false; //disable after many hours offline
+ }
+ hueLastRequestSent = millis();
+ return st;
+}
+
+bool handleHueResponse(String hueResp, bool isAuth)
+{
+ DEBUG_PRINTLN(hueApiKey);
+ DEBUG_PRINTLN(hueResp);
+ if (hueResp.indexOf("error")>0)//hue bridge returned error
+ {
+ int hueErrorCode = getJsonValue(&hueResp,"type").toInt();
+ switch (hueErrorCode)
+ {
+ case 1: hueError = "Unauthorized"; break;
+ case 3: hueError = "Invalid light ID"; break;
+ case 101: hueError = "Link button not pressed"; break;
+ default: hueError = "Bridge Error " + String(hueErrorCode);
+ }
+ return false;
+ }
+
+ if (isAuth)
+ {
+ String tempApi = getJsonValue(&hueResp,"username");
+ if (tempApi.length()>0)
+ {
+ hueApiKey = tempApi;
+ return true;
+ }
+ hueError = "Invalid response";
+ return false;
+ }
+
+ float hueX=0, hueY=0;
+ uint16_t hueHue=0, hueCt=0;
+ uint8_t hueBri=0, hueSat=0, hueColormode=0;
+
+ if (getJsonValue(&hueResp,"on").charAt(0) == 't')
+ {
+ String tempV = getJsonValue(&hueResp,"bri");
+ if (tempV.length()>0) //Dimmable device
+ {
+ hueBri = (tempV.toInt())+1;
+ tempV = getJsonValue(&hueResp,"colormode");
+ if (hueApplyColor && tempV.length()>0) //Color device
+ {
+ if (tempV.charAt(0) == 'x') //xy mode
+ {
+ tempV = getJsonValue(&hueResp,"xy");
+ if (tempV.length()>0) //valid
+ {
+ hueColormode = 1;
+ hueX = tempV.toFloat();
+ tempV = tempV.substring(tempV.indexOf(',')+1);
+ hueY = tempV.toFloat();
+ }
+ } else if (tempV.charAt(0) == 'h') //hs mode
+ {
+ tempV = getJsonValue(&hueResp,"hue");
+ if (tempV.length()>0) //valid
+ {
+ hueColormode = 2;
+ hueHue = tempV.toInt();
+ tempV = getJsonValue(&hueResp,"sat");
+ if (tempV.length()>0) //valid
+ {
+ hueSat = tempV.toInt();
+ }
+ }
+ } else //ct mode
+ {
+ tempV = getJsonValue(&hueResp,"\"ct"); //dirty hack to not get effect value instead
+ if (tempV.length()>0) //valid
+ {
+ hueColormode = 3;
+ hueCt = tempV.toInt();
+ }
+ }
+ }
+ } else //On/Off device
+ {
+ hueBri = bri_last;
+ }
+ } else
+ {
+ hueBri = 0;
+ }
+ hueFailCount = 0;
+ huePollIntervalMsTemp = huePollIntervalMs;
+ hueError = "Connected";
+ //applying vals
+ if (hueBri != hueBriLast)
+ {
+ bri = hueBri;
+ if (hueApplyOnOff)
+ {
+ if (hueBri==0) {bri = 0;}
+ else if (bri==0 && hueBri>0) bri = bri_last;
+ }
+ if (hueApplyBri)
+ {
+ if (hueBri>0) bri = hueBri;
+ }
+ hueBriLast = hueBri;
+ }
+ if (hueApplyColor)
+ {
+ switch(hueColormode)
+ {
+ case 1: if (hueX != hueXLast || hueY != hueYLast) colorXYtoRGB(hueX,hueY,col); hueXLast = hueX; hueYLast = hueY; break;
+ case 2: if (hueHue != hueHueLast || hueSat != hueSatLast) colorHStoRGB(hueHue,hueSat,col); hueHueLast = hueHue; hueSatLast = hueSat; break;
+ case 3: if (hueCt != hueCtLast) colorCTtoRGB(hueCt,col); hueCtLast = hueCt; break;
+ }
+ }
+ colorUpdated(7);
+ return true;
+}
+
+String getJsonValue(String* req, String key)
+{
+ //TODO may replace with ArduinoJSON if too complex
+ //this is horribly inefficient and designed to work only in this case
+ uint16_t pos = req->indexOf(key);
+ String b = req->substring(pos + key.length()+2);
+ if (b.charAt(0)=='\"') //is string
+ {
+ return b.substring(1,b.substring(1).indexOf('\"')+1);
+ } else if (b.charAt(0)=='[') //is array
+ {
+ return b.substring(1,b.indexOf(']'));
+ } else //is primitive type
+ {
+ return b.substring(0,b.indexOf(',')); //this works only if value not last
+ }
+ return "";
+}
+