MQTT Light - color, color temperature issues with Lovelace and also Homekit

Hi there,
I really do not know where to start this, I think there is something not working as expected, I know there have been some changes to stuff involved recently, but writing a bug report seems inappropriate at this point because I can’t pin it to a specific integration.

So just let me describe my problem.

I recently bought an RGBWW light controlled with a MiLight controller. I didn’t want to get a remote because I wanted to control it with HA and Homekit and I already knew of the “esp8266_milight_hub” project.
So I set this up and worked great, configured for auto discovery with HA and there you go.
Here my card config and a screenshot of the detailed card:

type: button
tap_action:
  action: toggle
entity: light.buro


This is based on the auto config via MQTT by the milight hub, the message the hub send looks like this:

{
    "schema": "json",
    "name": "Büro",
    "command_topic": "milight/0x721/rgb_cct/1",
    "state_topic": "milight/states/0x721/rgb_cct/1",
    "uniq_id": "136029-Büro",
    "device": {
        "manufacturer": "esp8266_milight_hub",
        "sw_version": "1.10.7",
        "identifiers": [
            1269801,
            1825,
            "rgb_cct",
            1
        ]
    },
    "availability_topic": "milight/client_status",
    "payload_available": "connected",
    "payload_not_available": "disconnected",
    "brightness": true,
    "effect": true,
    "effect_list": [
        "night_mode",
        "white_mode",
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8"
    ],
    "rgb": true,
    "color_temp": true
}

So as far as I know and regarding to the docs of HA this is not fully correct anymore. There is an open issue in the milight hub project that HA changed something but obviously it still works.

Now we get to my real issues. I also use Homekit and the light is published to Homekit. And because it can color and color temperature I can set that too there. Color works but color temperature does not as expected. Instead of setting color temp value it changes the color.
I monitored the MQTT messages sent when I change the color and color temp with HA and Homekit and obviously they are different:
changing color temp with HA:

{
    "state": "ON",
    "color_temp": 186
}

changing color temp with Homekit:

{
    "state": "ON",
    "color": {
        "r": 255,
        "g": 167,
        "b": 79
    }
}

As said before Homekit has two seperate controls for color and temperature but both just generate color change messages. So this seems to be an issue with the Homekit integration I assume.

But things get strange, to track this down I tried to create a dummy light with a manual MQTT light. But I am not able to create a light behaving like the one from auto dicovery. Here is my code:

light:
- platform: mqtt
  schema: json
  name: mqtt_json_light_1
  command_topic: 'home/rgb1/light/switch'
  state_topic: 'home/rgb1/light/status'
  unique_id: mqtt_json_light_1
  availability_topic: 'home/rgb1/client_status'
  payload_available: 'connected'
  payload_not_available: 'disconnected'
  brightness: true
  effect: true
  effect_list: 
    - 'night_mode'
  rgb: true
  color_temp: true

I tried to convert all what the auto discovery gets from the message above but this is what I get as a detailed card in lovelace:
image
The color and color temp configuration is missing. But “Supported color modes” are there so why are the controls missing?
I also tried to set it up as it is now in the docs, “rgb” and “color_temp” and “brightness” do not exists there anymore, there is “color_mode” now and “supported_color_modes” but no success. I am not able to configure a manual MQTT light to show the card in lovelace like the one for the auto discovered entity.

Any ideas?

~Alexander

Ok I am a little dumb in one way, the color wheel and color temp controls were not there because the light was off.
So playing around with the config and faking various messages it seems to me the HomeKit to HA integration has a problem if a light has color and color temp.
If a light has only color then in HomeKit I can select the color and depending on the color mode I get RBG or HS values for example.
If a light has just color temp then I have a different control in HomeKit and setting it produces the expected message in MQTT setting the color temperature.
But if a light has both, HA does it right, using the color temp slider generates a message with the color temp option, changing the color depending on the color mode the expected color values.
Not in Homekit so, I have there both controls too, color works as expected but changing the temperature will also send color values and not color temperature values…

I’ve recently bought some Zigbee RGBCW lights (controlling through Deconz). HomeAssistant works perfectly, but I was planning to control lights mainly from Homekit. RGB mode works great - no complains - but color temperature mode does not work. It only sets RGB values, not color temperature values.

Is there any way to fix this issue? Have you found any solution @Alex9779?

I’m new to the HomeAssistant ecosystem, so I don’t know much, but if someone could point me to the right direction, I would be thankful.

Thanks

!

