How to configure HomeKit light with colour?

Hi,
I’m trying to add the Xiaomi Gateway Light (via Xiaomi Mi Smart Home Binding) to HomeKit but couldn’t make it work, so I post here and hope can get some help. The light is a bit strange, it has HSB colour channel but brightness in HSB colour channel doesn’t seem to work, instead there is a separate brightness channel. I tried to associate only Lighting.Hue and Lighting.Saturation to the colour channel, but for some reason it thinks Saturation is brightness. Any hint on what to try next? Below is the items config:

Group gXiaomiGatewayLight "Xiaomi Gateway Light"  {homekit="Lighting"}
Switch Xiaomi_gateway_light_switch <light> (gXiaomiGatewayLight) {homekit="Lighting.OnState", channel="mihome:gateway:xxxxx:xxxxx:brightness" }
Color Xiaomi_gateway_color <rgb> (gXiaomiGatewayLight) {homekit="Lighting.Hue, Lighting.Saturation", channel="mihome:gateway:xxxxx:xxxxx:color" }
Dimmer Xiaomi_gateway_brightness <dimmablelight> (gXiaomiGatewayLight){homekit="Lighting.Brightness", channel="mihome:gateway:xxxxx:xxxxx:brightness" }
//Dimmer Xiaomi_gateway_colorTemperature (gXiaomiGatewayLight) {homekit="Lighting.ColorTemperature", channel="mihome:gateway:xxxxx:xxxxx:colorTemperature" }```

Hi @yfre , sorry to ping you here but you helped me with a few HomeKit addon issues.
Maybe you can help with the configuration problem?

BTW yesterday I tried to create another colour item (and of course remove all the other homekit tags but keep the new item in the same group), I made some ugly rules to sync the status between the items.
Color Xiaomi_gateway_color_homekit (gXiaomiGatewayLight) {homekit=“Lighting, Lighting.Hue, Lighting.Saturation, Lighting.Brightness” }

The configuration is copied from the HomeKit addon documentation, but it still doesn’t work fully. For some reason when I use the color picker in Home app to choose colour, it always send Hue below 100, looks like it treats Hue as percentage value or something. So the experiment also failed. I then link this item via HomeBridge plugin which worked flawlessly.

the configuration looks correct. here is for example my for Hue lights


Color TV_Lights    "TV Lights" {homekit ="Lighting,Lighting.OnState,Lighting.Hue,Lighting.Saturation,Lighting.Brightness" [dimmerMode="filterOn"]}

need better understand what excaclty is not working

  • do you see correct controls in home app, e.g. can you select colour and brightness?
  • do you see in the event logs which values the items receives from home app?
  • what happens with the actually device? does it change the colour?

Hi thank you! I notice you also define “Lighting.OnState” so I did the same in my config now:
Color Xiaomi_gateway_color_homekit “Mi Hub Light” (gXiaomiGatewayLight) {homekit =“Lighting,Lighting.OnState,Lighting.Hue,Lighting.Saturation,Lighting.Brightness”}

However it is really strange how it works:

  • do you see correct controls in home app, e.g. can you select colour and brightness?
    Yes I can see the controls and am able to select colour and brightness. But there seems to be some problem when I try to control the device
  • do you see in the event logs which values the items receives from home app?
  • what happens with the actually device? does it change the colour?
    I now try to log the values and below are my observation:
  1. When I change colour to red it sends 77,100,48, when I change to green it sends 78,95,90, when I change to blue it sends 78,100,90.
  2. When I change brightness it actually change colour. So hue and brightness for some reason messed up

And here comes most strange part, it sort of works when I first configure the HomeKit light, after restart of OpenHAB the control got messed up :frowning: When the control is messed up I also receive no response every often but I can still turn on / off the light though.

@yfre:
Just add: now after a few restarts, it’s now brightness and Saturation switched around - when I adjust brightness it sends command to change Saturation :joy:
I have moved the accessory out of the group to avoid conflict without help.
Any suggestion how to troubleshoot?

very strange. i have no explanation for this behaviour.

try to enable more logging via karaf console with

log:set TRACE org.openhab.io.homekit.internal

and see whether you get some more information from homekit binding.

background:
as you saw, home app sends 4 different values. HUE (rgb, e.g. 77,100,48), brightness, saturation and ON/OFF. but on openhab sides we have only one 1 item - color.

in homekit binding we have implemented therefore special logic to first collect all the commands from home app and then updates color item. maybe this logic is not working as expected for you.

so, please enable more logging and also check openhab log and event log. maybe your device also not happy with commands it receives.

Hi @yfre, thank you! I run OH in docker container and not sure how to send command to Karaf console. In the event log after I restarted OH3, I tried to turn the light on:

2022-05-26 13:31:48.195 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘Xiaomi_gateway_color_homekit’ received command ON
2022-05-26 13:31:48.196 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘Xiaomi_gateway_color_homekit’ received command 0,100,0
2022-05-26 13:31:48.204 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘Xiaomi_gateway_color_homekit’ changed from 0,0,0 to 0,0,100
2022-05-26 13:31:48.206 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘Xiaomi_gateway_color_homekit’ changed from 0,0,100 to 0,100,0
2022-05-26 13:31:49.543 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘Xiaomi_gateway_color’ received command 0,100,0
2022-05-26 13:31:49.545 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item ‘Xiaomi_gateway_color’ predicted to become 0,100,0
2022-05-26 13:31:49.609 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘Xiaomi_gateway_color’ received command 0,100,0
2022-05-26 13:31:49.617 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘Xiaomi_gateway_color’ changed from 0,0,60 to 0,100,0
2022-05-26 13:31:49.619 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item ‘Xiaomi_gateway_color’ predicted to become 0,100,0
2022-05-26 13:31:49.720 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘Xiaomi_gateway_light_switch’ changed from OFF to ON

From the event log I can see when I turn on the light:

  1. It frist sent command ON
  2. It then send color change (0,100,0) → I suspect this is the problem, assume this is triggered by ON command, but not sure why it send 100 Saturation instead of 100 Brightness. I think somehow the brightness control is mis-registered on saturation channel.
  3. ON changes state from (0,0,0) to (0,0,100)
  4. Color change in step 3 change the state from (0,0, 100) to (0, 100, 0)

Edit: now I find a way to enable TRACE log and below is the log when I change brightness to 72%, I still think this is something to do with the HomeKit binding, and clearly from the log you an see it sends Hue=72 instead of Brightness=72:
2022-05-26 16:54:36.214 [TRACE] [.homekit.internal.HomekitOHItemProxy] - send OnOff command for item Xiaomi_gateway_color_homekit (Type=ColorItem, State=66.0,100,100, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) with value ON
2022-05-26 16:54:36.216 [TRACE] [.homekit.internal.HomekitOHItemProxy] - send HSB command for item Xiaomi_gateway_color_homekit (Type=ColorItem, State=66.0,100,100, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) with following values hue=72.0 saturation=null brightness=null

Below is the logs in init phase:

