Home app shows identical bridged Matter compound devices (Thermostat + Fan) as different tiles — how is the primary service chosen?

Hi!

We build a Matter bridge that exposes air conditioners as compound devices, following Device Library §2.5.6 "Separate Endpoints":

Aggregator → Bridged Node (no application device type) → Thermostat (0x0301) + Fan (0x002B)

In the Home app some of these accessories appear as a Thermostat tile and others as a Fan tile, even when the devices are identical. A matter.js test bridge with 5 identical devices gave 1 Thermostat / 4 Fan tiles on Matter 1.5.1 and the same on 1.6.0. Removing and re-adding our ESP32 bridge, with no firmware change, swapped which device was shown as a Fan.

Putting the Thermostat device type on the Bridged Node endpoint itself, with the Fan as its child, gave 3 Thermostat / 2 Fan, so that is not stable either (and Device Library 1.5 §2.5.6 does not allow it).

The home hub log (homed, hmmtr.protocolmap) shows "Multiple primary service candidates found" for each of these devices; the chosen service is redacted.

Questions:

  1. How does Home choose the primary service for a bridged compound device?
  2. Is there a supported way for the accessory to indicate which endpoint is primary (order in PartsList, TagList, something else)?
  3. Is a single endpoint with Thermostat plus an extra Fan Control server cluster the recommended layout for Apple Home instead?

Filed as FB25263651.

Environment: iPhone with iOS 27.0.1, Apple TV home hub with tvOS 27.0.

Answered by DTS Engineer in 912559022

SO, let me start with what's going on here:

In the Home app, some of these accessories appear as a Thermostat tile and others as a Fan tile, even when the devices are identical.

The first thing I'd suggest here is building and running our "Interacting with a home automation network.” That sample lets you see and manipulate the actual HomeKit objects, which can be very helpful for understanding what's actually happening. In this particular case, what you'll find is going on here:

...A matter.js test bridge with 5 identical devices gave 1 Thermostat / 4 Fan tiles on Matter 1.5.1 and the same on 1.6.0. Removing and re-adding our ESP32 bridge, with no firmware change, swapped which device was shown as a Fan.

Is that those two cases AREN'T the same in HomeKit. One of them is using "Thermostat" while the other is using "Heater/Cooler.” For the backstory on why HomeKit has two different accessory types for this, take a look at this forum post. In any case, that split then leads to here:

The home hub log (homed, hmmtr.protocolmap) shows "Multiple primary service candidates found" for each of these devices; the chosen service is redacted.

When multiple primary service candidates are found with equivalent priority, HomeKit falls back to sorting based on their service UUID values. Unfortunately, the ordering of those values:

  1. Thermostat -> 0x4A
  2. Fan -> 0xB7
  3. Heater/Cooler -> 0xBC

...is what then causes the "flipping" you're seeing. However, it also points toward a bigger issue— the main functional difference between "Thermostat" and "Heater/Cooler" is that "Heater/Cooler" does NOT have an "Auto" mode. That means HomeKit is either presenting an Auto mode you don't have or failing to present an auto mode you do have, either of which is a problem.

What I can't explain is why it's not getting a consistent result here. That's coming from your Accessories FeatureMap, so it should be getting the same value each time.

Covering other questions:

Is there a supported way for the accessory to indicate which endpoint is primary (order in PartsList, TagList, something else)?

No, not really. HomeKit has its own system for this, and that should be resolving this more "directly,” but you can't really affect it.

Is a single endpoint with Thermostat plus an extra Fan Control server cluster the recommended layout for Apple Home instead?

We haven't provided formal guidance on this. You could solve this using multiple endpoints; however, I think the "flipping" between Thermostat and Heater/Cooler would still be a problem, just more subtle.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

SO, let me start with what's going on here:

In the Home app, some of these accessories appear as a Thermostat tile and others as a Fan tile, even when the devices are identical.

The first thing I'd suggest here is building and running our "Interacting with a home automation network.” That sample lets you see and manipulate the actual HomeKit objects, which can be very helpful for understanding what's actually happening. In this particular case, what you'll find is going on here:

...A matter.js test bridge with 5 identical devices gave 1 Thermostat / 4 Fan tiles on Matter 1.5.1 and the same on 1.6.0. Removing and re-adding our ESP32 bridge, with no firmware change, swapped which device was shown as a Fan.

Is that those two cases AREN'T the same in HomeKit. One of them is using "Thermostat" while the other is using "Heater/Cooler.” For the backstory on why HomeKit has two different accessory types for this, take a look at this forum post. In any case, that split then leads to here:

The home hub log (homed, hmmtr.protocolmap) shows "Multiple primary service candidates found" for each of these devices; the chosen service is redacted.

When multiple primary service candidates are found with equivalent priority, HomeKit falls back to sorting based on their service UUID values. Unfortunately, the ordering of those values:

  1. Thermostat -> 0x4A
  2. Fan -> 0xB7
  3. Heater/Cooler -> 0xBC

...is what then causes the "flipping" you're seeing. However, it also points toward a bigger issue— the main functional difference between "Thermostat" and "Heater/Cooler" is that "Heater/Cooler" does NOT have an "Auto" mode. That means HomeKit is either presenting an Auto mode you don't have or failing to present an auto mode you do have, either of which is a problem.

What I can't explain is why it's not getting a consistent result here. That's coming from your Accessories FeatureMap, so it should be getting the same value each time.

Covering other questions:

Is there a supported way for the accessory to indicate which endpoint is primary (order in PartsList, TagList, something else)?

No, not really. HomeKit has its own system for this, and that should be resolving this more "directly,” but you can't really affect it.

Is a single endpoint with Thermostat plus an extra Fan Control server cluster the recommended layout for Apple Home instead?

We haven't provided formal guidance on this. You could solve this using multiple endpoints; however, I think the "flipping" between Thermostat and Heater/Cooler would still be a problem, just more subtle.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware