diff --git a/bundles/org.openhab.io.homekit/README.md b/bundles/org.openhab.io.homekit/README.md index a43a062283fc5..0946541972090 100644 --- a/bundles/org.openhab.io.homekit/README.md +++ b/bundles/org.openhab.io.homekit/README.md @@ -7,6 +7,29 @@ In order to do so, you will need to make some configuration changes. HomeKit organizes your home into "accessories" that are made up of a number of "characteristics". Some accessory types require a specific set of characteristics. +HomeKit integration supports following accessory types: +- Window Covering/Blinds +- Switchable +- Outlet +- Lighting (simple, dimmable, color) +- Fan +- Thermostat +- Heater / Cooler +- Lock +- Security System +- Garage Door Opener +- Valve +- Contact Sensor +- Leak Sensor +- Motion Sensor +- Occupancy Sensor +- Smoke Sensor +- Temperature Sensor +- Humidity Sensor +- Light Sensor +- Carbon Dioxide Sensor +- Carbon Monoxide Sensor + **Attention: Some tags have been renamed. Old style may not be supported in future versions. See below for details.** ## Global Configuration @@ -59,11 +82,11 @@ org.openhab.homekit:maximumTemperature=100 ## Item Configuration -After setting this global configuration, you will need to tag your [openHAB items](https://www.openhab.org/docs/configuration/items.html) for HomeKit in order to map them to an ontology. +After setting the global configuration, you will need to tag your [openHAB items](https://www.openhab.org/docs/configuration/items.html) for HomeKit with accessory type. For our purposes, you may consider HomeKit accessories to be of two types: simple and complex. -A simple accessory will be mapped to a single openHAB item (i.e. Lightbulb is mapped to Switch, Dimmer, or Color item). -A complex accessory will be made up of multiple openHAB items (i.e. Thermostat is composed of mode, and current & target temperature). +A simple accessory will be mapped to a single openHAB item, e.g. HomeKit lighting can represent an openHAB Switch, Dimmer, or Color item. +A complex accessory will be made up of multiple openHAB items, e.g. HomeKit Thermostat can be composed of mode, and current & target temperature. Complex accessories require a tag on a Group Item indicating the accessory type, as well as tags on the items it composes. A HomeKit accessory has mandatory and optional characteristics (listed below in the table). @@ -93,12 +116,11 @@ Switch occupancy_and_motion_sensor "Occupancy and Motion Sensor Tag" {hom The tag can be: - full qualified: i.e. with accessory type and characteristic, e.g. "LeakSensor.LeakDetectedState" -- shorthand version: with only either accessory type or characteristic, .e.g. "LeakSensor", "LeakDetectedState". - +- shorthand version: with only either accessory type or characteristic, e.g. "LeakSensor", "LeakDetectedState". -if shorthand version has only accessory type, then HomeKit integration will automatically link *all* mandatory characteristics of this accessory type to the OpenHab item. -e.g. window covering has 3 mandatory characteristics -and following are identical definitions of window covering +if shorthand version has only accessory type, then HomeKit will automatically link *all* mandatory characteristics of this accessory type to the openHAB item. +e.g. HomeKit window covering has 3 mandatory characteristics: CurrentPosition, TargetPosition, PositionState. +Following are equal configuration: ```xtend Rollershutter window_covering "Window Rollershutter" {homekit="WindowCovering"} @@ -106,13 +128,12 @@ Rollershutter window_covering "Window Rollershutter" {homekit="WindowCoverin ``` If the shorthand version has only a characteristic then it must be a part of a group which has a HomeKit accessory type. - -Complex accessories are defined using group item. The group item must indicated the HomeKit accessory type, e.g. -using tags (in shorthand notation) +You can use openHAB group to define complex accessories. The group item must indicate the HomeKit accessory type, +e.g. LeakSensor definition using tags ```xtend Group gLegacy_leaksensor "Legacy Leak sensor Group" [ "LeakSensor" ] -Switch legacy_leaksensor "Legacy Leak sensor" (gLegacy_Leaksensor) [ "LeakSensor" ] +Switch legacy_leaksensor "Legacy Leak sensor" (gLegacy_Leaksensor) [ "LeakDetectedState" ] Switch legacy_leaksensor_battery "Legacy Leak sensor battery status" (gLegacy_Leaksensor) [ "homekit:BatteryLowStatus" ] ``` @@ -124,9 +145,21 @@ Switch leaksensor "Leak Sensor" Switch leaksensor_battery "Leak Sensor Battery" (gLeakSensor) {homekit="LeakSensor.BatteryLowStatus"} ``` -### Supported Accessories -A full list of supported accessory types can be found in the table *below*. +You can use openHAB group to manage state of multiple items. (see [Group items](https://www.openhab.org/docs/configuration/items.html#derive-group-state-from-member-items)) +In this case, you can assign HomeKit accessory type to the group and to the group items +Following example defines 3 HomeKit accessories of type Lighting: + +- "Light 1" and "Light 2" as independent lights +- "Light Group" that controls "Light 1" and "Light 2" as group + +```xtend +Group:Switch:OR(ON,OFF) gLight "Light Group" {homekit="Lighting"} +Switch light1 "Light 1" (gLight) {homekit="Lighting.OnState"} +Switch light2 "Light 2" (gLight) {homekit="Lighting.OnState"} +``` + +## Supported accessory type | Accessory Tag | Mandatory Characteristics | Optional Characteristics | Supported OH items | Description | |:---------------------|:----------------------------|:-----------------------------|:-------------------------|:-----------------------------------------------------------------| @@ -449,7 +482,7 @@ HomeKit home app sends following commands/update: - On "OFF" event home app sends "OFF" without brightness information. However, some dimmer devices for example do not expect brightness on "ON" event, some others do not expect "ON" upon brightness change. -In order to support different devices HomeKit binding can filter some events. Which events should be filtered is defined via dimmerMode configuration. +In order to support different devices HomeKit integration can filter some events. Which events should be filtered is defined via dimmerMode configuration. ```xtend Dimmer dimmer_light "Dimmer Light" {homekit="Lighting, Lighting.Brightness" [dimmerMode=""]} diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitChangeListener.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitChangeListener.java index 055e8777c5509..4293fe283d78a 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitChangeListener.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitChangeListener.java @@ -215,17 +215,36 @@ public int getConfigurationRevision() { /** * creates one or more HomeKit items for given openhab item. - * one openhab item can linked to several HomeKit accessories or characteristics. - * - * @param item openhab item + * one OpenHAB item can linked to several HomeKit accessories or characteristics. + * OpenHAB Item is a good candidate for homeKit accessory IF + * - it has HomeKit accessory types, i.e. HomeKit accessory tag AND + * - has no group with HomeKit tag, i.e. single line accessory ODER + * - has groups with HomeKit tag, but all groups are with baseItem, e.g. Group:Switch, + * so that the groups already complete accessory and group members can be a standalone HomeKit accessory. + * In contrast, items which are part of groups without BaseItem are additional HomeKit characteristics of the + * accessory defined by that group and dont need to be created as RootAccessory here. + * + * Examples: + * // Single Line HomeKit Accessory + * Switch light "Light" {homekit="Lighting"} + * + * // One HomeKit accessory defined using group + * Group gLight "Light Group" {homekit="Lighting"} + * Switch light "Light" (gLight) {homekit="Lighting.OnState"} + * + * // 2 HomeKit accessories: one is switch attached to group, another one a single switch + * Group:Switch:OR(ON,OFF) gLight "Light Group " {homekit="Lighting"} + * Switch light "Light" (gLight) {homekit="Lighting.OnState"} + * + * @param item openHAB item */ private void createRootAccessories(Item item) { final List> accessoryTypes = HomekitAccessoryFactory .getAccessoryTypes(item, metadataRegistry); final List groups = HomekitAccessoryFactory.getAccessoryGroups(item, itemRegistry, metadataRegistry); - if (!accessoryTypes.isEmpty() && groups.stream().noneMatch(g -> g.getBaseItem() != null)) { - // it has homekit accessory type and is not part of bigger homekit group item without baseItem, i.e. not - // Group:Switch + if (!accessoryTypes.isEmpty() + && (groups.isEmpty() || groups.stream().noneMatch(g -> g.getBaseItem() == null))) { + logger.trace("Item {} is a HomeKit accessory of types {}", item.getName(), accessoryTypes); final HomekitOHItemProxy itemProxy = new HomekitOHItemProxy(item); accessoryTypes.forEach(rootAccessory -> createRootAccessory(new HomekitTaggedItem(itemProxy, rootAccessory.getKey(), HomekitAccessoryFactory.getItemConfiguration(item, metadataRegistry))));