2022-05-26 16:51:33.304 [TRACE] [mekit.internal.HomekitChangeListener] - Item Xiaomi_gateway_color_homekit is a HomeKit accessory of types [LIGHTBULB=EMPTY, LIGHTBULB=HUE, LIGHTBULB=SATURATION, LIGHTBULB=BRIGHTNESS] 2022-05-26 16:51:33.318 [TRACE] [.accessories.HomekitAccessoryFactory] - Constructing Xiaomi_gateway_color_homekit of accessory type Lighting 2022-05-26 16:51:33.330 [TRACE] [.accessories.HomekitAccessoryFactory] - Mandatory characteristics for item Xiaomi_gateway_color_homekit characteristics [Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:ON_STATE] 2022-05-26 16:51:33.340 [TRACE] [.accessories.HomekitAccessoryFactory] - Optional characteristics for item Xiaomi_gateway_color_homekit characteristics {BRIGHTNESS=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), SATURATION=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), HUE=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight])} 2022-05-26 16:51:33.508 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type BRIGHTNESS item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:BRIGHTNESS 2022-05-26 16:51:33.526 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type SATURATION item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:SATURATION 2022-05-26 16:51:33.544 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type HUE item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:HUE 2022-05-26 16:51:33.550 [TRACE] [.accessories.HomekitAccessoryFactory] - Constructing Xiaomi_gateway_color_homekit of accessory type Lighting 2022-05-26 16:51:33.554 [TRACE] [.accessories.HomekitAccessoryFactory] - Mandatory characteristics for item Xiaomi_gateway_color_homekit characteristics [Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:ON_STATE] 2022-05-26 16:51:33.564 [TRACE] [.accessories.HomekitAccessoryFactory] - Optional characteristics for item Xiaomi_gateway_color_homekit characteristics {BRIGHTNESS=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), SATURATION=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), HUE=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight])} 2022-05-26 16:51:33.573 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type BRIGHTNESS item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:BRIGHTNESS 2022-05-26 16:51:33.584 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type SATURATION item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:SATURATION 2022-05-26 16:51:33.588 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type HUE item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:HUE 2022-05-26 16:51:33.592 [TRACE] [.accessories.HomekitAccessoryFactory] - Constructing Xiaomi_gateway_color_homekit of accessory type Lighting 2022-05-26 16:51:33.601 [TRACE] [.accessories.HomekitAccessoryFactory] - Mandatory characteristics for item Xiaomi_gateway_color_homekit characteristics [Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:ON_STATE] 2022-05-26 16:51:33.615 [TRACE] [.accessories.HomekitAccessoryFactory] - Optional characteristics for item Xiaomi_gateway_color_homekit characteristics {BRIGHTNESS=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), SATURATION=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), HUE=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight])} 2022-05-26 16:51:33.633 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type BRIGHTNESS item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:BRIGHTNESS 2022-05-26 16:51:33.643 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type SATURATION item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:SATURATION 2022-05-26 16:51:33.663 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type HUE item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:HUE 2022-05-26 16:51:33.675 [TRACE] [.accessories.HomekitAccessoryFactory] - Constructing Xiaomi_gateway_color_homekit of accessory type Lighting 2022-05-26 16:51:33.687 [TRACE] [.accessories.HomekitAccessoryFactory] - Mandatory characteristics for item Xiaomi_gateway_color_homekit characteristics [Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:ON_STATE] 2022-05-26 16:51:33.691 [TRACE] [.accessories.HomekitAccessoryFactory] - Optional characteristics for item Xiaomi_gateway_color_homekit characteristics {BRIGHTNESS=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), SATURATION=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]), HUE=Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight])} 2022-05-26 16:51:33.707 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type BRIGHTNESS item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:BRIGHTNESS 2022-05-26 16:51:33.717 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type SATURATION item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:SATURATION 2022-05-26 16:51:33.728 [TRACE] [ssories.HomekitCharacteristicFactory] - CreateCharacteristic, type HUE item Item:Xiaomi_gateway_color_homekit (Type=ColorItem, State=0,0,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) HomeKit type:LIGHTBULB HomeKit characteristic:HUE

I don’t know if it’s normal to construct the accessory a couple of times, but besides that I don’t see anything strange, no error either.

@yfre, sorry forgot the attach the below info from Karaf:

openhab> openhab:homekit show 1846828048
1846828048 Mi Hub Light
Services:
Service Type: 00000043-0000-1000-8000-0026BB765291
Characteristics:
: class io.github.hapjava.characteristics.impl.common.OnCharacteristic
: class io.github.hapjava.characteristics.impl.lightbulb.BrightnessCharacteristic
: class io.github.hapjava.characteristics.impl.lightbulb.SaturationCharacteristic
: class io.github.hapjava.characteristics.impl.lightbulb.HueCharacteristic

