steilerDev / homebridge-openhab2-complete

A homebridge plugin for openHAB, that has the expectation to fully support all Services offered by Apple's Homekit Accessory Protocol (HAP)
GNU General Public License v3.0
53 stars 16 forks source link

Homebridge Plugin for OpenHAB2 - Complete Edition (works also with OpenHAB3!)

NPM

This homebridge plugin for openHAB fully supports all services offered by Apple's HomeKit Accessory Protocol (HAP), as far as it is feasible based on the item types offered by OpenHAB (see below for the currently supported 32 accessories). In opposite to the existing openHAB homebridge plugin or the native openHAB Homekit Plugin, this plugin requires explicit declaration of accessories in the homebridge configuration and does not use openHAB's tagging system, which leads to a little more effort during configuration, but proves more reliable and functional in more complex installations. See Comparisson below.

Preface

Since the native HomeKit integration of OpenHAB has significantly improved (still lacking some of the available Service of this plugin), I don't think there is much value in this plugin.

After testing openHAB3's HomeKit integration for a week, I decided to move back to homebridge, due to the instability of openHAB's implementation.

As part of my OpenHAB 3 migration I updated the code to support OH3, finally put some bug fixes that happened over the last year into the release and replaced the depricated request package.

To pull the Github version:

npm install -g -f steilerDev/homebridge-openhab2-complete#master

Installation

Note: Please install homebridge first.

npm install -g homebridge-openhab2-complete

Some people are experiencing dependency issues between homebridge's node version and the required node version for this project. My local setup is based on oznu's homebridge docker container, where I never ran into any problems. In order to install the plugin in the docker, just add npm install homebridge-openhab2-complete to the startup.sh script inside the mapped docker volume.

Configuration

This is a platform plugin, that will register all accessories within the Bridge provided by homebridge. The following shows the general homebridge configuration (config.json), see the Supported HAP Services below, in order to get the detailed configuration for each service.

{
    "bridge": {
        ...
    },

    "accessories": [
        ...
    ],

    "platforms": [
        {
            "platform": "openHAB2-Complete",
            "host": "http://192.168.0.100",
            "port": "8080",
            "username": "homebridge",
            "password": "homebridge",
            "accessories": [
                {
                    "name": "An items name, as shown in Homekit later",
                    "type": "switch",
                    "item": "Itemname-within-OpenHAB"
                },
                ...
            ]
        },
        ...
    ]
}

Alternatively you can group accessories of the same type in a sub-array:

...
    "platforms": [
        {
            ...
            "accessories": [
                {
                    "type": "switch",
                    "items": [
                        {
                            "name": "An items name, as shown in Homekit later",
                            "item": "Itemname-within-OpenHAB"
                        },
                        {
                            "name": "An items name, as shown in Homekit later",
                            "item": "Itemname-within-OpenHAB"
                        },
                        ...
                    ]
                },
                ...
            ]
        },
...

Supported HAP Services

The following is a list of all services that are currently supported and which values are required within the accessory configuration. Every accessory needs a name (as shown in HomeKit later) and a type. The combination of name and type needs to be unique and should not change in the hombridge configuration (you can safely rename the item within the Home.app after adding them). Changing name or type in the config will change the item's serial number, which would be registered as a new/different one.

The following services are also defined by the HomeKit protocol, but since I don't know a good way to map them to openHAB items, I currently don't plan to implement them. Let me know if you have any ideas, by opening an issue!

Configuration for every accessory

Grouping

Since iOS 13 multiple accessories can be grouped within a single accessory. This can be -as far as I have tested- done in an arbitrary way. The syntax to define a grouped item is as follows:

{
    {
        "type": "group",
        "name": "Group Name",
        "model": "Group Type Model",
        "batteryItem": "Itemname-within-OpenHAB",
        "batteryItemThreshold": "20",
        "items": [
            {
                "type": "homebridge-openhab2-complete item type",
                "name": "An items name, as shown in Homekit later",
                "item": "Itemname-within-OpenHAB"
            }, 
            {
                "type": "homebridge-openhab2-complete item type",
                "items": [
                    {
                        "name": "An items name, as shown in Homekit later",
                        "item": "Itemname-within-OpenHAB",
                    },
                    {
                        ...
                    }
                ]
            }
        ]
    }
}

Battery Levels and Warnings

Every accessory can be configured to show battery warnings and battery levels. The following configuration can be optionally added to every item:

{
    "batteryItem": "Itemname-within-OpenHAB",
    "batteryItemThreshold": "10",
    "batteryItemInverted": "false",
    "batteryItemChargingState": "Itemname-within-OpenHAB",
    "batteryItemChargingStateInverted": "false"
}

Available accessory types

Lightbulb

This service describes a lightbulb.

{
    "name": "An items name, as shown in Homekit later",
    "type": "light",
    "item": "Itemname-within-OpenHAB",
    "sendOnOnlyWhenOff": "false"
}

Fan

This service describes a fan.

{
    "name": "An items name, as shown in Homekit later",
    "type": "fan",
    "item": "Itemname-within-OpenHAB"
}

Security System

This service describes a security system.

{
    "name": "An items name, as shown in Homekit later",
    "type": "security",
    "item": "Itemname-within-OpenHAB"
}

Thermostat

This service describes a thermostat.

Important notes on Thermostat Capabilities

Important notes on Thermostat Capabilities

{
    "name": "An items name, as shown in Homekit later",
    "type": "thermostat",
    "currentTempItem": "Itemname-within-OpenHAB",
    "targetTempItem": "Itemname-within-OpenHAB",
    "currentHumidityItem": "Itemname-within-OpenHAB",
    "targetHumidityItem": "Itemname-within-OpenHAB",
    "heatingItem": "Itemname-within-OpenHAB",
    "coolingItem": "Itemname-within-OpenHAB",
    "tempUnit": "Celsius",
    "heatingThresholdTempItem": "Itemname-within-OpenHAB",
    "coolingThresholdTempItem": "Itemname-within-OpenHAB",
    "modeItem": "Itemname-within-OpenHAB",
    "modeItemCapability": "HeatingCooling",
    "minTemp": "-100",
    "maxTemp": "200",
    "minTempStep": "0.1"
}

Humidifier/Dehumidifier

This service describes a humidifier and/or dehumidifier accessory.

{
    "name": "An items name, as shown in Homekit later",
    "type": "humidifier",
    "currentHumidityItem": "Itemname-within-OpenHAB",
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "humidifierItem": "Itemname-within-OpenHAB",
    "dehumidifierItem": "Itemname-within-OpenHAB",
    "modeItem": "Itemname-within-OpenHAB",
    "humidifierThresholdItem": "Itemname-within-OpenHAB",
    "dehumidifierThresholdItem": "Itemname-within-OpenHAB",
    "waterLevelItem": "Itemname-within-OpenHAB",
    "swingItem": "Itemname-within-OpenHAB",
    "swingItemInverted": "false",
    "rotationSpeedItem": "Itemname-within-OpenHAB",
    "minFanSpeed": "0",
    "maxFanSpeed": "100",
    "minFanStep": "1"
}

Heater/Cooler

This service describes a heater and/or cooler accessory.

Important notes on Heater/Cooler

The Heater/Cooler implementation within HomeKit clashes with OpenHAB. The Heater/Cooler is usable but there might be bugs around the mode. If the swing item and rotation speed item are not required, it is recommended to use the Thermostat Service!

Important notes on Heater/Cooler

{
    "name": "An items name, as shown in Homekit later",
    "type": "heatercooler",
    "currentTempItem": "Itemname-within-OpenHAB",
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "heatingItem": "Itemname-within-OpenHAB",
    "coolingItem": "Itemname-within-OpenHAB",
    "modeItem": "Itemname-within-OpenHAB",
    "heatingThresholdTempItem": "Itemname-within-OpenHAB",
    "coolingThresholdTempItem": "Itemname-within-OpenHAB",
    "swingItem": "Itemname-within-OpenHAB",
    "swingItemInverted": "false",
    "rotationSpeedItem": "Itemname-within-OpenHAB",
    "tempUnit": "Celsius",
    "minTemp": "-100",
    "maxTemp": "200",
    "minTempStep": "0.1",
    "minFanSpeed": "0",
    "maxFanSpeed": "100",
    "minFanStep": "1"
}

Air Purifier

This service describes an air purifier accessory.

{
    "name": "An items name, as shown in Homekit later",
    "type": "airpurifier",
    "purifyingItem": "Itemname-within-OpenHAB",
    "modeItem": "Itemname-within-OpenHAB",
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "swingItem": "Itemname-within-OpenHAB",
    "swingItemInverted": "false",
    "rotationSpeedItem": "Itemname-within-OpenHAB",
    "minFanSpeed": "0",
    "maxFanSpeed": "100",
    "minFanStep": "1"
}

Speaker

This service is used to control the audio output settings on a speaker device.

Note: Even though Speaker is part of Apple's HAP specification, this accessory is shown as "not supported" in the Home app.

{
    "name": "An items name, as shown in Homekit later",
    "type": "speaker",
    "muteItem": "Itemname-within-OpenHAB",
    "muteItemInverted": "true",
    "volumeItem": "Itemname-within-OpenHAB"

}

Microphone

This service is used to control the audio input settings on an audio device (primarily used for microphones).

Note: Even though Microphone is part of Apple's HAP specification, this accessory is shown as "not supported" in the Home app.

{
    "name": "An items name, as shown in Homekit later",
    "type": "microphone",
    "muteItem": "Itemname-within-OpenHAB",
    "muteItemInverted": "true",
    "volumeItem": "Itemname-within-OpenHAB"

}

Valve

This service describes a generic valve or a specific Faucet, Irigation System or Showerhead.

{
    "name": "An items name, as shown in Homekit later",
    "type": "valve",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true",
    "inUseItem": "Itemname-within-OpenHAB",
    "inUseItemInverted": "true",
    "durationItem": "Itemname-within-OpenHAB",
    "valveType": "generic"
}

Window Covering

This service describes motorized window coverings or shades - examples include shutters, blinds, awnings etc.

{
    "name": "An items name, as shown in Homekit later",
    "type": "windowcovering", 
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "multiplier": "1",
    "stateItem": "Itemname-within-OpenHAB",
    "stateItemInverted": "false",
    "stateItemMultiplier": "1",
    "manuMode": "false",
    "horizontalTiltItem": "Itemname-within-OpenHAB",
    "horizontalTiltItemRangeStart": "-90",
    "horizontalTiltItemRangeEnd": "90",
    "verticalTiltItem": "Itemname-within-openHAB",
    "verticalTiltItemRangeStart": "-90",
    "verticalTiltItemRangeEnd": "90"
}

Door

This service describes a motorized door

{
    "name": "An items name, as shown in Homekit later",
    "type": "door", 
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "multiplier": "1",
    "stateItem": "Itemname-within-OpenHAB",
    "stateItemInverted": "false",
    "stateItemMultiplier": "1",
    "manuMode": "false"
}

Window

This service describes a motorized window

{
    "name": "An items name, as shown in Homekit later",
    "type": "window", 
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "multiplier": "1",
    "stateItem": "Itemname-within-OpenHAB",
    "stateItemInverted": "false",
    "stateItemMultiplier": "1",
    "manuMode": "false"
}

Lock Mechanism

The HomeKit Lock Mechanism service is designed to expose and control the physical lock mechanism on a device.

{
    "name": "An items name, as shown in Homekit later",
    "type": "lock", 
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "stateItem": "Itemname-within-OpenHAB",
    "stateItemInverted": "false"
}

Garage Door Opener

This service describes a garage door opener tat controls a single door. If a garage has more than one door, then each door should have its own Garage Door Opener Service.

{
    "name": "An items name, as shown in Homekit later",
    "type": "garage", 
    "item": "Itemname-within-OpenHAB",
    "inverted": "false",
    "multiplier": "1",
    "stateItem": "Itemname-within-OpenHAB",
    "stateItemInverted": "false",
    "stateItemMultiplier": "1",
    "obstructionItem": "Itemname-within-OpenHAB",
    "obstructionItemInverted": "false"
}

Slat

This service describes a slat which tilts on a vertical or a horizontal axis.

Note: Even though Slat is part of Apple's HAP specification, this accessory is shown as "not supported" in the Home app.

{
    "name": "An items name, as shown in Homekit later",
    "type": "slat",
    "stateItem": "Itemname-within-OpenHAB",
    "stateItemInverted": "false",
    "item": "Itemname-within-OpenHAB",
    "itemRangeStart": "itemRangeStart",
    "itemRangeEnd": "itemRangeEnd",
    "slatType": "horizontal"
}

Temperature Sensor

This service describes a temperature sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "temp",
    "currentTempItem": "Itemname-within-OpenHAB",
    "tempUnit": "Celsius",
    "minTemp": "-100",
    "maxTemp": "200",
    "minTempStep": "0.1"
}

Humidity Sensor

This service describes a humidity sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "humidity",
    "item": "Itemname-within-OpenHAB"
}

Light Sensor

This service describes a light sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "lux",
    "item": "Itemname-within-OpenHAB"
}

Air Quality Sensor

This service describes an air quality sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "air",
    "item": "Itemname-within-OpenHAB"
}

Switch

This service describes a binary switch.

{
    "name": "An items name, as shown in Homekit later",
    "type": "switch",
    "item": "Itemname-within-OpenHAB",
    "inverted": "false"
}

Outlet

This service describes an outlet.

{
    "name": "An items name, as shown in Homekit later",
    "type": "outlet",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true",
    "inUseItem": "Itemname-within-OpenHAB",
    "inUseItemInverted": "false"
}

Motion Sensor

This service describes a motion sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "motion",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true"
}

Occupancy Sensor

This service describes an occupancy sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "occupancy",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true"
}

Leak Sensor

This service describes a leak sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "leak",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true"
}

Carbon Monoxide Sensor

This service describes a carbon monoxide sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "co",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true",
    "levelItem": "Itemname-within-OpenHAB"
}

Carbon Dioxide Sensor

This service describes a carbon dioxide sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "co2",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true",
    "levelItem": "Itemname-within-OpenHAB"
}

