Announce new HomeKit client binding

This is to announce that we have a new HomeKit client binding which is in an advanced stage of completion. So if users would like to test it, then your feedback would be most welcome. There are Jars for OH 5.03 and 5.1.x at the top of the PR thread.

6 Likes

Great news!

I’d love to give it a spin, but I’m on 4.3. Would it be possible possible to compile a jar for this version?

I dont think 4.x is possible. There is too big a gap in terms of Java language features and dependencies.

Very excited to see this. I’ve got a series of Aqara FP2’s that I’m connecting to HA’s homekit client and then bridging over to OH via matter. I’d love to get them into OH more natively.

Fortunately, I have an extra lying around for testing. Unfortunately no luck yet.

I’m on 5.1 snapshot build #4899. Binding loaded fine. Scanning detects all my FP2’s (and my Rachio spinkler). Adding the thing works fine, but pairing did not.

Thing page gave a pairing result of true when I ran the pairing action, but thing status remained Offline/configuration error (pairing / verification failed).

The only error I saw in the logs was this:

2025-11-11 20:36:40.903 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception: 
java.lang.IllegalArgumentException: Duplicate channels homekit:accessory:cb371a0e8b10:sensor-occupancy#occupancy-detected
	at org.openhab.core.thing.util.ThingHelper.ensureUniqueChannels(ThingHelper.java:140) ~[?:?]
	at org.openhab.core.thing.util.ThingHelper.ensureUniqueChannels(ThingHelper.java:116) ~[?:?]
	at org.openhab.core.thing.binding.builder.ThingBuilder.withChannels(ThingBuilder.java:154) ~[?:?]
	at org.openhab.binding.homekit.internal.handler.HomekitAccessoryHandler.createChannels(HomekitAccessoryHandler.java:413) ~[?:?]
	at org.openhab.binding.homekit.internal.handler.HomekitAccessoryHandler.onRootThingAccessoriesLoaded(HomekitAccessoryHandler.java:895) ~[?:?]
	at org.openhab.binding.homekit.internal.handler.HomekitBaseAccessoryHandler.processDependentThings(HomekitBaseAccessoryHandler.java:235) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
	at java.lang.Thread.run(Thread.java:1583) [?:?]

Subsequent attempts to pair result in

2025-11-11 20:38:38.146 [WARN ] [.handler.HomekitBaseAccessoryHandler] - Pairing / verification failed 'Pairing method 'SETUP' action failed with error 'UNAVAILABLE'' for homekit:accessory:cb371a0e8b10

Which I guess means that the device at least thinks the first attempt at pairing worked. Now I have to figure out how to unpair (or reset it) before I can try again.

I can’t test my rachio it seems, that one needs the app on an iOS device to generate the homekit code and we have no iOS devices here. Over Thanksgiving some of my guests might have iPhones.

Edit:
For what it’s worth I think the duplicate channels refers to the fact that you can configure different presense zones with the FP2’s and I just randomly set this one up with two zones for testing. From my experience with the HA homekit configs that means that 3 presences channels are produced, 1 general for the entire detection area of the device and then 1 for each zone within that area.

Here’s an example from HA of one of the devices with 3 zones (and therefore 4 presence channels):

@JustinG many thanks for testing. It revealed apparently two bugs – namely 1) the duplicated channels, and 2) that that error caused the valid pairing result not to have been persisted. I will get onto this.

@AndrewFG I was able to pair my tado bridge (unsure whether it was with true or false, I’m afraid - it appeared to fail with both, but then turned out to be paired after all).

I then was able to create one of the things. I don’t understand all channels:

The 0 and 1 states seem odd, and when opening the items:

&

I understand the temperature-target, of course, but it’s not yet working:

openhab> bundle:list -s | grep -i homekit
380 │ Active │  80 │ 5.0.3.202511111917    │ org.openhab.binding.homekit
openhab> log:tail
14:35:44.866 [INFO ] [openhab.event.ItemCommandEvent       ] - Item 'Verwarming_badkamer_targetTemp' received command 18
14:35:44.869 [INFO ] [openhab.event.ItemStatePredictedEvent] - Item 'Verwarming_badkamer_targetTemp' predicted to become 18
14:35:44.870 [INFO ] [openhab.event.ItemStateChangedEvent  ] - Item 'Verwarming_badkamer_targetTemp' changed from 17 °C to 18 °C

