Homebridge is a lightweight NodeJS server you can run on your home network that emulates the iOS HomeKit API. It supports Plugins, which are community-contributed modules that provide a basic bridge from HomeKit to various 3rd-party APIs provided by manufacturers of "smart home" devices.
Preparing the Homebridge Docker Image
Download
Start by downloading the Docker image from Docker Hub. It is recommended to use the latest version:
docker pull oznu/homebridge:latest
How to Run
Homebridge requires full access to your local network to function correctly which can be achieved using the --net=host flag. Currently this image will not work when using Docker for Mac or Docker for Windows.
You can run the image with the following command:
docker run \
--net=host \
--name=homebridge \
-e PUID=<UID> -e PGID=<GID> \
-e TZ=Europe/Berlin \
-e HOMEBRIDGE_CONFIG_UI=1 \
-e HOMEBRIDGE_CONFIG_UI_PORT=8080 \
-e HOMEBRIDGE_INSECURE=1 \
-v </path/to/config>:/homebridge \
oznu/homebridge
The </path/to/config>
has to be created on your host system, e.g. :
mkdir /opt/homebridge
chmod 775 /opt/homebridge
Sometimes when using data volumes (-v flags) permissions issues can arise between the host OS and the container. We avoid this issue by allowing you to specify the user PUID and group PGID. Ensure the data volume directory on the host is owned by the same user you specify and it will "just work".
In this instance PUID=1001 and PGID=1001. To find yours use id user as below:
id <dockeruser>
uid=1001(dockeruser) gid=1001(dockergroup) groups=1001(dockergroup)
Configuration
Create a file name config.json
inside the /opt/homebridge
directory. A template can be found at the end of this tutorial. This configuration file will add 10 MQTT buttons for the Full HD camera with the IP address 192.168.2.117
and Admin Login admin
/ instar
running it's MQTT Broker on port 1883
with the broker login admin
/ instar
. Please changes these information inside the configuration file before copying it to the directory.
But we are not yet able to use this template as it requires 2 plugins we need to install first. So we have to start with a blank template, start up Homebridge and install the those plugins first.
{
"bridge": {
"name": "Homebridge",
"username": "CC:22:3D:E3:CE:35",
"manufacturer": "homebridge.io",
"model": "homebridge",
"port": 51826,
"pin": "031-45-155"
},
"description": "This is an example configuration file with one fake accessory and one fake platform. You can use this as a template for creating your own configuration file containing devices you actually own.",
"ports": {
"start": 52100,
"end": 52150,
"comment": "This section is used to control the range of ports that separate accessory (like camera or television) should be bind to."
},
"accessories": [],
"platforms": [
{
"name": "Config",
"port": 8080,
"auth": "form",
"theme": "dark-mode",
"tempUnits": "c",
"lang": "auto",
"sudo": false,
"accessoryControl": {
"debug": true
},
"platform": "config"
}
]
}
Add this content to /opt/homebridge/config.json
:
nano /opt/homebridge/config.json
chmod 775 /opt/homebridge/*
Run
You have already downloaded the image, now you can check the Image ID and run the container:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/oznu/homebridge latest f0039cfe89f4 46 hours ago 726 MB
Add your Image ID, Docker User and Group ID, Timezone and configuration directory to the following command:
docker run \
--net=host \
--name=homebridge \
--privileged \
--rm \
-e PUID=0 -e PGID=0 \
-e TZ=Europe/Berlin \
-e HOMEBRIDGE_CONFIG_UI=1 \
-e HOMEBRIDGE_CONFIG_UI_PORT=8080 \
-e HOMEBRIDGE_INSECURE=1 \
-v /opt/homebridge:/homebridge \
-ti -u root f0039cfe89f4 /bin/bash
Setting Up Homebridge
Wait for the Homebridge UI to spin up on Port 8080
and login with admin
/ admin
:
You can install the following plugins through the Hombridge UI:
- homebridge-camera-ffmpeg
- homebridge-mqttthing
When installing the homebridge-camera-ffmpeg
plugin you will be asked to fill out the following form to add your camera:
For this camera:
- LAN IP
192.168.2.117
- RTSP Port
554
- Admin Username
admin
- Admin Password
instar
You will have to add these two lines (change them according to your camera configuration):
-re -i rtsp://admin:instar@192.168.2.117:554/12
-i http://192.168.2.117/tmpfs/auto.jpg?usr=admin&pwd=instar
This will add the following lines to our configuration file:
With the MQTT plugin installed, we can import the MQTT Buttons in the accessories
section of the configuration file - the necessary code can be found at end of this tutorial. Again, this code is for the camera with the following configuration and has to be adjusted accordingly:
- Camera LAN IP
192.168.2.117
- MQTT Broker Port
1883
- MQTT User
admin
- MQTT Password
instar
Copy & paste in the complete accessories
section to add all MQTT buttons:
Commit your Changes to the Docker Image
Login to your host machine from a new terminal window and find out the Container ID that was assigned to the homebridge container:
docker ps -a
CONTAINER ID IMAGE NAMES
5b4bd0d0189d localhost/oznu/homebridge:debian-no-avahi homebridge
In this case the Container ID is 5b4bd0d0189d
and I want to call the image, that will contain all our changes, instar-mqtt-homebridge
:
docker commit 5b4bd0d0189d instar-mqtt-homebridge
We can now stop the original image and switch to our newly created image:
docker images
REPOSITORY IMAGE ID
localhost/instar-mqtt-homebridge 42e1bcaed5e6
The old container has the ID 5b4bd0d0189d
- so we can stop this now and run the new image with Image ID 42e1bcaed5e6
instead:
docker stop 5b4bd0d0189d
To run the new image you have to modify the following command as before - but this time either use the Image ID 42e1bcaed5e6
or Repository Name localhost/instar-mqtt-homebridge
you have to assigned to your new image:
docker run \
--net=host \
--name=instar-mqtt-homebridge \
--privileged \
--rm \
-e PUID=0 -e PGID=0 \
-e TZ=Europe/Berlin \
-e HOMEBRIDGE_CONFIG_UI=1 \
-e HOMEBRIDGE_CONFIG_UI_PORT=8080 \
-e HOMEBRIDGE_INSECURE=1 \
-v /opt/homebridge:/homebridge \
-ti -u root 42e1bcaed5e6 /bin/bash
When you access the Homebridge dashboard you should now find all MQTT buttons under the Accessories tab (Click and configure them, if you want to add them to your main dashboard page):
Hombridge Configuration Template
{
"bridge": {
"name": "Homebridge",
"username": "CC:22:3D:E3:CE:35",
"manufacturer": "homebridge.io",
"model": "homebridge",
"port": 51826,
"pin": "031-45-155"
},
"description": "This is an example configuration file with one fake accessory and one fake platform. You can use this as a template for creating your own configuration file containing devices you actually own.",
"ports": {
"start": 52100,
"end": 52150,
"comment": "This section is used to control the range of ports that separate accessory (like camera or television) should be bind to."
},
"accessories": [
{
"accessory": "mqttthing",
"type": "switch",
"name": "Alarm Area 1",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Alarm Area 1",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/area1/enable",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/area1/enable",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "1",
"offValue": "0",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Alarm Area 2",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Alarm Area 2",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/area2/enable",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/area2/enable",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "1",
"offValue": "0",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Alarm Area 3",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Alarm Area 3",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/area3/enable",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/area3/enable",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "1",
"offValue": "0",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Alarm Area 4",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Alarm Area 4",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/area4/enable",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/area4/enable",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "1",
"offValue": "0",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "PIR Sensor",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "PIR Sensor",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/actions/pir/enable",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/actions/pir/enable",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "1",
"offValue": "0",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Link Areas",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Link Areas",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/actions/linkareas",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/actions/linkareas",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "on",
"offValue": "off",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Alarm Email",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Alarm Email",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/actions/email",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/actions/email",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "on",
"offValue": "off",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Alarm Push",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Alarm Push",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/alarm/push/enable",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/alarm/push/enable",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "on",
"offValue": "off",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Audio",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Audio",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/multimedia/audio/enable/high",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/multimedia/audio/enable/high",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "1",
"offValue": "0",
"confirmationPeriodms": 1000,
"retryLimit": 3
},
{
"accessory": "mqttthing",
"type": "switch",
"name": "Preset Position",
"manufacturer": "INSTAR",
"model": "IN-8015 FullHD",
"serialNumber": "1234567890",
"firmwareRevision": "0.1",
"url": "http://192.168.2.117:1883",
"username": "admin",
"password": "instar",
"caption": "Preset Position",
"mqttOptions": {
"keepalive": 30
},
"mqttPubOptions": {
"retain": true
},
"logMqtt": true,
"topics": {
"getOn": {
"topic": "instar/local/status/features/ptz/preset",
"apply": "return JSON.parse(message).val;"
},
"setOn": {
"topic": "instar/local/features/ptz/preset",
"apply": "return JSON.stringify({val: (message)})"
}
},
"onValue": "1",
"offValue": "0",
"confirmationPeriodms": 1000,
"retryLimit": 3
}
],
"platforms": [
{
"name": "Config",
"port": 8080,
"auth": "form",
"theme": "dark-mode",
"tempUnits": "c",
"lang": "auto",
"sudo": false,
"accessoryControl": {
"debug": true
},
"platform": "config"
},
{
"name": "Camera ffmpeg",
"cameras": [
{
"name": "IN-8015",
"videoConfig": {
"source": "-re -i rtsp://admin:instar@192.168.2.117:554/11",
"stillImageSource": "-i http://192.168.2.117/tmpfs/auto.jpg?usr=admin&pwd=instar",
"maxStreams": 2,
"maxWidth": 1920,
"maxHeight": 1080,
"maxFPS": 10,
"maxBitrate": 300,
"vcodec": "libx264",
"packetSize": 1316,
"audio": false,
"debug": false
}
}
],
"platform": "Camera-ffmpeg"
}
]
}