mirror of https://github.com/arendst/Tasmota.git
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:
parent
f517755303
commit
b5d7f75647
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue