From b5d7f75647ab656bca132ae8986ad520c30eaf8e Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 8 Sep 2018 08:49:08 +0200 Subject: [PATCH] Fix setting and getting color temperature for Philips Hue emulation - Improve setting and getting color temperature for Philips Hue emulation - Clamp Philips Hue API values - Turn off white LEDs when setting hue+saturation --- sonoff/xdrv_04_light.ino | 26 ++++++++++++++++---------- sonoff/xplg_wemohue.ino | 33 +++++++++++++++++++++++++-------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 209fe467a..93c2c522c 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -557,8 +557,8 @@ void LightState(uint8_t append) if (light_subtype > LST_SINGLE) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_COLOR "\":\"%s\""), mqtt_data, LightGetColor(0, scolor)); // Add status for HSB - LightGetHsb(&hsb[0],&hsb[1],&hsb[2]); - // Scale these percentages up to the numbers expected byt he client + LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false); + // Scale these percentages up to the numbers expected by the client h = round(hsb[0] * 360); s = round(hsb[1] * 100); b = round(hsb[2] * 100); @@ -911,13 +911,15 @@ void LightHsbToRgb() light_current_color[0] = (uint8_t)(r * 255.0f); light_current_color[1] = (uint8_t)(g * 255.0f); light_current_color[2] = (uint8_t)(b * 255.0f); + light_current_color[3] = 0; + light_current_color[4] = 0; } /********************************************************************************************/ -void LightGetHsb(float *hue, float *sat, float *bri) +void LightGetHsb(float *hue, float *sat, float *bri, bool gotct) { - if (light_subtype > LST_COLDWARM) { + if (light_subtype > LST_COLDWARM && !gotct) { LightRgbToHsb(); *hue = light_hue; *sat = light_saturation; @@ -925,16 +927,19 @@ void LightGetHsb(float *hue, float *sat, float *bri) } else { *hue = 0; *sat = 0; -// *bri = (2.54f * (float)Settings.light_dimmer); *bri = (0.01f * (float)Settings.light_dimmer); } } -void LightSetHsb(float hue, float sat, float bri, uint16_t ct) +void LightSetHsb(float hue, float sat, float bri, uint16_t ct, bool gotct) { if (light_subtype > LST_COLDWARM) { - if ((LST_RGBWC == light_subtype) && (ct > 0)) { - LightSetColorTemp(ct); + if ((LST_RGBWC == light_subtype) && (gotct)) { + uint8_t tmp = (uint8_t)(bri * 100); + Settings.light_dimmer = tmp; + if (ct > 0) { + LightSetColorTemp(ct); + } } else { light_hue = hue; light_saturation = sat; @@ -1114,7 +1119,7 @@ boolean LightCommand() } else { // Command with only 1 parameter, Hue (0360) ? (HSB[0] % 360) : HSB[0] ) /360.0, ( (HSB[1]>100) ? (HSB[1] % 100) : HSB[1] ) /100.0, ( (HSB[2]>100) ? (HSB[2] % 100) : HSB[2] ) /100.0, - 0); + 0, + false); } } else { LightState(0); diff --git a/sonoff/xplg_wemohue.ino b/sonoff/xplg_wemohue.ino index 93912bc76..f0b20ef59 100644 --- a/sonoff/xplg_wemohue.ino +++ b/sonoff/xplg_wemohue.ino @@ -17,6 +17,9 @@ along with this program. If not, see . */ +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) + #if defined(USE_WEBSERVER) && defined(USE_EMULATION) /*********************************************************************************************\ * Belkin WeMo and Philips Hue bridge emulation @@ -462,10 +465,10 @@ const char HUE_LIGHTS_STATUS_JSON[] PROGMEM = "\"hue\":{h}," "\"sat\":{s}," "\"xy\":[0.5, 0.5]," - "\"ct\":500," + "\"ct\":{t}," "\"alert\":\"none\"," "\"effect\":\"none\"," - "\"colormode\":\"hs\"," + "\"colormode\":\"{m}\"," "\"reachable\":true}"; const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = ",\"type\":\"Extended color light\"," @@ -559,20 +562,26 @@ void HueConfig(String *path) WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response); } +bool g_gotct = false; + void HueLightStatus1(byte device, String *response) { float hue = 0; float sat = 0; float bri = 0; + uint16_t ct = 500; if (light_type) { - LightGetHsb(&hue, &sat, &bri); + LightGetHsb(&hue, &sat, &bri, g_gotct); + ct = LightGetColorTemp(); } *response += FPSTR(HUE_LIGHTS_STATUS_JSON); response->replace("{state}", (power & (1 << (device-1))) ? "true" : "false"); response->replace("{h}", String((uint16_t)(65535.0f * hue))); response->replace("{s}", String((uint8_t)(254.0f * sat))); response->replace("{b}", String((uint8_t)(254.0f * bri))); + response->replace("{t}", String(ct)); + response->replace("{m}", g_gotct?"ct":"hs"); } void HueLightStatus2(byte device, String *response) @@ -678,11 +687,13 @@ void HueLights(String *path) } if (light_type) { - LightGetHsb(&hue, &sat, &bri); + LightGetHsb(&hue, &sat, &bri, g_gotct); } - if (hue_json.containsKey("bri")) { + if (hue_json.containsKey("bri")) { // Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off. tmp = hue_json["bri"]; + tmp = max(tmp, 1); + tmp = min(tmp, 254); bri = (float)tmp / 254.0f; if (resp) { response += ","; @@ -694,7 +705,7 @@ void HueLights(String *path) resp = true; change = true; } - if (hue_json.containsKey("hue")) { + if (hue_json.containsKey("hue")) { // The hue value is a wrapping value between 0 and 65535. Both 0 and 65535 are red, 25500 is green and 46920 is blue. tmp = hue_json["hue"]; hue = (float)tmp / 65535.0f; if (resp) { @@ -704,11 +715,14 @@ void HueLights(String *path) response.replace("{id", String(device)); response.replace("{cm", "hue"); response.replace("{re", String(tmp)); + g_gotct = false; resp = true; change = true; } - if (hue_json.containsKey("sat")) { + if (hue_json.containsKey("sat")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white). tmp = hue_json["sat"]; + tmp = max(tmp, 0); + tmp = min(tmp, 254); sat = (float)tmp / 254.0f; if (resp) { response += ","; @@ -717,6 +731,8 @@ void HueLights(String *path) response.replace("{id", String(device)); response.replace("{cm", "sat"); response.replace("{re", String(tmp)); + g_gotct = false; + resp = true; change = true; } if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm) @@ -728,11 +744,12 @@ void HueLights(String *path) response.replace("{id", String(device)); response.replace("{cm", "ct"); response.replace("{re", String(ct)); + g_gotct = true; change = true; } if (change) { if (light_type) { - LightSetHsb(hue, sat, bri, ct); + LightSetHsb(hue, sat, bri, ct, g_gotct); } change = false; }