Alas:

Binding logs:

2025-11-12 14:35:44.875 [TRACE] [mekit.internal.transport.IpTransport - 2186      ] - HTTP request:
PUT /characteristics HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.
Content-Length: 53
Content-Type: application/hap+json

{"characteristics":[{"iid":15,"value":18.0,"aid":5}]}
2025-11-12 14:35:44.920 [TRACE] [mekit.internal.transport.IpTransport - 2186      ] - HTTP response:
HTTP/1.1 204 No Content
Content-Length:0


2025-11-12 14:36:09.592 [TRACE] [mekit.internal.transport.IpTransport - 2381      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:36:09.641 [TRACE] [mekit.internal.transport.IpTransport - 2381      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:37:09.645 [TRACE] [mekit.internal.transport.IpTransport - 2625      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:37:09.686 [TRACE] [mekit.internal.transport.IpTransport - 2625      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:38:09.690 [TRACE] [mekit.internal.transport.IpTransport - 2479      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:38:09.752 [TRACE] [mekit.internal.transport.IpTransport - 2479      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:39:09.755 [TRACE] [mekit.internal.transport.IpTransport - 2737      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:39:09.841 [TRACE] [mekit.internal.transport.IpTransport - 2737      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:40:09.845 [TRACE] [mekit.internal.transport.IpTransport - 2735      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:40:09.886 [TRACE] [mekit.internal.transport.IpTransport - 2735      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:41:09.890 [TRACE] [mekit.internal.transport.IpTransport - 2738      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:41:09.945 [TRACE] [mekit.internal.transport.IpTransport - 2738      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:42:09.949 [TRACE] [mekit.internal.transport.IpTransport - 2874      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:42:10.013 [TRACE] [mekit.internal.transport.IpTransport - 2874      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:43:10.018 [TRACE] [mekit.internal.transport.IpTransport - 2751      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:43:10.079 [TRACE] [mekit.internal.transport.IpTransport - 2751      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:44:10.084 [TRACE] [mekit.internal.transport.IpTransport - 2903      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:44:10.164 [TRACE] [mekit.internal.transport.IpTransport - 2903      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:45:10.168 [TRACE] [mekit.internal.transport.IpTransport - 3039      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:45:10.231 [TRACE] [mekit.internal.transport.IpTransport - 3039      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:46:10.237 [TRACE] [mekit.internal.transport.IpTransport - 3095      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:46:10.308 [TRACE] [mekit.internal.transport.IpTransport - 3095      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:47:10.312 [TRACE] [mekit.internal.transport.IpTransport - 3053      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:47:10.369 [TRACE] [mekit.internal.transport.IpTransport - 3053      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}
2025-11-12 14:48:10.371 [TRACE] [mekit.internal.transport.IpTransport - 2479      ] - HTTP request:
GET /characteristics?id=5.12,5.15,5.13,5.14,5.17 HTTP/1.1
Host: tado\032Internet\032Bridge\032IB3857268224._hap._tcp.local.


2025-11-12 14:48:10.423 [TRACE] [mekit.internal.transport.IpTransport - 2479      ] - HTTP response:
HTTP/1.1 200 OK
Content-Length:171
Content-Type:application/hap+json

{"characteristics":[{"aid":5,"iid":12,"value":0},{"aid":5,"iid":13,"value":1},{"aid":5,"iid":14,"value":18.8},{"aid":5,"iid":15,"value":18},{"aid":5,"iid":17,"value":65}]}

Furthermore: are these all the possible channels?

Because it’s of course important to know whether the device is on MANUAL or SCHEDULE… Or in any case, it’s important I can set it to either. (Having it later remain in a state that might not be accurate, is not up to standard, but at least it’s workable for me.)

Congratulations!


The Apple specification uses numbers to read the current state and read/write the target state. And as you say the meaning of these numbers is not always obvious. They are documented in the Apple specification (see screenshots below) so in the binding the channel’s state description contains a lookup between the number and its description.


What you see is certainly the full list of standard channels according to the Apple specification. If you follow the analog discussion on the Home Assistant forum you can see that everyone is complaining about this.

It may be that Tado has implemented some custom channels (which the binding currently cannot see) => So perhaps you can turn on trace logging, and capture the full response of the initial GET /accessories request which should let us see if there are such custom channels (albeit not telling us what they mean..)

Indeed. I think tado is being disengenuous when they claim that HomeKit is a one for one replacement of their own (paid) API..

According to your logs this channel is aid:5, iid:15 .. and we can see the command value 18 being sent, and the same value coming back on the next polling. So I think the HomeKit API is working properly. My hypothesis is that since you have set a manual override in the app, this overrides what may come from HomeKit. You should probably try setting the heat-cooling-target channel to heat or cool or auto before you send the temperature setpoint command.

Unfortunately I think this will need some experimentation to unravel the arcana of Tado’s implementation; where unfortunately I am no wiser than you..

Ok. I have just pushed a fix for the duplicate channels issue; the new Jar is in the same location as before..

Indeed it means just that. The binding will already have stored the pairing credentials,so when you load the new Jar the Thing should come online immediately.

As mentioned above, this should in fact not be necessary.

PS this suggests that perhaps we should disable the ‘pair’ thing action if the thing is already paired; and disable the ‘unpair’ thing action if it not already paired.

Some more testing is probably needed. But if I set the valve to SCHEDULE, I still can’t control the target temperature with the HomeKit binding. That’s all I could test now; time is lacking.

1 Like

Awesome progress! I had actually already managed to unpair the device after my last post, so I got the chance to go through the whole process from discovery to pairing and that all worked.

Three new (far more minor) issues:

  1. Although all the different presence zones are found and created as channels, they do not get values independently. Both of the individual detection zones trigger when there is presence in either of them (the overall zone triggers too, but that should happen).
  2. Maybe this is a homekit thing because it’s also true of my other sensors connected HA → MatterBridge → OH, but the binary values for presence are opposite what I expect. My other sensors come in as Switch channels, but OFF is presence detected and ON is no presence (I reverse that with a map profile). With these Contact channels, CLOSED is presence and OPEN is no presence. For presence channels I would expect the 1 value to be presence and the 0 value no presence.
  3. The HA connection is push not polling, the response time with polling is not great for a presence sensor.

Illumination channel seems to work just fine.

One additional question: I do not have these sensors set with static IPs, but the IP does seem to be one of the primary connection datapoints. Is the Thing actually using the IP, because that will likely change over time.

Ok. I will look into that.

I tried to follow the OH standard (as follows) so perhaps you can can give me a log with json when your sensor changes state and back so I can check the logic?

  • 0 == false == OFF == CLOSED
  • 1 == true == ON == OPEN

The binding supports both polling and eventing models. But not all devices support the latter on all charactersistics. You should see a log message like the following. Whereby the logic is that to save resources the binding will only do polling and eventing on channels that are actually linked to an item. So if you have newly linked the Items then you may need to do a restart.

2025-11-13 08:31:15.627 [DEBUG] [rnal.handler.HomekitAccessoryHandler] - homekit:accessory:8e2a9e4bff1:73418603 updated with 2 channels (of which 2 polled, 2 evented), 5 properties, label: 'null', equipment tag: 'null'

Yes I recommend using static IPs

I checked this logic again and can confirm it.

If a channel is newly linked during a session then it will be added to the polled channel list, but not to the evented channel list. A restart is required to initialize the evented channel list.

Again I checked the code. I cannot find anything wrong. However if you have JSON it would certainly help.

Can you elaborate on that? What does that mean exactly?

Probably disable and reenable the bridge thing. Or the thing itself if it has no bridge.

Yep, restart solved that. Events now push to the binding.

As I suspected, it is the underlying value that’s “backwards”

Leaving area gets a value of 1:

==> /log/openhab.log <==

2025-11-13 08:42:40.892 [TRACE] [mekit.internal.transport.IpTransport] - HTTP event:
EVENT/1.0 200 OK
Content-Type: application/hap+json
Content-Length: 52
{"characteristics":[{"aid":1,"iid":2698,"value":1}]}

==> /log/events.log <==
2025-11-13 08:42:40.894 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Presence_HKTest_Sensoroccupancy_Occupancydetected2' changed from CLOSED to OPEN (source: org.openhab.core.thing$homekit:accessory:cb371a0e8b10:sensor-occupancy#occupancy-detected-2)
2025-11-13 08:42:40.894 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Presence_HKTest_Sensoroccupancy_Occupancydetected1' changed from CLOSED to OPEN (source: org.openhab.core.thing$homekit:accessory:cb371a0e8b10:sensor-occupancy#occupancy-detected-1)
2025-11-13 08:42:40.894 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Presence_HKTest_Sensoroccupancy_Occupancydetected' changed from CLOSED to OPEN (source: org.openhab.core.thing$homekit:accessory:cb371a0e8b10:sensor-occupancy#occupancy-detected)

Entering area gets a value of 0:

==> /log/openhab.log <==

2025-11-13 08:49:31.625 [TRACE] [mekit.internal.transport.IpTransport] - HTTP event:
EVENT/1.0 200 OK
Content-Type: application/hap+json
Content-Length: 52
{"characteristics":[{"aid":1,"iid":2698,"value":0}]}

==> /log/events.log <==
2025-11-13 08:49:31.628 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Presence_HKTest_Sensoroccupancy_Occupancydetected2' changed from OPEN to CLOSED (source: org.openhab.core.thing$homekit:accessory:cb371a0e8b10:sensor-occupancy#occupancy-detected-2)
2025-11-13 08:49:31.628 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Presence_HKTest_Sensoroccupancy_Occupancydetected1' changed from OPEN to CLOSED (source: org.openhab.core.thing$homekit:accessory:cb371a0e8b10:sensor-occupancy#occupancy-detected-1)
2025-11-13 08:49:31.628 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Presence_HKTest_Sensoroccupancy_Occupancydetected' changed from OPEN to CLOSED (source: org.openhab.core.thing$homekit:accessory:cb371a0e8b10:sensor-occupancy#occupancy-detected)

That still doesn’t prove whether these sensor send an unusual value (as I understand it Aqara does that sometimes) or the homekit standard for presence is reversed. I can say that the devices connected to HA properly indicate presence/absence in HA without any need to modify the incoming value manually. But the raw values HA relays out through MQTT or Matter are the reversed values. So, the HA homekit integration is at least in some way aware of this issue, which makes me suspect that it’s some homekit standard.

Also, in the above logs you can see that all three channels respond identically to a single event.

Interestingly there’s the occasional log which I assume is either OH polling or some heartbeat connection:

==> /log/openhab.log <==
2025-11-13 08:49:22.458 [TRACE] [mekit.internal.transport.IpTransport] - HTTP response:
HTTP/1.1 200 OK
Content-Type: application/hap+json
Content-Length: 147
{"characteristics":[{"aid":1,"iid":2698,"value":1},{"aid":1,"iid":2698,"value":1},{"aid":1,"iid":2698,"value":1},{"aid":1,"iid":2674,"value":106}]}

All three objects that I assume are the three different presence channels have the same iid.

I meant: what does ‘a session’ mean? And ‘polled’ and ‘evented’ channels? :slight_smile:

A session is a HomeKit encrypted HTTP connection over a standard TCP socket.

A polled channel is one where the binding has to request the data “pull”..

An evented channel where the accessory sends the data to the binding “push”..

You can check the Apple specification (which is linked at the top of my PR) chapter 9.60 refers to Motion Detected where 0 (false, closed) means no motion and 1 (true, open) means motion detected. So it looks like your sensor is wrong.

And I do not want to make custom deviations from the Apple specification for particular manufacturers or particular devices. Otherwise nobody will have any real reference to anything..

This is a polling request / response. If the three characteristics have the same aid and the same iid then they are in effect the identical characteristic, as there is no way to tell the difference btween them. I consider this to be a bug in the device.

These are mmWave presence sensors, not motion sensors. So it should be 9.67, but indeed the specs say that should be 1 for occupancy and 0 for no occupancy. However, there does appear to be a difference in that motion is listed as bool format and occupancy as unit8. Is there any way that’s causing the issue?

Interesting. My devices connected to HA do not have this issue. Each of the detection zones gets a different iid.

HA diagnositcs
          {
            "iid": 2688,
            "type": "00000086-0000-1000-8000-0026BB765291",
            "characteristics": [
              {
                "type": "00000023-0000-1000-8000-0026BB765291",
                "iid": 2689,
                "perms": [
                  "pr"
                ],
                "format": "string",
                "value": "Presence Sensor 1",
                "description": "Name",
                "maxLen": 64
              },
              {
                "type": "00000071-0000-1000-8000-0026BB765291",
                "iid": 2690,
                "perms": [
                  "pr",
                  "ev"
                ],
                "format": "uint8",
                "value": 0,
                "description": "Occupancy Detected",
                "minValue": 0,
                "maxValue": 1,
                "minStep": 1
              },
              {
                "type": "C8622A33-826A-4DD3-9BE9-D496361F29BB",
                "iid": 2691,
                "perms": [
                  "pr",
                  "hd"
                ],
                "format": "uint8",
                "value": 0,
                "description": "Sensor Index",
                "minValue": 0,
                "maxValue": 30,
                "minStep": 1
              }
            ]
          },
          {
            "iid": 2692,
            "type": "00000086-0000-1000-8000-0026BB765291",
            "characteristics": [
              {
                "type": "00000023-0000-1000-8000-0026BB765291",
                "iid": 2693,
                "perms": [
                  "pr"
                ],
                "format": "string",
                "value": "Presence Sensor 2",
                "description": "Name",
                "maxLen": 64
              },
              {
                "type": "00000071-0000-1000-8000-0026BB765291",
                "iid": 2694,
                "perms": [
                  "pr",
                  "ev"
                ],
                "format": "uint8",
                "value": 0,
                "description": "Occupancy Detected",
                "minValue": 0,
                "maxValue": 1,
                "minStep": 1
              },
              {
                "type": "C8622A33-826A-4DD3-9BE9-D496361F29BB",
                "iid": 2695,
                "perms": [
                  "pr",
                  "hd"
                ],
                "format": "uint8",
                "value": 1,
                "description": "Sensor Index",
                "minValue": 0,
                "maxValue": 30,
                "minStep": 1
              }
            ]
          },
          {
            "iid": 2696,
            "type": "00000086-0000-1000-8000-0026BB765291",
            "characteristics": [
              {
                "type": "00000023-0000-1000-8000-0026BB765291",
                "iid": 2697,
                "perms": [
                  "pr"
                ],
                "format": "string",
                "value": "Presence Sensor 3",
                "description": "Name",
                "maxLen": 64
              },
              {
                "type": "00000071-0000-1000-8000-0026BB765291",
                "iid": 2698,
                "perms": [
                  "pr",
                  "ev"
                ],
                "format": "uint8",
                "value": 0,
                "description": "Occupancy Detected",
                "minValue": 0,
                "maxValue": 1,
                "minStep": 1
              },
              {
                "type": "C8622A33-826A-4DD3-9BE9-D496361F29BB",
                "iid": 2699,
                "perms": [
                  "pr",
                  "hd"
                ],
                "format": "uint8",
                "value": 2,
                "description": "Sensor Index",
                "minValue": 0,
                "maxValue": 30,
                "minStep": 1
              }
            ]
          }

This test device does look like its got a firmware update waiting, so I’ll try that and see if that is the difference.

That’s true. And in fact some even (excuse the pun) use “true” (string) rather than true (boolean) .. but in all cases I follow the common rule 1 == true == “true” == ON == OPEN == Percent.HUNDRED

1 Like