Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[homekit] fix group handling #8058

Merged
merged 4 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -427,7 +460,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