diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 94cd394ee..196a6b809 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -4,6 +4,8 @@ - Add better config corruption recovery (#9046) - Remove support for 1-step upgrade from versions before 6.6.0.11 to versions after 8.4.0.1 +- Change White blend mode moved to using ``SetOption 105`` instead of ``RGBWWTable`` +- Add Virtual CT for 4 channels lights, emulating a 5th channel ### 8.4.0.1 20200730 diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index dd5632d12..ca6067031 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -914,6 +914,8 @@ void CmndSetoption(void) case 20: // SetOption102 - Set Baud rate for Teleinfo serial communication (0 = 1200 or 1 = 9600) case 21: // SetOption103 - Enable TLS mode (requires TLS version) case 22: // SetOption104 - No Retain - disable all MQTT retained messages, some brokers don't support it: AWS IoT, Losant + case 24: // SetOption106 - Virtual CT - Creates a virtual White ColorTemp for RGBW lights + case 25: // SetOption107 - Virtual CT Channel - signals whether the hardware white is cold CW (true) or warm WW (false) restart_flag = 2; break; } diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 908ec026e..941659d62 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -284,6 +284,7 @@ struct LIGHT { bool update = true; bool pwm_multi_channels = false; // SetOption68, treat each PWM channel as an independant dimmer + bool virtual_ct = false; // SetOption106, add a 5th virtual channel, only if SO106 = 1, SO68 = 0, Light is RGBW (4 channels), SO37 < 128 bool fade_initialized = false; // dont't fade at startup bool fade_running = false; @@ -1281,13 +1282,16 @@ bool LightModuleInit(void) } // post-process for lights + uint32_t pwm_channels = (light_type & 7) > LST_MAX ? LST_MAX : (light_type & 7); if (Settings.flag3.pwm_multi_channels) { // SetOption68 - Enable multi-channels PWM instead of Color PWM - uint32_t pwm_channels = (light_type & 7) > LST_MAX ? LST_MAX : (light_type & 7); if (0 == pwm_channels) { pwm_channels = 1; } devices_present += pwm_channels - 1; // add the pwm channels controls at the end - } else if ((Settings.param[P_RGB_REMAP] & 128) && (LST_RGBW <= (light_type & 7))) { + } else if ((Settings.param[P_RGB_REMAP] & 128) && (LST_RGBW <= pwm_channels)) { // if RGBW or RGBCW, and SetOption37 >= 128, we manage RGB and W separately, hence adding a device devices_present++; + } else if ((Settings.flag4.virtual_ct) && (LST_RGBW == pwm_channels)) { + Light.virtual_ct = true; // enabled + light_type++; // create an additional virtual 5th channel } return (light_type > LT_BASIC); @@ -1314,6 +1318,12 @@ void LightCalcPWMRange(void) { void LightInit(void) { + // move white blend mode from deprecated `RGBWWTable` to `SetOption105` + if (0 == Settings.rgbwwTable[4]) { + Settings.flag4.white_blend_mode = true; + Settings.rgbwwTable[4] = 255; // set RGBWWTable value to its default + } + Light.device = devices_present; Light.subtype = (light_type & 7) > LST_MAX ? LST_MAX : (light_type & 7); // Always 0 - LST_MAX (5) Light.pwm_multi_channels = Settings.flag3.pwm_multi_channels; // SetOption68 - Enable multi-channels PWM instead of Color PWM @@ -1875,10 +1885,6 @@ void LightAnimate(void) Light.new_color[i] = Light.current_color[i]; } } else { -/* - Response_P(PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\"}")); - MqttPublishPrefixTopic_P(TELE, PSTR(D_CMND_WAKEUP)); -*/ Response_P(PSTR("{\"" D_CMND_WAKEUP "\":\"" D_JSON_DONE "\"")); ResponseLightState(1); ResponseJsonEnd(); @@ -1939,6 +1945,7 @@ void LightAnimate(void) uint16_t cur_col_10[LST_MAX]; // 10 bits resolution Light.update = false; + bool rgbwwtable_applied = false; // did we already applied RGBWWTable (ex: in white_blend_mode or virtual_ct) // first set 8 and 10 bits channels for (uint32_t i = 0; i < LST_MAX; i++) { @@ -1954,7 +1961,7 @@ void LightAnimate(void) // Now see if we need to mix RGB and True White // Valid only for LST_RGBW, LST_RGBCW, rgbwwTable[4] is zero, and white is zero (see doc) - if ((LST_RGBW <= Light.subtype) && (0 == Settings.rgbwwTable[4]) && (0 == cur_col_10[3]+cur_col_10[4])) { + if ((LST_RGBW <= Light.subtype) && (Settings.flag4.white_blend_mode) && (0 == cur_col_10[3]+cur_col_10[4])) { uint32_t min_rgb_10 = min3(cur_col_10[0], cur_col_10[1], cur_col_10[2]); for (uint32_t i=0; i<3; i++) { // substract white and adjust according to rgbwwTable @@ -1974,18 +1981,34 @@ void LightAnimate(void) cur_col_10[4] = changeUIntScale(ct, 0, 1023, 0, white_10); cur_col_10[3] = white_10 - cur_col_10[4]; } + rgbwwtable_applied = true; + } else if ((Light.virtual_ct) && (0 == cur_col_10[0]+cur_col_10[1]+cur_col_10[2])) { + // virtual_ct is on and we don't have any RGB set + uint16_t sw_white = Settings.flag4.virtual_ct_cw ? cur_col_10[4] : cur_col_10[3]; // white power for virtual RGB + uint16_t hw_white = Settings.flag4.virtual_ct_cw ? cur_col_10[3] : cur_col_10[4]; // white for hardware LED + uint32_t adjust_sw = change8to10(Settings.flag4.virtual_ct_cw ? Settings.rgbwwTable[4] : Settings.rgbwwTable[3]); + uint32_t adjust_hw = change8to10(Settings.flag4.virtual_ct_cw ? Settings.rgbwwTable[3] : Settings.rgbwwTable[4]); + // set the target channels. Note: Gamma correction was arleady applied + cur_col_10[3] = changeUIntScale(hw_white, 0, 1023, 0, adjust_hw); + cur_col_10[4] = 0; // we don't actually have a 5the channel + sw_white = changeUIntScale(sw_white, 0, 1023, 0, adjust_sw); // pre-adjust virtual channel + for (uint32_t i=0; i<3; i++) { + uint32_t adjust = change8to10(Settings.rgbwwTable[i]); + cur_col_10[i] = changeUIntScale(sw_white, 0, 1023, 0, adjust); + } + rgbwwtable_applied = true; } } - // Apply RGBWWTable only if Settings.rgbwwTable[4] != 0 - if (0 != Settings.rgbwwTable[4]) { + // Apply RGBWWTable only if not Settings.flag4.white_blend_mode + if (!rgbwwtable_applied) { for (uint32_t i = 0; i 0) ? changeUIntScale(cur_col_10[i], 1, 1023, 1, Settings.pwm_range) : 0;