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
This commit is contained in:
Erik 2018-09-08 08:49:08 +02:00
parent f517755303
commit b5d7f75647
2 changed files with 41 additions and 18 deletions

View File

@ -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 (0<H<360), Saturation (0<S<100) OR Brightness (0<B<100)
float hsb[3];
LightGetHsb(&hsb[0],&hsb[1],&hsb[2]);
LightGetHsb(&hsb[0],&hsb[1],&hsb[2], false);
HSB[0] = round(hsb[0] * 360);
HSB[1] = round(hsb[1] * 100);
HSB[2] = round(hsb[2] * 100);
@ -1130,7 +1135,8 @@ boolean LightCommand()
LightSetHsb(( (HSB[0]>360) ? (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);

View File

@ -17,6 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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;
}