From 2bab993776c946827c1a0920f0157c44dd32c5d4 Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Mon, 8 Aug 2022 01:47:26 -0600 Subject: [PATCH] [homekit] fix collecting characteristics that don't belong to a complex accessory (#13233) given: ``` Group eThermostat { homekit="Thermostat" } Number:Temperature Thermostat_AmbTemp (eThermostat) { homekit="CurrentTemperature" } Number:Temperature Thermostat_SetTemp (eThermostat) { homekit="TargetTemperature" } Group gThermostatZoneContacts // in reality there are multiple thermostats and multiple of these groups, // so that a rule on members of gThermostatZoneContacts can find the related // thermostat to turn it off when a window is open Group:Contact:OR(OPEN,CLOSED) gWindows (eThermostat, gThermostatZoneContacts) Contact Window_Contact (gWindows) { homekit="ContactSensor" } ``` When constructing the Thermostat accessory for eThermostat, detects the Window_Contact as a mandatory characteristic, because it's a base accessory in a nested group. This leads to lots of warnings about the temperature value of a contact item being out of range. The fix is two-fold - first of all, there's no reason to search nested groups for characteristics of a complex accessory. Second of all, even if for some reason you were to nest an accessory in an accessory, the nested accessory does not actually belong to the outer accessory, so don't add it as a mandatory characteristic of the outer. I suspect there's still one more bug, because AbstractHomekitAccessoryImpl. getCharacteristic(HomekitCharacteristicType.CURRENT_TEMPERATURE) was returning Window_Contact, which is only tagged as a ContactSensor. But after fixing the above two bugs, it was no longer reproducible, and I didn't continue digging. Signed-off-by: Cody Cutrer --- .../internal/accessories/HomekitAccessoryFactory.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java index a9d1b0d350728..139940c43b15c 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitAccessoryFactory.java @@ -272,7 +272,7 @@ private static List getMandatoryCharacteristicsFromItem(Homek MetadataRegistry metadataRegistry) { List collectedCharacteristics = new ArrayList<>(); if (taggedItem.isGroup()) { - for (Item item : ((GroupItem) taggedItem.getItem()).getAllMembers()) { + for (Item item : ((GroupItem) taggedItem.getItem()).getMembers()) { addMandatoryCharacteristics(taggedItem, collectedCharacteristics, item, metadataRegistry); } } else { @@ -312,7 +312,9 @@ private static void addMandatoryCharacteristics(HomekitTaggedItem mainItem, List // if the item has only accessory tag, e.g. TemperatureSensor, // then we will link all mandatory characteristic to this item, // e.g. we will link CurrentTemperature in case of TemperatureSensor. - if (isRootAccessory(accessory)) { + // Note that accessories that are members of other accessories do _not_ + // count - we're already constructing another root accessory. + if (isRootAccessory(accessory) && mainItem.getItem().equals(item)) { mandatoryCharacteristics.forEach(c -> characteristics.add(new HomekitTaggedItem(itemProxy, accessory.getKey(), c, mainItem.isGroup() ? (GroupItem) mainItem.getItem() : null, HomekitAccessoryFactory.getItemConfiguration(item, metadataRegistry))));