Sign Up for Free

RunKit +

Try any Node.js package right in your browser

This is a playground to test code. It runs a full Node.js environment and already has all of npm’s 400,000 packages pre-installed, including homebridge-mqtt with all npm packages installed. Try it out:

var homebridgeMqtt = require("homebridge-mqtt")

This service is provided by RunKit and is not affiliated with npm, Inc or the package authors.

homebridge-mqtt v0.6.2

MQTT Plugin for Homebridge

homebridge-mqtt

NPM version

Homebridge-mqtt is a Plugin for Homebridge. The design is based on MVC pattern, have a look at homebridge-mvc. Homebridge-mqtt is a dynamic Plugin that allows you to add and control accessories from a "Bridge" or "Device" with a mqtt API. Node-RED is the perfect platform to use with homebridge-mqtt.

Note-RED is a visual tool for wiring together hardware devices, APIs and online services.

Installation

If you are new to Homebridge, please first read the documentation to install Homebridge.

Install homebridge-mqtt:

sudo npm install -g homebridge-mqtt

Configuration

Add the mqtt-platform in config.json in your home directory inside .homebridge.

{
  "platform": "mqtt",
  "name": "mqtt",
  "url": "mqtt://127.0.0.1"
}

Replace 127.0.0.1 with the ip-address of your mqtt broker.

Optional Settings

Only add the optional settings if you need them.

{
  ...
  "port": "1883",
  "topic_type": "multiple",
  "topic_prefix": "homebridge",
  "username": "foo",
  "password": "bar",
  "cert": "/path/to/certificate.pem",
  "key": "path/to/key.pem",
  "ca": "/path/to/ca_certificate.pem",
  "qos": 1
}

Note:

topic_type multiple: the data is sent to all devices, e.g.

topic : homebridge/from/set

topic_type single: the data is sent to a single device, the accessory name is added to the topic, e.g.

topic : homebridge/from/set/flex_lamp

Note 2:

Optional parameter request_id: A unique (user defined) value may be added to any request, it will be included in the corresponding response

request_id : 4711

mqtt API

The data (payload) is sent/received in a JSON format using following topics:

  • homebridge/to/add
  • homebridge/to/add/service
  • homebridge/to/remove
  • homebridge/to/remove/service
  • homebridge/to/get
  • homebridge/to/set
  • homebridge/to/set/reachability
  • homebridge/to/set/accessoryinformation
  • homebridge/from/get
  • homebridge/from/set
  • homebridge/from/response
  • homebridge/from/identify

Version 0.3.0 and higher supports multiple services. To handle multiple services a new property service_name has been introduced.

Note: To add a service to an existing accessory (created prior version 0.3.0) please first remove the accessory and add it again.

Howto examples

add accessory

topic: homebridge/to/add
payload: {"name": "flex_lamp", "service_name": "light", "service": "Switch"}

or with the additional accessory informations

topic: homebridge/to/add
payload: 
{
  "name": "flex_lamp",
  "service_name": "light",
  "service": "Switch",
  "manufacturer": "lamp_manu",
  "model": "flex_007",
  "serialnumber": "4711",
  "firmwarerevision": "1.0.0"
}

response:

topic: homebridge/from/response
payload: {"ack": true, "message": "accessory 'flex_lamp' service_name 'light' is added."}

add service

Note: an accessory with the same name must be added before.

topic: homebridge/to/add/service
payload: {"name": "multi_sensor", "service_name": "humidity", "service": "HumiditySensor"}

response:

topic: homebridge/from/response
payload: {"ack": true, "message": "service_name 'humidity', service 'HumiditySensor' is added."}

remove accessory

topic: homebridge/to/remove
payload: {"name": "flex_lamp"}

response:

topic: homebridge/from/response
payload: {"ack": true, "message": "accessory 'flex_lamp' is removed."}

remove service

topic: homebridge/to/remove/service
payload: {"name": "multi_sensor", "service_name": "humidity"}

response:

topic: homebridge/from/response
payload: {"ack": true, "message": "accessory 'multi_sensor' service_name 'humidity' is removed."}

get accessory/accessories

The purpose of this topic is to retrieve accessory configurations. Use homebridge/from/set to control your devices.

topic: homebridge/to/get
payload: {"name": "outdoor_temp"}

homebridge sends the accessory configuration:

topic: homebridge/from/response
payload:
{
  "outdoor_temp": {
    "services": {
      "Temperature": "TemperatureSensor"
    },
    "characteristics": {
      "Temperature": {
        "CurrentTemperature": 13.4
      }
    }
  }
}
topic: homebridge/to/get
payload: {"name": "*"}

homebridge sends all accessory configurations:

topic: homebridge/from/response
payload:
{
  "node_switch": {
    "services": {
      "light": "Switch"
    },
    "characteristics": {
      "Light": {
        "On": true
      }
    }
  },
  "office_lamp": {
    "services": {
      "office_light": "Lightbulb"
    },
    "characteristics": {
      "office_light": {
        "On": "blank",
        "Brightness": 65
      }
    }
  },
  "living_temp": {
    "services": {
      "living_temperature": "TemperatureSensor"
    },
    "characteristics": {
      "living_temperature": {
        "CurrentTemperature": 19.6
      }
    }
  }
}
topic: homebridge/to/get
payload: {"name": "*_props"}

homebridge sends all accessory configurations, including properties:

topic: homebridge/from/response
payload:
{
  "node_switch": {
    "services": {
      "light": "Switch"
    },
    "characteristics": {
      "Light": {
        "On": true
      }
    },
    "properties": {
      "Light": {
        "On": {
          "format": "bool",
          "unit": null,
          "minValue": null,
          "maxValue": null,
          "minStep": null,
          "perms": [
            "pr",
            "pw",
            "ev"
          ]
        }
      }
    },
    "office_lamp": {
      "services": {
        "office_light": "Lightbulb"
      },
      "characteristics": {
        "office_light": {
          "On": "blank",
          "Brightness": 65
        }
      },
      "properties": {
        "office_light": {
          "On": {
            "format": "bool",
            "unit": null,
            "minValue": null,
            "maxValue": null,
            "minStep": null,
            "perms": [
              "pr",
              "pw",
              "ev"
            ]
          },
          "Brightness": {
            "format": "int",
            "unit": "percentage",
            "minValue": 0,
            "maxValue": 100,
            "minStep": 1,
            "perms": [
              "pr",
              "pw",
              "ev"
            ]
          }
        }
      }
    },
    "living_temp": {
      "services": {
        "living_temperature": "TemperatureSensor"
      },
      "characteristics": {
        "living_temperature": {
          "CurrentTemperature": 19.6
        }
      },
      "properties": {
        "living_temperature": {
          "CurrentTemperature": {
            "format": "float",
            "unit": "celsius",
            "minValue": 0,
            "maxValue": 100,
            "minStep": 0.1,
            "perms": [
              "pr",
              "ev"
            ]
          }
        }
      }
    }
  }
}

set value (to homebridge)

topic: homebridge/to/set
payload: {"name": "flex_lamp", "service_name": "light", "characteristic": "On", "value": true}

get value (from homebridge)

topic: homebridge/from/get
payload: {"name": "flex_lamp", "service_name": "light", "service_type":"Switch", "characteristic": "On", "cachedValue": true}

Homebridge-mqtt will return the cached value to HomeKit. Optionally you can publish the actual value using homebridge/to/set.

set value (from homebridge)

topic: homebridge/from/set
payload: {"name": "flex_lamp", "service_name": "light", "service_type":"Switch", "characteristic": "On", "value": true}

get (cached) value (to homebridge)

topic: homebridge/to/get/characteristic
payload: {"name": "flex_lamp", "service_name": "light", "characteristic": "On"}

response:

topic: homebridge/from/response
payload: {"name": "flex_lamp", "service_name": "light", "characteristic": "On", "cachedValue": true}

set reachability

topic: homebridge/to/set/reachability
payload: {"name": "flex_lamp", "reachable": true}
or
payload: {"name": "flex_lamp", "reachable": false}

set accessory information

topic: homebridge/to/set/accessoryinformation
payload: {"name": "flex_lamp", "manufacturer": "espressif", "model": "esp8266-12", "serialnumber": "4711", "firmwarerevision": "1.1.0"}

identify accessory

topic: homebridge/from/identify
payload: {"name":"indoor_temp","manufacturer":"homebridge-mqtt","model":"v0.3.0","serialnumber":"2017-02-13T12:17"}

define characterstic

The required characteristics are added with the default properties. If you need to change the default, define the characteristic-name with the properties. e.g.:

topic: homebridge/to/add
payload:
  {
    "name": "living_temp",
    "service_name": "temperature",
    "service": "TemperatureSensor",
    "CurrentTemperature": {"minValue": -20, "maxValue": 60, "minStep": 1}
  }

To add an optional charachteristic define the characteristic-name with "default" or with the properties. e.g.:

topic: homebridge/to/add
payload: 
  {
    "name": "living_lamp",
    "service_name": "light",
    "service": "Lightbulb",
    "Brightness": "default"
  }
topic: homebridge/to/add
payload:
  {
    "name": "bathroom_blind",
    "service_name": "blind",
    "service": "WindowCovering",
    "CurrentPosition": {"minStep": 5},
    "TargetPosition": {"minStep": 5},
    "CurrentHorizontalTiltAngle": {"minValue": 0, "minStep": 5},
    "TargetHorizontalTiltAngle": {"minValue": 0, "minStep": 5}
  }

HomeKit.ts describes all the predifined Services, Characteristcs, format and properties for the value e.g.:

/**
 * Service "Contact Sensor"
 */

Service.ContactSensor = function(displayName, subtype) {
  Service.call(this, displayName, '00000080-0000-1000-8000-0026BB765291', subtype);

  // Required Characteristics
  this.addCharacteristic(Characteristic.ContactSensorState);

  // Optional Characteristics
  this.addOptionalCharacteristic(Characteristic.StatusActive);
  this.addOptionalCharacteristic(Characteristic.StatusFault);
  this.addOptionalCharacteristic(Characteristic.StatusTampered);
  this.addOptionalCharacteristic(Characteristic.StatusLowBattery);
  this.addOptionalCharacteristic(Characteristic.Name);
};

/**
 * Characteristic "Contact Sensor State"
 */

Characteristic.ContactSensorState = function() {
  Characteristic.call(this, 'Contact Sensor State', '0000006A-0000-1000-8000-0026BB765291');
  this.setProps({
    format: Characteristic.Formats.UINT8,
    perms: [Characteristic.Perms.READ, Characteristic.Perms.NOTIFY]
  });
  this.value = this.getDefaultValue();
};

inherits(Characteristic.ContactSensorState, Characteristic);

Characteristic.ContactSensorState.UUID = '0000006A-0000-1000-8000-0026BB765291';

// The value property of ContactSensorState must be one of the following:
Characteristic.ContactSensorState.CONTACT_DETECTED = 0;
Characteristic.ContactSensorState.CONTACT_NOT_DETECTED = 1;

Derived from this:

service = ContactSensor
characteristic = ContactSensorState
format = UINT8
property = 0 or 1

Node-red example

node-red-mqtt

For more examples take a look at the wiki

Metadata

RunKit is a free, in-browser JavaScript dev environment for prototyping Node.js code, with every npm package installed. Sign up to share your code.
Sign Up for Free