Please kindly advice what I should do next? The problem is for some reason brightness and hue/saturation controls are mixed up.

Edit: I’d also like to add that the integration between OH3 and device is working flawlessly. I tried to expose the Color item via HomeBridge plugin, which also works without problem. That’s why I think there is some issue with the binding, but can’t explain why it works first time but switches channels after restart of OH. The channel switch also happen quite randomly, sometimes between brightness and hue, sometimes between brightness and saturation.

@yfre: sorry to keep pinging you on this but just want to report what I have found out so far.
I have look into the code and tried to gain some understanding (not a Java guy so took quite some time), the class I looked: openhab-addons/HomekitOHItemProxy.java at 020db307bb5e643bb3ddb420fcac484163f59dd2 · openhab/openhab-addons · GitHub
I understand it groups Hue/Saturation, or ON/Brightness when sending commands, which all makes sense.
In working setup (that is when OH3 is already running, I add the homekit configuration to the color item, everything works before restart of OH3.
Below log is when I turn on the light:
2022-05-29 19:46:38.448 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@a7adb2c, command type ON_COMMAND, command state ON. cache state after: {ON_COMMAND=ON}
2022-05-29 19:46:38.449 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@a7adb2c, command type BRIGHTNESS_COMMAND, command state 100. cache state after: {ON_COMMAND=ON, BRIGHTNESS_COMMAND=100}
2022-05-29 19:46:38.449 [TRACE] [.homekit.internal.HomekitOHItemProxy] - send Brightness command for item Xiaomi_gateway_color_homekit (Type=ColorItem, State=95.0,58,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) with value 100
Below log is when I adjust brightness:
2022-05-29 19:48:44.210 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@a7adb2c, command type ON_COMMAND, command state ON. cache state after: {ON_COMMAND=ON}
2022-05-29 19:48:44.211 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@a7adb2c, command type BRIGHTNESS_COMMAND, command state 57. cache state after: {ON_COMMAND=ON, BRIGHTNESS_COMMAND=57}
2022-05-29 19:48:44.211 [TRACE] [.homekit.internal.HomekitOHItemProxy] - send Brightness command for item Xiaomi_gateway_color_homekit (Type=ColorItem, State=95.0,58,59, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) with value 57

As you can see ON and brightness are always fired together. Hue/saturation channels are also mapped correctly.

Now after I restart OH3, the behaviour is changed.
Below is the log when I turn on light
2022-05-29 20:44:54.652 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@7367c9d1, command type ON_COMMAND, command state ON. cache state after: {ON_COMMAND=ON}
2022-05-29 20:44:54.703 [TRACE] [.homekit.internal.HomekitOHItemProxy] - timer of 50 ms is over, sending the command

Note: no command is sent because it also expect the brightness, and in this case HomeKit never send brightness value.

Below is the log when I adjust brightness:
2022-05-29 20:47:51.127 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@7367c9d1, command type ON_COMMAND, command state ON. cache state after: {ON_COMMAND=ON}
2022-05-29 20:47:51.128 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@7367c9d1, command type SATURATION_COMMAND, command state 67. cache state after: {ON_COMMAND=ON, SATURATION_COMMAND=67}
2022-05-29 20:47:51.178 [TRACE] [.homekit.internal.HomekitOHItemProxy] - timer of 50 ms is over, sending the command
2022-05-29 20:47:51.179 [TRACE] [.homekit.internal.HomekitOHItemProxy] - send HSB command for item Xiaomi_gateway_color_homekit (Type=ColorItem, State=45,29,0, Label=Mi Hub Light, Category=null, Groups=[gXiaomiGatewayLight]) with following values hue=null saturation=67 brightness=null

You can see now it treats Brightness as Saturation, which could be the reason why it never sent brightness when the light is turned on.

So to conclude:

  1. When the method sendCommandProxy(HomekitCommandType commandType, State state) is called, somehow it sends in brightness command as saturation
  2. Based on my past experience it could also send brightness command as hue
  3. Everything works perfectly fine when I add the HomeKit configuration while OH3 is running (it will dynamically add the accessory). However after a restart there is a good chance that the channels mixed up (I’m yet to find the logic where the capabilities are registered)

Thank you for the investigation. i also was analyzing the source code over weekend and could not find an explanation for behavior you experience.

as you saw in the source code, the logic is pretty simple - if gets “Brightness” from homekit and sends command “Brightness” via sendCommandProxy .i dont see how it could set saturation instead.

just to exclude home app is the source of issue, could you please enable more logging at apple homekit protocol level with following command in karaf console

log:set TRACE io.github.hapjava

this will print the values it gets from apple ios device. this could help to verify that it sends brightness and we do map it wrongly to saturation.

Hi, thank you for the instructions. I’m not sure how to interpret the log though, below is when I sent ON command:

2022-05-30 19:14:48.379 [DEBUG] [.server.impl.http.impl.BinaryHandler] - Received data [/192.168.1.131:52876]:
PUT /characteristics HTTP/1.1
Host: openHAB._hap._tcp.local
Content-Length: 58
Content-Type: application/hap+json

{"characteristics":[{"aid":1846828048,"iid":9,"value":1}]}
2022-05-30 19:14:48.394 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@54b0af8f, command type ON_COMMAND, command state ON. cache state after: {ON_COMMAND=ON}
2022-05-30 19:14:48.398 [TRACE] [er.impl.http.HomekitClientConnection] - 204 /characteristics
2022-05-30 19:14:48.402 [DEBUG] [.server.impl.http.impl.BinaryHandler] - Sending data [/192.168.1.131:52876]:
HTTP/1.1 204 No Content
Content-type: application/hap+json
Connection: keep-alive


2022-05-30 19:14:48.406 [TRACE] [server.impl.http.impl.LoggingHandler] - WRITE PooledUnsafeDirectByteBuf(ridx: 0, widx: 105, cap: 256) [/192.168.1.131:52876]:
570013FB2A302D02E46041873AD1076140DC58D971643ADC59DAFD1E6F7B348DE4AC1D8659575F665C0D4FC51D920159B74003B72FA7277FD8AA93EF5CC66F4DF961ED084696CB73B1E8E5E3B7178621A04A194E91826E873178A0DA20124A06F599546253AABEBA6D

2022-05-30 19:14:48.449 [TRACE] [.homekit.internal.HomekitOHItemProxy] - timer of 50 ms is over, sending the command
2022-05-30 19:14:49.923 [TRACE] [impl.connections.SubscriptionManager] - Publishing change for 1165470838
2022-05-30 19:14:49.932 [DEBUG] [.server.impl.http.impl.BinaryHandler] - Sending data [/192.168.1.131:52876]:
EVENT/1.0 200 OK
Content-type: application/hap+json
Content-Length: 63
Connection: keep-alive

Below the log when adjusting brightness (which actually changed saturation):

022-05-30 20:02:54.460 [DEBUG] [.server.impl.http.impl.BinaryHandler] - Received data [/192.168.1.131:52876]:
PUT /characteristics HTTP/1.1
Host: openHAB._hap._tcp.local
Content-Length: 60
Content-Type: application/hap+json

{"characteristics":[{"aid":1846828048,"iid":10,"value":54}]}
2022-05-30 20:02:54.464 [TRACE] [.homekit.internal.HomekitOHItemProxy] - add command to command cache: item org.openhab.io.homekit.internal.HomekitOHItemProxy@54b0af8f, command type SATURATION_COMMAND, command state 54. cache state after: {SATURATION_COMMAND=54, ON_COMMAND=ON}

important part is this
{“characteristics”:[{“aid”:1846828048,“iid”:10,“value”:54}]}

it sends for item with id with 1846828048 and characteristic with “id 10” the value 54.
there must one more log at very beginning with longer message that has the mapping from IDs to actual characteristics.
search in the logs for
/accessories
or
/acccessory

Hi @yfre thanks for the help!

I found a large JSON printout with the id “1846828048”, is it the right place?

{
         "aid":1846828048,
         "services":[
            {
               "iid":1,
               "type":"3E",
               "characteristics":[
                  {
                     "iid":2,
                     "type":"14",
                     "perms":[
                        "pw"
                     ],
                     "format":"bool",
                     "description":"identifies the accessory"
                  },
                  {
                     "iid":3,
                     "type":"20",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"manufacturer",
                     "value":"none",
                     "maxLen":255
                  },
                  {
                     "iid":4,
                     "type":"21",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"model",
                     "value":"none",
                     "maxLen":255
                  },
                  {
                     "iid":5,
                     "type":"23",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"name",
                     "value":"Mi Hub Light",
                     "maxLen":255
                  },
                  {
                     "iid":6,
                     "type":"30",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"serial number",
                     "value":"Xiaomi_gateway_color_homekit",
                     "maxLen":255
                  },
                  {
                     "iid":7,
                     "type":"52",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"firmware revision",
                     "value":"none",
                     "maxLen":255
                  }
               ]
            },
            {
               "iid":8,
               "type":"43",
               "characteristics":[
                  {
                     "iid":9,
                     "type":"25",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"bool",
                     "description":"On / Off state",
                     "value":false
                  },
                  {
                     "iid":10,
                     "type":"2F",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"float",
                     "description":"color saturation",
                     "value":0.0,
                     "minValue":0.0,
                     "maxValue":100.0,
                     "minStep":1.0,
                     "unit":"%"
                  },
                  {
                     "iid":11,
                     "type":"13",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"float",
                     "description":"hue or color",
                     "value":0.0,
                     "minValue":0.0,
                     "maxValue":360.0,
                     "minStep":1.0,
                     "unit":"arcdegrees"
                  },
                  {
                     "iid":12,
                     "type":"8",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"int",
                     "description":"level of brightness",
                     "value":0,
                     "minValue":0,
                     "maxValue":100,
                     "minStep":1,
                     "unit":"%"
                  }
               ]
            }
         ]
      },

Hmm according the json request it sent the command with iid=10 which is saturation. Is Home App actually send the json message? I also tested with other HomeKit client (Eve for example) and looks like the same behaviour. Could there be some cache somewhere? Or maybe during initialisation something went wrong?
Many thanks

yes, exactly. this is correct JSON.
home app requests is once and stored it on iOS device. afterwards is only use aid (accessory id) and iid for all communication. it is not really documented, when/how often iOS requests new accessory json

in case of openHAB, the iid and aid can change.

  • aid is based on the name of openHAB item, so, as long the item is not renamed it should be the same
  • iid is just counting up for every characteristics. theoretically, iid can change after OH restart.

so, i was thinking, maybe iOS device has stored somewhere old iids and use them for communication and hence sends to the wrong channel in OH.

this mapping stored in iOS device centrally and used by all apps.

please try following

  • if you have homekit bridges like apple tv, ipad or homepod, deactivate them. maybe they have old mapping
  • restart ios device / iphone

Hi @yfre , thank you for the insight, great to know more about how it works :slight_smile:
I will try disable home hub and restart my iphone as you suggested.
In addition I will also try if iid changes after restart (between working and not working states).
Will report back the result here.

Hi @yfre
You’re right iid is changed almost every time I restart OpenHAB. For example below you can see iid=10 is hue, previously iid=10 is saturation. Not sure I understand why it’s not deterministic. Also it looks like restarting of iPhone help - somehow it triggers iPhone to sync the iids, however it’s not really a good long term solution. So Looks like the problem to be fixed is to ensure iid stays the same after restart of OH. Do you know if there is any workaround to make it happen? Many thanks in advance!

{
         "aid":1846828048,
         "services":[
            {
               "iid":1,
               "type":"3E",
               "characteristics":[
                  {
                     "iid":2,
                     "type":"14",
                     "perms":[
                        "pw"
                     ],
                     "format":"bool",
                     "description":"identifies the accessory"
                  },
                  {
                     "iid":3,
                     "type":"20",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"manufacturer",
                     "value":"none",
                     "maxLen":255
                  },
                  {
                     "iid":4,
                     "type":"21",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"model",
                     "value":"none",
                     "maxLen":255
                  },
                  {
                     "iid":5,
                     "type":"23",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"name",
                     "value":"Mi Hub Light",
                     "maxLen":255
                  },
                  {
                     "iid":6,
                     "type":"30",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"serial number",
                     "value":"Xiaomi_gateway_color_homekit",
                     "maxLen":255
                  },
                  {
                     "iid":7,
                     "type":"52",
                     "perms":[
                        "pr"
                     ],
                     "format":"string",
                     "description":"firmware revision",
                     "value":"none",
                     "maxLen":255
                  }
               ]
            },
            {
               "iid":8,
               "type":"43",
               "characteristics":[
                  {
                     "iid":9,
                     "type":"25",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"bool",
                     "description":"On / Off state",
                     "value":true
                  },
                  {
                     "iid":10,
                     "type":"13",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"float",
                     "description":"hue or color",
                     "value":0.0,
                     "minValue":0.0,
                     "maxValue":360.0,
                     "minStep":1.0,
                     "unit":"arcdegrees"
                  },
                  {
                     "iid":11,
                     "type":"2F",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"float",
                     "description":"color saturation",
                     "value":0.0,
                     "minValue":0.0,
                     "maxValue":100.0,
                     "minStep":1.0,
                     "unit":"%"
                  },
                  {
                     "iid":12,
                     "type":"8",
                     "perms":[
                        "pr",
                        "pw",
                        "ev"
                     ],
                     "format":"int",
                     "description":"level of brightness",
                     "value":56,
                     "minValue":0,
                     "maxValue":100,
                     "minStep":1,
                     "unit":"%"
                  }
               ]
            }
         ]

Edit: I also tried to use a separate Dimmer to control brightness so Color channel only for Hue and Saturation, and it gives the same result. For some reason the capabilities are registered in a random order and a restart of OH almost guarantee the re-ordering of iids. I haven’t seen similar problem with other accessories, and strangely nobody seemed to have this problem (based on search in the forum).

Added a screenshot to illustrate the problem - now brightness channel is mixed up with hue that’s why the percentage value is above 100%

thanks for checking this.

there are multiple candidates where it can get non-deterministic - either during config parsing in openHAB or during iid creation in the protocol library we use. ideally, iid should stored in the database (maybe as item metadata) and re-used. but this would a major re-work in the binding and library…

as quick and still good solution i will implement following

  • there is a way to inform ios devices about changes in the configuration. this force them to retrieve the new accessory list
  • currently we trigger this only on openhab items changes. i will add this to the start function, i.e. every time openhab starts, it will inform all ios devices about new configuration. which could be in the way also good as items config could change between restarts.

Hi @yfre , thank you for looking into it!
“here are multiple candidates where it can get non-deterministic - either during config parsing in openHAB or during iid creation in the protocol library we use.”
Can I do something to help finding out if it’s config parse of OH or HAP-Java who determine the order? If it’s config parse maybe we can do something in OH by sorting the items or HomeKit annotations?

“currently we trigger this only on openhab items changes. i will add this to the start function”
Yes I noticed when I modify the items file it pauses all accessories in HomeKit for re-sync, and that’s probably why when I add the HK config while OH is running, it always works. Ideally we should consider the cache or DB solution so HK settings can be backup for restore. I have done multiple times messed around with items file and a re-sync cause HomeKit lost all accessories. Can always add them back by fixing the issue, but all automations need to be re-created/checked. But I think it is a good idea to re-sync when OH restarts though.
Thanks for looking into it and please let me know if you need me to take any more tests.

done. Pull request is here

re-sync should not destroy any configuration and automation in home app as long as the accessories ID (aid) remain the same