@Filipko unfortunately I am still searching…
I created a manuel MQTT light and I now have a better understanding of all the options but it is still not really clear and the docs lack a lot of information you have to test to understand.
I found so far that the light seems to work correct. I assume there is a problem in the Homekit bridge. If Homekit is not sending the correct stuff if you have a light with color and temp I cannot say, I think it does it correct so. But then the interpretation by HA is wrong. HA itself does it correct but the commands from Homekit are translated in a wrong way for such a light.
I will try to find more…

core-dev/homeassistant/components/homekit/type_lights.py

if color_supported(self._color_modes):
    self.chars.append(CHAR_HUE)
    self.chars.append(CHAR_SATURATION)
elif color_temp_supported(self._color_modes):
    # ColorTemperature and Hue characteristic should not be
    # exposed both. Both states are tracked separately in HomeKit,
    # causing "source of truth" problems.
    self.chars.append(CHAR_COLOR_TEMPERATURE)

This is a snippet from homekit module for lights.
Obviously it only supports one or the other for some reason.

Maybe it could be changed. @bdraco is author of this snippet.

Maybe I could somehow help Nick?

I want to achieve that, when I am in the color tab - HS color is used and when in Temperature tab - COLOR_TEMP is used. I am just blindly shooting ideas and I am not completely familiar with the code or the whole code base and what events is Homekit sending to homeassistant. Maybe you could help me point to the right direction.

Thanks

Yeah I had a look at that file too but didn’t find that comment. Thanks for pointing it out.
Currently I am trying to set up some dev env to see what’s going on, but this is not an easy task as this requires to be able to add the dev env as a bridge to HomeKit and therefore the dev env has to be reachable from outside the dev computer it is running on. As I am not that familiar with Docker and all that stuff I am failing right now because of the HomeKit advertising.
I’d really love to see what HomeKit is doing here because I don’t really get the meaning of that comment…

The HomeKit spec indicates Hue/Saturation and Color Temperature are mutually exclusive characteristics. The spec explicitly states that Color Temperature must not be used with lamps that support color.

So the screens @Filipko shared of HomeKit are an error? It feels so intentionally designed switching between color and temperature, you have two buttons at the top to switch between color and temperature and you have different selection controls…

1 Like

That is odd, but @bdraco is right according to apple spec:

HomeKitADK/HAPCharacteristicTypes.h at 4967f698bdcf0af122e13e986a2c9b595a68cdc5 · apple/HomeKitADK · GitHub

/**
 * Color Temperature.
 *
 * This characteristic describes color temperature which is represented in reciprocal megaKelvin (MK^-1) or mirek scale.
 * (M = 1,000,000 / K where M is the desired mirek value and K is temperature in Kelvin).
 *
 * If this characteristic is included in the `Light Bulb`, `Hue` and `Saturation` must not be included as optional
 * characteristics in `Light Bulb`. This characteristic must not be used for lamps which support color.
 *
 * This characteristic requires iOS 10.3 or later.
 *
 * - Format: UInt32
 * - Permissions: Paired Read, Paired Write, Notify
 * - Minimum Value: 50
 * - Maximum Value: 400
 * - Step Value: 1
 *
 * @see HomeKit Accessory Protocol Specification R14
 *      Section 9.21 Color Temperature
 */
/**@{*/
#define kHAPCharacteristicDebugDescription_ColorTemperature "color-temperature"

Do you think it could be done? Apple provides two separate controls for setting either color temperature or color, so it must work. Also manufacturer like Philips Hue has done it somehow. I have RGB-CW bulbs and through homekit, it is unusable because of this issue. The white mixed from RGB is not quite right, that is why it would be perfect to use the separate color temperature controls… :confused:

GitHub - Supereg/homebridge-http-lightbulb: Powerful http lightbulb for Homebridge: https://github.com/nfarina/homebridge

colorTemperature optional: Defines everything related to the ‘ColorTemperature’ characteristic:
Although the HAP documentation states, that when using colorTemperature, hue and saturation must not be defined, using all three in combination works perfectly fine.
When selecting something in the color selector the color is sent via the Hue and Saturation characteristics. When selecting something in the temperature selector the temperature is sent via the ColorTemperature characteristic.
If colorTemperature is not specified, the color temperature is sent via the Hue and Saturation characteristics.

According to this description, it should work @bdraco . I would like to try that, but I don’t know how to setup DEV environment with homeassistant and custom homekit component or so…

--- a/homeassistant/components/homekit/type_lights.py
+++ b/homeassistant/components/homekit/type_lights.py
@@ -70,7 +70,7 @@ class Light(HomeAccessory):
         if color_supported(self._color_modes):
             self.chars.append(CHAR_HUE)
             self.chars.append(CHAR_SATURATION)
