diff --git a/code/espurna/homeassistant.ino b/code/espurna/homeassistant.ino index 079e58d9..18415c39 100644 --- a/code/espurna/homeassistant.ino +++ b/code/espurna/homeassistant.ino @@ -104,6 +104,8 @@ void _haSendSwitch(unsigned char i, JsonObject& config) { if (lightHasColor()) { config["rgb_state_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, false); config["rgb_command_topic"] = mqttTopic(MQTT_TOPIC_COLOR_RGB, true); + } + if (lightUseCCT()) { config["color_temp_command_topic"] = mqttTopic(MQTT_TOPIC_MIRED, true); } diff --git a/code/espurna/light.ino b/code/espurna/light.ino index 51ab46b9..9440ca16 100644 --- a/code/espurna/light.ino +++ b/code/espurna/light.ino @@ -88,6 +88,11 @@ void _setRGBInputValue(unsigned char red, unsigned char green, unsigned char blu _light_channel[2].inputValue = constrain(blue, 0, LIGHT_MAX_VALUE);; } +void _setCCTInputValue(unsigned char warm, unsigned char cold) { + _light_channel[0].inputValue = constrain(warm, 0, LIGHT_MAX_VALUE); + _light_channel[1].inputValue = constrain(cold, 0, LIGHT_MAX_VALUE); +} + void _generateBrightness() { double brightness = (double) _light_brightness / LIGHT_MAX_BRIGHTNESS; @@ -278,7 +283,21 @@ void _fromHSV(const char * hsv) { // https://github.com/stelgenhof/AiLight void _fromKelvin(unsigned long kelvin) { - if (!_light_has_color) return; + if (!_light_has_color) { + + if(!_light_use_cct) return; + + _light_mireds = constrain(round(1000000UL / kelvin), LIGHT_MIN_MIREDS, LIGHT_MAX_MIREDS); + + // This change the range from 153-500 to 0-347 so we get a value between 0 and 1 in the end. + double factor = ((double) _light_mireds - (double) LIGHT_COLDWHITE_MIRED)/((double) LIGHT_WARMWHITE_MIRED - (double) LIGHT_COLDWHITE_MIRED); + unsigned char warm = round(factor * LIGHT_MAX_VALUE); + unsigned char cold = round(((double) 1.0 - factor) * LIGHT_MAX_VALUE); + + _setCCTInputValue(warm, cold); + + return; + } _light_mireds = constrain(round(1000000UL / kelvin), LIGHT_MIN_MIREDS, LIGHT_MAX_MIREDS); @@ -542,12 +561,15 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl mqttSubscribe(MQTT_TOPIC_BRIGHTNESS); if (_light_has_color) { - mqttSubscribe(MQTT_TOPIC_MIRED); - mqttSubscribe(MQTT_TOPIC_KELVIN); mqttSubscribe(MQTT_TOPIC_COLOR_RGB); mqttSubscribe(MQTT_TOPIC_COLOR_HSV); mqttSubscribe(MQTT_TOPIC_TRANSITION); } + + if (_light_has_color || _light_use_cct) { + mqttSubscribe(MQTT_TOPIC_MIRED); + mqttSubscribe(MQTT_TOPIC_KELVIN); + } // Group color if (mqtt_group_color.length() > 0) mqttSubscribeRaw(mqtt_group_color.c_str()); @@ -700,6 +722,10 @@ bool lightHasColor() { return _light_has_color; } +bool lightUseCCT() { + return _light_use_cct; +} + void _lightComms(unsigned char mask) { // Report color & brightness to MQTT broker @@ -869,16 +895,16 @@ bool _lightWebSocketOnReceive(const char * key, JsonVariant& value) { void _lightWebSocketStatus(JsonObject& root) { if (_light_has_color) { - if (_light_use_cct) { - root["useCCT"] = _light_use_cct; - root["mireds"] = _light_mireds; - } if (getSetting("useRGB", LIGHT_USE_RGB).toInt() == 1) { root["rgb"] = lightColor(true); } else { root["hsv"] = lightColor(false); } } + if (_light_use_cct) { + root["useCCT"] = _light_use_cct; + root["mireds"] = _light_mireds; + } JsonArray& channels = root.createNestedArray("channels"); for (unsigned char id=0; id < _light_channel.size(); id++) { channels.add(lightChannel(id)); @@ -913,13 +939,15 @@ void _lightWebSocketOnAction(uint32_t client_id, const char * action, JsonObject lightUpdate(true, true); } } - if (_light_use_cct) { - if (strcmp(action, "mireds") == 0) { - _fromMireds(data["mireds"]); - lightUpdate(true, true); - } - } } + + if (_light_use_cct) { + if (strcmp(action, "mireds") == 0) { + _fromMireds(data["mireds"]); + lightUpdate(true, true); + } + } + if (strcmp(action, "channel") == 0) { if (data.containsKey("id") && data.containsKey("value")) { @@ -1135,13 +1163,13 @@ void _lightConfigure() { } _light_use_white = getSetting("useWhite", LIGHT_USE_WHITE).toInt() == 1; - if (_light_use_white && (_light_channel.size() < 4)) { + if (_light_use_white && (_light_channel.size() < 4) && (_light_channel.size() != 2)) { _light_use_white = false; setSetting("useWhite", _light_use_white); } _light_use_cct = getSetting("useCCT", LIGHT_USE_CCT).toInt() == 1; - if (_light_use_cct && ((_light_channel.size() < 5) || !_light_use_white)) { + if (_light_use_cct && (((_light_channel.size() < 5) && (_light_channel.size() != 2)) || !_light_use_white)) { _light_use_cct = false; setSetting("useCCT", _light_use_cct); } diff --git a/code/html/index.html b/code/html/index.html index 0f4cb90f..9f8aecad 100644 --- a/code/html/index.html +++ b/code/html/index.html @@ -508,7 +508,7 @@
-
Use forth dimmable channel as (cold) white light calculated out of the RGB values.
Will only work if the device has at least 4 dimmable channels.
Enabling this will render useless the "Channel 4" slider in the status page.
Reload the page to update the web interface.
+
For 2 channels warm white and cold white lights or color lights to use forth dimmable channel as (cold) white light calculated out of the RGB values.
Will only work if the device has at least 4 dimmable channels.
Enabling this will render useless the "Channel 4" slider in the status page.
Reload the page to update the web interface.
@@ -516,7 +516,7 @@
-
Use fifth dimmable channel as warm white light and the forth dimmable channel as cold white.
Will only work if the device has at least 5 dimmable channels and "white channel" above is also ON.
Enabling this will render useless the "Channel 5" slider in the status page.
Reload the page to update the web interface.
+
Use a dimmable channel as warm white light and another dimmable channel as cold white light.
On devices with two dimmable channels the first use used for warm white light and the second for cold white light.
On color lights the fifth use used for warm white light and the fourth for cold white light.
Will only work if the device has exactly 2 dimmable channels or at least 5 dimmable channels and "white channel" above is also ON.
Enabling this will render useless the "Channel 5" slider in the status page.
Reload the page to update the web interface.