Supereg / homebridge-http-switch

Powerful http switch for Homebridge: https://github.com/homebridge/homebridge
ISC License
218 stars 36 forks source link
hap homebridge homebridge-http homebridge-plugin homekit http http-switch javascript mqtt mqtt-smarthome notifications regex switch toggle-switch

homebridge-http-switch Plugin

npm npm GitHub Workflow Status GitHub issues GitHub pull requests

homebridge-http-switch is a Homebridge plugin with which you can configure HomeKit switches which forward any requests to a defined http server. This comes in handy when you already have home automated equipment which can be controlled via http requests. Or you have built your own equipment, for example some sort of lightning controlled with an wifi enabled Arduino board which than can be integrated via this plugin into Homebridge.

homebridge-http-switch supports three different type of switches. A normal stateful switch and two variants of stateless switches (stateless and stateless-reverse) which differ in their original position. For stateless switches you can specify multiple urls to be targeted when the switch is turned On/Off.
More about on how to configure such switches can be read further down.

Installation

First of all you need to have Homebridge installed. Refer to the repo for instructions.
Then run the following command to install homebridge-http-switch

sudo npm install -g homebridge-http-switch

Updating the switch state in HomeKit

The 'On' characteristic from the 'switch' service has the permission to notify the HomeKit controller of state changes. homebridge-http-switch supports two ways to send state changes to HomeKit.

The 'pull' way:

The 'pull' way is probably the easiest to set up and supported in every scenario. homebridge-http-switch requests the state of the switch in an specified interval (pulling) and sends the value to HomeKit.
Look for pullInterval in the list of configuration options if you want to configure it.

The 'push' way:

When using the 'push' concept, the http device itself sends the updated value to homebridge-http-switch whenever the value changes. This is more efficient as the new value is updated instantly and homebridge-http-switch does not need to make needless requests when the value didn't actually change.
However because the http device needs to actively notify the homebridge-http-switch there is more work needed to implement this method into your http device.

Using MQTT:

MQTT (Message Queuing Telemetry Transport) is a protocol widely used by IoT devices. IoT devices can publish messages on a certain topic to the MQTT broker which then sends this message to all clients subscribed to the specified topic. In order to use MQTT you need to setup a broker server (mosquitto is a solid open source MQTT broker running perfectly on a device like the Raspberry Pi) and then instruct all clients to publish/subscribe to it.
For shelly.cloud devices mqtt is the best and only option to implement push-updates.

Using 'homebridge-http-notification-server':

For those of you who are developing the http device by themselves I developed a pretty simple 'protocol' based on http to send push-updates.
How to implement the protocol into your http device can be read in the chapter Notification Server

Configuration:

The configuration can contain the following properties:

Basic configuration options:

Advanced configuration options:

Below are two example configurations. One is using simple string urls and the other is using simple urlObjects.
Both configs can be used for a basic plugin configuration.

{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Switch",

          "switchType": "stateful",

          "onUrl": "http://localhost/api/switchOn",
          "offUrl": "http://localhost/api/switchOff",

          "statusUrl": "http://localhost/api/switchStatus"
        }   
    ]
}
{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Switch",

          "switchType": "stateful",

          "onUrl": {
            "url": "http://localhost/api/switchOn",
            "method": "GET"
          },
          "offUrl": {
            "url": "http://localhost/api/switchOff",
            "method": "GET"
          },

          "statusUrl": {
            "url": "http://localhost/api/switchStatus",
            "method": "GET"
          }
        }   
    ]
}

UrlObject

A urlObject can have the following properties:

Below is an example of an urlObject containing the basic properties:

{
  "url": "http://example.com:8080",
  "method": "GET",
  "body": "exampleBody",

  "strictSSL": false,

  "auth": {
    "username": "yourUsername",
    "password": "yourPassword"
  },

  "headers": {
    "Content-Type": "text/html"
  }
}

MQTTObject

A mqttObject can have the following properties:

Basic configuration options:
Advanced configuration options:

Below is an example of an mqttObject containing the basic properties for a switch service:

{
  "host": "127.0.0.1",
  "port": 1883,

  "credentials": {
    "username": "yourUsername",
    "password": "yourPassword"
  },

  "subscriptions": [
    {
      "topic": "your/topic/here",
      "characteristic": "On",
      "messagePattern": "on"
    }
  ]
}

Stateless Switch

Since OFF is the only possible state you do not need to declare offUrl and statusUrl

{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Switch",

          "switchType": "stateless",

          "timeout": 1000,

          "onUrl": "http://localhost/api/switchOn"
        }   
    ]
}  

Reverse Stateless Switch

Since ON is the only possible state you do not need to declare onUrl and statusUrl

{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Switch",

          "switchType": "stateless-reverse",

          "timeout": 1000,

          "offUrl": "http://localhost/api/switchOff"
        }   
    ]
}

Multiple On or Off Urls

If you wish to do so you can specify an array of urls or urlObjects (onUrl or offUrl) when your switch is a stateless switch or a reverse-stateless switch.
This is not possible with a normal stateful switch.

Below are two example configurations of an stateless switch with three urls. One is using simple string array and the other is using simple urlObject arrays.

{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Switch",

          "switchType": "stateless",
          "onUrl": [
            "http://localhost/api/switch1On",
            "http://localhost/api/switch2On",
            "http://localhost/api/switch3On"
          ]
        }   
    ]
}
{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Switch",

          "switchType": "stateless",
          "onUrl": [
            {
              "url": "http://localhost/api/switch1On"
            },
            {
              "url": "http://localhost/api/switch2On"
            },
            {
              "url": "http://localhost/api/switch3On"
            }
          ]
        }   
    ]
}

The 'delay(...)' url

When using multiple urls and "series" as multipleUrlExecutionStrategy you can also specify so called delay urls in the onUrl or offUrl arrays. This could be used to guarantee a certain delay between two urls.
The delay url has the following pattern: "delay(INTEGER)" where 'INTEGER' is replaced with the delay in milliseconds.

Here is an example:

{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Delayed Switch",

          "switchType": "stateless",
          "multipleUrlExecutionStrategy": "series",

          "onUrl": [
            "http://localhost/api/switch1On",
            "delay(1000)",
            "http://localhost/api/switch2On"
          ]
        }   
    ]
}

Examples for custom statusPatterns

The statusPattern property can be used to change the phrase which is used to identify if the switch should be turned on or off. So when you want the switch to be turned on when your server sends "true" in the body of the http response you could specify the following pattern:

{
    "statusPattern": "true"
}

However using Regular Expressions much more complex patterns are possible. Let's assume your http enabled device responds with the following json string as body, where one property has an random value an the other indicates the status of the switch:

{
    "perRequestRandomValue": 89723789,
    "switchState": true
}

Then you could use the following pattern:

{
    "statusPattern": "{\n    \"perRequestRandomValue\": [0-9]+,\n    \"switchState\": true\n}"
}

Note: The statusPattern must be placed on the same level as the statusUrl property, not inside the statusUrl object. See below for example.

{
    "statusUrl": {
     },
    "statusPattern": "....",
}

More on how to build regex patterns: https://www.w3schools.com/jsref/jsref_obj_regexp.asp

Notification Server

homebridge-http-switch can be used together with homebridge-http-notification-server in order to receive updates when the state changes at your external program. For details on how to implement those updates and how to install and configure homebridge-http-notification-server, please refer to the README of the repository first.

Down here is an example on how to configure homebridge-http-switch to work with your implementation of the homebridge-http-notification-server.

{
    "accessories": [
        {
          "accessory": "HTTP-SWITCH",
          "name": "Switch",

          "notificationID": "my-switch",
          "notificationPassword": "superSecretPassword",

          "onUrl": "http://localhost/api/switchOn",
          "offUrl": "http://localhost/api/switchOff",

          "statusUrl": "http://localhost/api/switchStatus"
        }   
    ]
}

To get more details about the configuration have a look at the README.

Available characteristics (for the POST body)

Down here are all characteristics listed which can be updated with an request to the homebridge-http-notification-server