-        elif color_temp_supported(self._color_modes):
+        if color_temp_supported(self._color_modes):
             # ColorTemperature and Hue characteristic should not be
             # exposed both. Both states are tracked separately in HomeKit,
             # causing "source of truth" problems.

If you change the elif to an if, it should add both chars

I was not able to get a working dev env with but I tried it by hacking my running HA installation and it works.
So I still have issues with my light but I assume this is because of the not fully correct auto discover config sent by the milight hub.
Next step is to setup the light correctly and then see if it working correctly.
At the moment I can control color and temp and MQTT message are correctly sent but in RGB values while the light has HS but does not tell HA correctly…
I will post results…

BTW without really knowing of what is going on this are my changes:

--- a/homeassistant/components/homekit/type_lights.py
+++ b/homeassistant/components/homekit/type_lights.py
@@ -70,7 +70,7 @@ class Light(HomeAccessory):
         if color_supported(self._color_modes):
             self.chars.append(CHAR_HUE)
             self.chars.append(CHAR_SATURATION)
-        elif color_temp_supported(self._color_modes):
+        if color_temp_supported(self._color_modes):
             # ColorTemperature and Hue characteristic should not be
             # exposed both. Both states are tracked separately in HomeKit,
             # causing "source of truth" problems.
@@ -183,16 +183,15 @@ class Light(HomeAccessory):
 
         # Handle Color
         if CHAR_SATURATION in self.chars and CHAR_HUE in self.chars:
+            hue, saturation = None, None
             if ATTR_HS_COLOR in new_state.attributes:
                 hue, saturation = new_state.attributes[ATTR_HS_COLOR]
-            elif ATTR_COLOR_TEMP in new_state.attributes:
+            if ATTR_COLOR_TEMP in new_state.attributes:
                 hue, saturation = color_temperature_to_hs(
                     color_temperature_mired_to_kelvin(
                         new_state.attributes[ATTR_COLOR_TEMP]
                     )
                 )
-            else:
-                hue, saturation = None, None
             if isinstance(hue, (int, float)) and isinstance(saturation, (int, float)):
                 hue = round(hue, 0)
                 saturation = round(saturation, 0)

My type_lights.py was at commit: b775a0d796974608b2e5edfe3e772d7689470f0d

My naive changes are similar to @Alex9779:

diff --git a/homeassistant/components/homekit/type_lights.py b/homeassistant/components/homekit/type_lights.py
index 8be1580537dd4511b2c1921491961e6f3e9e6e52..5a55ab7338d055446351db4b7b3d3113da180870 100644
--- a/homeassistant/components/homekit/type_lights.py
+++ b/homeassistant/components/homekit/type_lights.py
@@ -68,7 +68,7 @@ class Light(HomeAccessory):
         if self._features & SUPPORT_COLOR:
             self.chars.append(CHAR_HUE)
             self.chars.append(CHAR_SATURATION)
-        elif self._features & SUPPORT_COLOR_TEMP:
+        if self._features & SUPPORT_COLOR_TEMP:
             # ColorTemperature and Hue characteristic should not be
             # exposed both. Both states are tracked separately in HomeKit,
             # causing "source of truth" problems.
@@ -183,13 +183,13 @@ class Light(HomeAccessory):
         if CHAR_SATURATION in self.chars and CHAR_HUE in self.chars:
             if ATTR_HS_COLOR in new_state.attributes:
                 hue, saturation = new_state.attributes[ATTR_HS_COLOR]
-            elif ATTR_COLOR_TEMP in new_state.attributes:
+            if ATTR_COLOR_TEMP in new_state.attributes:
                 hue, saturation = color_temperature_to_hs(
                     color_temperature_mired_to_kelvin(
                         new_state.attributes[ATTR_COLOR_TEMP]
                     )
                 )
-            else:
+            if ATTR_HS_COLOR not in new_state.attributes and ATTR_HS_COLOR not in new_state.attributes:
                 hue, saturation = None, None
             if isinstance(hue, (int, float)) and isinstance(saturation, (int, float)):
                 hue = round(hue, 0)

Color temperature controls do work (cool and warm white), but when I save the cool white color (from the Homekit color picker), it saves it as RGB value (I guess). But for example a warm white is saved properly and color temperature is displayed correctly.

But when I call siri to change lights to white, I think it sends rgb value and color_temperature does not work. But when I manually select color temperature from the color temperature tab, it works. So at least some improvement for me.

My steps to modify live homekit component.

1. ssh [email protected] -p 22222
2. login
3. root
4. docker exec -t -i homeassistant /bin/bash
5. cd /usr/src/homeassistant/homeassistant/components/homekit/
6. vi type_lights.py

It is quite cumbersome but I haven’t found a better way yet.