|
|
|
|
@@ -141,8 +141,21 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private static List<HomekitCharacteristicType> getRequiredCharacteristics(HomekitTaggedItem taggedItem) {
|
|
|
|
|
if (taggedItem.getAccessoryType() == BATTERY) {
|
|
|
|
|
final String isChargeable = taggedItem.getConfiguration(HomekitBatteryImpl.BATTERY_TYPE, "false");
|
|
|
|
|
if ("true".equalsIgnoreCase(isChargeable) || "yes".equalsIgnoreCase(isChargeable)) {
|
|
|
|
|
final List<HomekitCharacteristicType> characteristics = new ArrayList<>();
|
|
|
|
|
characteristics.addAll(Arrays.asList(MANDATORY_CHARACTERISTICS.get(taggedItem.getAccessoryType())));
|
|
|
|
|
characteristics.add(BATTERY_CHARGING_STATE);
|
|
|
|
|
return characteristics;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Arrays.asList(MANDATORY_CHARACTERISTICS.get(taggedItem.getAccessoryType()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* creates HomeKit accessory for a openhab item.
|
|
|
|
|
* creates HomeKit accessory for an openhab item.
|
|
|
|
|
*
|
|
|
|
|
* @param taggedItem openhab item tagged as HomeKit item
|
|
|
|
|
* @param metadataRegistry openhab metadata registry required to get item meta information
|
|
|
|
|
@@ -158,12 +171,12 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
HomekitAccessoryUpdater updater, HomekitSettings settings) throws HomekitException {
|
|
|
|
|
final HomekitAccessoryType accessoryType = taggedItem.getAccessoryType();
|
|
|
|
|
logger.trace("Constructing {} of accessory type {}", taggedItem.getName(), accessoryType.getTag());
|
|
|
|
|
final List<HomekitTaggedItem> requiredCharacteristics = getMandatoryCharacteristics(taggedItem,
|
|
|
|
|
final List<HomekitTaggedItem> foundCharacteristics = getMandatoryCharacteristicsFromItem(taggedItem,
|
|
|
|
|
metadataRegistry);
|
|
|
|
|
final HomekitCharacteristicType[] mandatoryCharacteristics = MANDATORY_CHARACTERISTICS.get(accessoryType);
|
|
|
|
|
if ((mandatoryCharacteristics != null) && (requiredCharacteristics.size() < mandatoryCharacteristics.length)) {
|
|
|
|
|
final List<HomekitCharacteristicType> mandatoryCharacteristics = getRequiredCharacteristics(taggedItem);
|
|
|
|
|
if (foundCharacteristics.size() < mandatoryCharacteristics.size()) {
|
|
|
|
|
logger.warn("Accessory of type {} must have following characteristics {}. Found only {}",
|
|
|
|
|
accessoryType.getTag(), mandatoryCharacteristics, requiredCharacteristics);
|
|
|
|
|
accessoryType.getTag(), mandatoryCharacteristics, foundCharacteristics);
|
|
|
|
|
throw new HomekitException("Missing mandatory characteristics");
|
|
|
|
|
}
|
|
|
|
|
AbstractHomekitAccessoryImpl accessoryImpl;
|
|
|
|
|
@@ -171,10 +184,9 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
final @Nullable Class<? extends AbstractHomekitAccessoryImpl> accessoryImplClass = SERVICE_IMPL_MAP
|
|
|
|
|
.get(accessoryType);
|
|
|
|
|
if (accessoryImplClass != null) {
|
|
|
|
|
accessoryImpl = accessoryImplClass
|
|
|
|
|
.getConstructor(HomekitTaggedItem.class, List.class, HomekitAccessoryUpdater.class,
|
|
|
|
|
HomekitSettings.class)
|
|
|
|
|
.newInstance(taggedItem, requiredCharacteristics, updater, settings);
|
|
|
|
|
accessoryImpl = accessoryImplClass.getConstructor(HomekitTaggedItem.class, List.class,
|
|
|
|
|
HomekitAccessoryUpdater.class, HomekitSettings.class)
|
|
|
|
|
.newInstance(taggedItem, foundCharacteristics, updater, settings);
|
|
|
|
|
addOptionalCharacteristics(taggedItem, accessoryImpl, metadataRegistry);
|
|
|
|
|
return accessoryImpl;
|
|
|
|
|
} else {
|
|
|
|
|
@@ -255,7 +267,7 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
* @param metadataRegistry meta data registry
|
|
|
|
|
* @return list of mandatory
|
|
|
|
|
*/
|
|
|
|
|
private static List<HomekitTaggedItem> getMandatoryCharacteristics(HomekitTaggedItem taggedItem,
|
|
|
|
|
private static List<HomekitTaggedItem> getMandatoryCharacteristicsFromItem(HomekitTaggedItem taggedItem,
|
|
|
|
|
MetadataRegistry metadataRegistry) {
|
|
|
|
|
List<HomekitTaggedItem> collectedCharacteristics = new ArrayList<>();
|
|
|
|
|
if (taggedItem.isGroup()) {
|
|
|
|
|
@@ -265,8 +277,7 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
} else {
|
|
|
|
|
addMandatoryCharacteristics(taggedItem, collectedCharacteristics, taggedItem.getItem(), metadataRegistry);
|
|
|
|
|
}
|
|
|
|
|
logger.trace("Mandatory characteristics for item {} characteristics {}", taggedItem.getName(),
|
|
|
|
|
collectedCharacteristics);
|
|
|
|
|
logger.trace("Mandatory characteristics: {}", collectedCharacteristics);
|
|
|
|
|
return collectedCharacteristics;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -285,9 +296,8 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
private static void addMandatoryCharacteristics(HomekitTaggedItem mainItem, List<HomekitTaggedItem> characteristics,
|
|
|
|
|
Item item, MetadataRegistry metadataRegistry) {
|
|
|
|
|
// get list of mandatory characteristics
|
|
|
|
|
HomekitCharacteristicType[] mandatoryCharacteristics = MANDATORY_CHARACTERISTICS
|
|
|
|
|
.get(mainItem.getAccessoryType());
|
|
|
|
|
if ((mandatoryCharacteristics == null) || (mandatoryCharacteristics.length == 0)) {
|
|
|
|
|
List<HomekitCharacteristicType> mandatoryCharacteristics = getRequiredCharacteristics(mainItem);
|
|
|
|
|
if (mandatoryCharacteristics.isEmpty()) {
|
|
|
|
|
// no mandatory characteristics linked to accessory type of mainItem. we are done
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -299,13 +309,12 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
for (Entry<HomekitAccessoryType, HomekitCharacteristicType> accessory : getAccessoryTypes(item,
|
|
|
|
|
metadataRegistry)) {
|
|
|
|
|
// if the item has only accessory tag, e.g. TemperatureSensor,
|
|
|
|
|
// the we will link all mandatory characteristic to this item,
|
|
|
|
|
// then we will link all mandatory characteristic to this item,
|
|
|
|
|
// e.g. we will link CurrentTemperature in case of TemperatureSensor.
|
|
|
|
|
if (isRootAccessory(accessory)) {
|
|
|
|
|
Arrays.stream(mandatoryCharacteristics)
|
|
|
|
|
.forEach(c -> characteristics.add(new HomekitTaggedItem(itemProxy, accessory.getKey(), c,
|
|
|
|
|
mainItem.isGroup() ? (GroupItem) mainItem.getItem() : null,
|
|
|
|
|
HomekitAccessoryFactory.getItemConfiguration(item, metadataRegistry))));
|
|
|
|
|
mandatoryCharacteristics.forEach(c -> characteristics.add(new HomekitTaggedItem(itemProxy,
|
|
|
|
|
accessory.getKey(), c, mainItem.isGroup() ? (GroupItem) mainItem.getItem() : null,
|
|
|
|
|
HomekitAccessoryFactory.getItemConfiguration(item, metadataRegistry))));
|
|
|
|
|
} else {
|
|
|
|
|
// item has characteristic tag on it, so, adding it as that characteristic.
|
|
|
|
|
|
|
|
|
|
@@ -313,7 +322,7 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
|
|
|
|
|
// check whether it is a mandatory characteristic. optional will be added later by another method.
|
|
|
|
|
if (belongsToType(mainItem.getAccessoryType(), accessory)
|
|
|
|
|
&& isMandatoryCharacteristic(mainItem.getAccessoryType(), characteristic)) {
|
|
|
|
|
&& isMandatoryCharacteristic(mainItem, characteristic)) {
|
|
|
|
|
characteristics.add(new HomekitTaggedItem(itemProxy, accessory.getKey(), characteristic,
|
|
|
|
|
mainItem.isGroup() ? (GroupItem) mainItem.getItem() : null,
|
|
|
|
|
HomekitAccessoryFactory.getItemConfiguration(item, metadataRegistry)));
|
|
|
|
|
@@ -373,30 +382,28 @@ public class HomekitAccessoryFactory {
|
|
|
|
|
GroupItem groupItem = (GroupItem) taggedItem.getItem();
|
|
|
|
|
groupItem.getMembers().forEach(item -> getAccessoryTypes(item, metadataRegistry).stream()
|
|
|
|
|
.filter(c -> !isRootAccessory(c)).filter(c -> belongsToType(taggedItem.getAccessoryType(), c))
|
|
|
|
|
.filter(c -> !isMandatoryCharacteristic(taggedItem.getAccessoryType(), c.getValue()))
|
|
|
|
|
.filter(c -> !isMandatoryCharacteristic(taggedItem, c.getValue()))
|
|
|
|
|
.forEach(characteristic -> characteristicItems.put(characteristic.getValue(), (GenericItem) item)));
|
|
|
|
|
} else {
|
|
|
|
|
getAccessoryTypes(taggedItem.getItem(), metadataRegistry).stream().filter(c -> !isRootAccessory(c))
|
|
|
|
|
.filter(c -> !isMandatoryCharacteristic(taggedItem.getAccessoryType(), c.getValue()))
|
|
|
|
|
.filter(c -> !isMandatoryCharacteristic(taggedItem, c.getValue()))
|
|
|
|
|
.forEach(characteristic -> characteristicItems.put(characteristic.getValue(),
|
|
|
|
|
(GenericItem) taggedItem.getItem()));
|
|
|
|
|
}
|
|
|
|
|
logger.trace("Optional characteristics for item {} characteristics {}", taggedItem.getName(),
|
|
|
|
|
characteristicItems);
|
|
|
|
|
logger.trace("Optional characteristics for item {}: {}", taggedItem.getName(), characteristicItems.values());
|
|
|
|
|
return Collections.unmodifiableMap(characteristicItems);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* return true is characteristic is a mandatory characteristic for the accessory.
|
|
|
|
|
*
|
|
|
|
|
* @param accessory accessory
|
|
|
|
|
* @param item item
|
|
|
|
|
* @param characteristic characteristic
|
|
|
|
|
* @return true if characteristic is mandatory, false if not mandatory
|
|
|
|
|
*/
|
|
|
|
|
private static boolean isMandatoryCharacteristic(HomekitAccessoryType accessory,
|
|
|
|
|
HomekitCharacteristicType characteristic) {
|
|
|
|
|
return MANDATORY_CHARACTERISTICS.containsKey(accessory)
|
|
|
|
|
&& Arrays.asList(MANDATORY_CHARACTERISTICS.get(accessory)).contains(characteristic);
|
|
|
|
|
private static boolean isMandatoryCharacteristic(HomekitTaggedItem item, HomekitCharacteristicType characteristic) {
|
|
|
|
|
return MANDATORY_CHARACTERISTICS.containsKey(item.getAccessoryType())
|
|
|
|
|
&& getRequiredCharacteristics(item).contains(characteristic);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|