Skip to content

Commit

Permalink
[homekit] fix group handling (openhab#8058)
Browse files Browse the repository at this point in the history
* fix group handling

Signed-off-by: Eugen Freiter <[email protected]>
Signed-off-by: CSchlipp <[email protected]>
  • Loading branch information
yfre authored and CSchlipp committed Jul 26, 2020
1 parent 5e24f7e commit d05c9f5
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 21 deletions.
63 changes: 48 additions & 15 deletions bundles/org.openhab.io.homekit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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).
Expand Down Expand Up @@ -93,26 +116,24 @@ 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"}
Rollershutter window_covering "Window Rollershutter" {homekit="WindowCovering, WindowCovering.CurrentPosition, WindowCovering.TargetPosition, WindowCovering.PositionState"}
```

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" ]
```

Expand All @@ -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 |
|:---------------------|:----------------------------|:-----------------------------|:-------------------------|:-----------------------------------------------------------------|
Expand Down Expand Up @@ -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="<mode>"]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Entry<HomekitAccessoryType, HomekitCharacteristicType>> accessoryTypes = HomekitAccessoryFactory
.getAccessoryTypes(item, metadataRegistry);
final List<GroupItem> 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))));
Expand Down

0 comments on commit d05c9f5

Please sign in to comment.