diff --git a/homeassistant/components/mqtt/light/schema_basic.py b/homeassistant/components/mqtt/light/schema_basic.py
index 03f78b8c43fa4b698db7fcb6c2f4c9d80d61ebbb..c12d8719d7a4db2f53626d9f34c02cab9b4205aa 100644
--- a/homeassistant/components/mqtt/light/schema_basic.py
+++ b/homeassistant/components/mqtt/light/schema_basic.py
@@ -463,6 +463,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
 
         add_topic(CONF_BRIGHTNESS_STATE_TOPIC, brightness_received)
 
+        @callback
         def _rgbx_received(
             msg: ReceiveMessage,
             template: str,
@@ -533,11 +534,26 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
         @log_messages(self.hass, self.entity_id)
         def rgbww_received(msg: ReceiveMessage) -> None:
             """Handle new MQTT messages for RGBWW."""
+
+            @callback
+            def _converter(
+                r: int, g: int, b: int, cw: int, ww: int
+            ) -> tuple[int, int, int]:
+                min_kelvin = color_util.color_temperature_mired_to_kelvin(
+                    self.max_mireds
+                )
+                max_kelvin = color_util.color_temperature_mired_to_kelvin(
+                    self.min_mireds
+                )
+                return color_util.color_rgbww_to_rgb(
+                    r, g, b, cw, ww, min_kelvin, max_kelvin
+                )
+
             rgbww = _rgbx_received(
                 msg,
                 CONF_RGBWW_VALUE_TEMPLATE,
                 ColorMode.RGBWW,
-                color_util.color_rgbww_to_rgb,
+                _converter,
             )
             if rgbww is None:
                 return
diff --git a/tests/components/mqtt/test_light.py b/tests/components/mqtt/test_light.py
index ba0b21b5ceba807792629313fb0a5a1dbbeb8bc8..0199ee19772be4b66c58cc152377046a5f054ecf 100644
--- a/tests/components/mqtt/test_light.py
+++ b/tests/components/mqtt/test_light.py
@@ -198,6 +198,7 @@ from homeassistant.const import (
 from homeassistant.core import HomeAssistant, State
 
 from .test_common import (
+    help_custom_config,
     help_test_availability_when_connection_lost,
     help_test_availability_without_topic,
     help_test_custom_availability_payload,
@@ -441,6 +442,176 @@ async def test_controlling_state_via_topic(
     assert light_state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) == color_modes
 
 
+@pytest.mark.parametrize(
+    "hass_config",
+    [
+        help_custom_config(
+            light.DOMAIN,
+            DEFAULT_CONFIG,
+            (
+                {
+                    "state_topic": "test-topic",
+                    "optimistic": True,
+                    "brightness_command_topic": "test_light_rgb/brightness/set",
+                    "color_mode_state_topic": "color-mode-state-topic",
+                    "rgb_command_topic": "test_light_rgb/rgb/set",
+                    "rgb_state_topic": "rgb-state-topic",
+                    "rgbw_command_topic": "test_light_rgb/rgbw/set",
+                    "rgbw_state_topic": "rgbw-state-topic",
+                    "rgbww_command_topic": "test_light_rgb/rgbww/set",
+                    "rgbww_state_topic": "rgbww-state-topic",
+                },
+            ),
+        )
+    ],
+)
+async def test_received_rgbx_values_set_state_optimistic(
+    hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
+) -> None:
+    """Test the state is set correctly when an rgbx update is received."""
+    await mqtt_mock_entry()
+    state = hass.states.get("light.test")
+    assert state and state.state is not None
+    async_fire_mqtt_message(hass, "test-topic", "ON")
+    ## Test rgb processing
+    async_fire_mqtt_message(hass, "rgb-state-topic", "255,255,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgb"
+    assert state.attributes["rgb_color"] == (255, 255, 255)
+
+    # Only update color mode
+    async_fire_mqtt_message(hass, "color-mode-state-topic", "rgbww")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbww"
+
+    # Resending same rgb value should restore color mode
+    async_fire_mqtt_message(hass, "rgb-state-topic", "255,255,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgb"
+    assert state.attributes["rgb_color"] == (255, 255, 255)
+
+    # Only update brightness
+    await common.async_turn_on(hass, "light.test", brightness=128)
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 128
+    assert state.attributes["color_mode"] == "rgb"
+    assert state.attributes["rgb_color"] == (255, 255, 255)
+
+    # Resending same rgb value should restore brightness
+    async_fire_mqtt_message(hass, "rgb-state-topic", "255,255,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgb"
+    assert state.attributes["rgb_color"] == (255, 255, 255)
+
+    # Only change rgb value
+    async_fire_mqtt_message(hass, "rgb-state-topic", "255,255,0")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgb"
+    assert state.attributes["rgb_color"] == (255, 255, 0)
+
+    ## Test rgbw processing
+    async_fire_mqtt_message(hass, "rgbw-state-topic", "255,255,255,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbw"
+    assert state.attributes["rgbw_color"] == (255, 255, 255, 255)
+
+    # Only update color mode
+    async_fire_mqtt_message(hass, "color-mode-state-topic", "rgb")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgb"
+
+    # Resending same rgbw value should restore color mode
+    async_fire_mqtt_message(hass, "rgbw-state-topic", "255,255,255,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbw"
+    assert state.attributes["rgbw_color"] == (255, 255, 255, 255)
+
+    # Only update brightness
+    await common.async_turn_on(hass, "light.test", brightness=128)
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 128
+    assert state.attributes["color_mode"] == "rgbw"
+    assert state.attributes["rgbw_color"] == (255, 255, 255, 255)
+
+    # Resending same rgbw value should restore brightness
+    async_fire_mqtt_message(hass, "rgbw-state-topic", "255,255,255,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbw"
+    assert state.attributes["rgbw_color"] == (255, 255, 255, 255)
+
+    # Only change rgbw value
+    async_fire_mqtt_message(hass, "rgbw-state-topic", "255,255,128,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbw"
+    assert state.attributes["rgbw_color"] == (255, 255, 128, 255)
+
+    ## Test rgbww processing
+    async_fire_mqtt_message(hass, "rgbww-state-topic", "255,255,255,32,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbww"
+    assert state.attributes["rgbww_color"] == (255, 255, 255, 32, 255)
+
+    # Only update color mode
+    async_fire_mqtt_message(hass, "color-mode-state-topic", "rgb")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgb"
+
+    # Resending same rgbw value should restore color mode
+    async_fire_mqtt_message(hass, "rgbww-state-topic", "255,255,255,32,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbww"
+    assert state.attributes["rgbww_color"] == (255, 255, 255, 32, 255)
+
+    # Only update brightness
+    await common.async_turn_on(hass, "light.test", brightness=128)
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 128
+    assert state.attributes["color_mode"] == "rgbww"
+    assert state.attributes["rgbww_color"] == (255, 255, 255, 32, 255)
+
+    # Resending same rgbww value should restore brightness
+    async_fire_mqtt_message(hass, "rgbww-state-topic", "255,255,255,32,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbww"
+    assert state.attributes["rgbww_color"] == (255, 255, 255, 32, 255)
+
+    # Only change rgbww value
+    async_fire_mqtt_message(hass, "rgbww-state-topic", "255,255,128,32,255")
+    await hass.async_block_till_done()
+    state = hass.states.get("light.test")
+    assert state.attributes["brightness"] == 255
+    assert state.attributes["color_mode"] == "rgbww"
+    assert state.attributes["rgbww_color"] == (255, 255, 128, 32, 255)
+
+
 @pytest.mark.parametrize(
     "hass_config",
     [