Contact Sensor

This service describes a contact sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "contact",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true"
}

Smoke Sensor

This service describes a smoke sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "smoke",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true"
}

Filter Maintenance Sensor

This service describes a filter maintenance sensor.

{
    "name": "An items name, as shown in Homekit later",
    "type": "filter",
    "item": "Itemname-within-OpenHAB",
    "inverted": "true",
    "levelItem": "Itemname-within-OpenHAB"
}

Additional Services & Notes from the Developer

Obviously the aim of this project is a full coverage of the HAP specification. Due to the limitations of smart devices in my home I can only test a subset and would love to have your feedback and input for this project.

Due to the very limited documentation on homebridge plugin development I have not implemented a dynamic platform (there is only this partly complete wiki entry). If anyone of you knows how to do it, please contact me directly!

If you have feedback or suggestions how to better represent the services as openHAB Items, feel free to open an issue.

Contribute & Add new service/accessory

If you would like to contribute just send me a pull request. In order to add a new service you have to modify/add the following parts:

  1. Create your own accessory class within ./accessory
  2. The only required functions are getServices() (returning an array of HAP.Service with attached HAP.Characteristic) and identify() (which does not need to do anything). Those are implemented in the Accessory super class and don't need to be overridden. Make sure that this._services is populated and reflects your service
  3. Define const type = "YourTypeName" (this will be used inside config.json to identify an accessory of your type) and function createAccessory(platform, config) returning an instance of your Accessory.
  4. Finally expose type and createAccessory through module.exports = {type, createAccessory}

My accessories are using centrally defined characteristics inside ./accessory/characteristic. See NumericSensor.js for a simple characteristic implementation and TemperatureSensor.js for a simple accessory using this characteristic. This is not a requirement, but highly recommended.

Connecting to HTTPS openHAB instances

To connect to a server with a self-signed certificate, you have to add that certificate or your own Certificate Authority to NodeJS.

When using Docker, this can be accomplished by putting the .crt file in a mounted directory (e.g. /homebridge) and setting the Docker enviroment variable NODE_EXTRA_CA_CERTS=/homebridge/ca.crt (e.g. in docker-compose.yml under environment).

Example docker-compose.yml:

version: '2'
services:
  homebridge:
    image: oznu/homebridge:ubuntu
    restart: always
    network_mode: host
    environment:
      - PGID=1000
      - PUID=1000
      - HOMEBRIDGE_CONFIG_UI=1
      - HOMEBRIDGE_CONFIG_UI_PORT=8581
      - TZ=Berlin/Germany
      - NODE_EXTRA_CA_CERTS=/homebridge/CA.crt
    volumes:
      - ./data:/homebridge

Acknowledgments

First of all, a massive thank you to all the users of this plugin, seeing so many positive responses to my work keeps me going and improving!

A couple of people helped me test this piece of software, by opening issues, pointing me into new and interesting directions and showing me ways to improve this plugin. A couple of them are very persistent and I want to thank you guys: