-
Notifications
You must be signed in to change notification settings - Fork 388
Developers: Plugin Settings GUI
Plugin authors can publish a config.schema.json
which defines the config their plugin requires in the JSON Schema format (v6, v4 or v3). Homebridge Config UI X will use this file to generate a user-interfaces so users can set up a plugin without having to manually manipulate the config.json
.
- Enabling Support For Your Plugin
- Form Generator Playground
- Basic Structure
- Element Types
- Help Text
- Validators
- Header and Footer Display
- Simple Example
- Complex Example
- Limitations and Workarounds
- Advanced Requirements
- Plugins Using This
To add support for a GUI settings page for your plugin, all you need to do is define and publish the config.schema.json
as part of your npm package. Homebridge Config UI X will detect this file and show the Settings
button on the plugin page:
The config schema supports both Platform and Accessory plugin types.
The forms are generated using Angular JSON Schema Form, you can test your schema and form layout using the demonstration playground. This JSON Schema Tool can also help you create your schema and then you can modify to your liking.
{
"pluginAlias": "Camera-ffmpeg",
"pluginType": "platform",
"singular": false,
"headerDisplay": "Optional content to display above the plugin config. Supports markdown.",
"footerDisplay": "Optional content to display below the plugin config. Supports markdown.",
"schema": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string",
"required": true
}
}
},
"form": null,
"display": null
}
-
pluginAlias
: The plugin identifier. -
pluginType
: The type of plugin, valid values areplatform
oraccessory
. -
singular
: If set totrue
the UI will not allow the user to add more than one config block. This is usually used for platform plugins where only a single config block should be present. -
headerDisplay
andfooterDisplay
: See Below for details. -
form
anddisplay
: These attributes are optional and can be used to further customise how the interface is presented to the user, see the playground for more examples.
You do not need to include the platform
or accessory
attribute in your schema
object. This will be automatically added based on the pluginType
.
Setting default values is a great way to ensure your users get up and running as smoothly as possible - to do this just add the default
attribute with the desired value:
{
"pluginAlias": "daikin-esp8266-platform",
"pluginType": "platform",
"singular": true,
"schema": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string",
"default": "Daikin AC",
"required": true
}
}
}
}
Checkboxes return true
or false
and can be implemented using the JSON Schema boolean
type.
{
"pluginAlias": "config",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"sudo": {
"title": "Use Sudo",
"type": "boolean"
}
}
}
}
"sudo": true
Checkboxes can also build a string of arrays from a pre-defined list. The below example will generate an array named disabled_modes
with the values Off
, Home
, Night
, or Away
depending on which checkboxes are selected.
{
"pluginAlias": "config",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"disabled_modes": {
"title": "Disabled Modes",
"type": "array",
"uniqueItems": true,
"items": {
"title": "Mode",
"type": "string",
"enum": [
"Off",
"Home",
"Night",
"Away"
]
}
}
}
}
"disabled_modes": ["Off", "Night"]
Arrays of any size are supported using the JSON Schema array
type. Arrays of objects are also supported, see the complex example below.
{
"pluginAlias": "UniFi Occupancy Sensor",
"pluginType": "accessory",
"schema": {
"type": "object",
"properties": {
"watch": {
"title": "Watched Devices",
"type": "array",
"items": {
"title": "MAC Address",
"type": "string"
}
}
}
}
}
Dropdown select boxes can be implemented using the JSON Schema oneOf
attribute.
{
"pluginAlias": "config",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"auth": {
"title": "Auth Mode",
"type": "string",
"default": "form",
"oneOf": [
{ "title": "Form", "enum": ["form"] },
{ "title": "Basic Auth", "enum": ["basic"] },
{ "title": "None", "enum": ["none"] }
],
"required": true
}
}
}
}
Datalists suggest values to the user in a similar way to drop down boxes, but still allowing the user to enter their own value if they like.
{
"pluginAlias": "config",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"vcodec": {
"title": "Video Codec",
"type": "string",
"placeholder": "libx264",
"description": "The ffmpeg video processing codec to use.",
"typeahead": {
"source": [
"libx264",
"copy",
"h264_omx",
"h264",
"h264_mmal"
]
}
}
}
}
}
Help text can be added below each input using the description
attribute.
{
"pluginAlias": "Camera-ffmpeg",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string",
"required": true,
"description": "The name of the plugin"
}
}
}
}
The min and max string length can be set using the minLength
and maxLength
JSON Schema attributes. Both are optional.
{
"pluginAlias": "Camera-ffmpeg",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string",
"minLength": 4,
"maxLength": 10
}
}
}
}
Numeric input can be validated using the minimum
and maximum
JSON Schema attributes. Providing both a min and max value will display a range slider to the user.
{
"pluginAlias": "Camera-ffmpeg",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"timeout": {
"title": "Timeout",
"type": "integer",
"minimum": 15,
"maximum": 3000
}
}
}
}
You can validate the user's input using a regex in the JSON Schema pattern
attribute.
{
"pluginAlias": "UniFi Occupancy Sensor",
"pluginType": "accessory",
"schema": {
"type": "object",
"properties": {
"mac": {
"title": "MAC Address",
"type": "string",
"pattern": "^([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$"
}
}
}
}
You can also use the built-in format
types to validate the data:
-
date-time
: Date representation, as defined by RFC 3339, section 5.6. -
email
: Internet email address, see RFC 5322, section 3.4.1. -
hostname
: Internet hostname, see RFC 1034, section 3.1. -
ipv4
: IPv4 address, according to dotted-quad ABNF syntax as defined in RFC 2673, section 3.2. -
ipv6
: IPv6 address, as defined in RFC 2373, section 2.2. -
uri
: A universal resource identifier (URI), according to RFC3986.
Example:
{
"pluginAlias": "UniFi Occupancy Sensor",
"pluginType": "accessory",
"schema": {
"type": "object",
"properties": {
"host": {
"title": "IP Address / Hostname",
"type": "string",
"required": true,
"format": "hostname"
}
}
}
}
Plugin authors can display additional content in the user interface above and below the config form using the headerDisplay
and footerDisplay
attributes. These displays support markdown and plain text.
Things to keep in mind when creating displays:
- Keep it short. Screen real estate is limited, rather than displaying your entire setup guide it might be better to provide a link to your wiki instead.
- Remote images are supported when using the full image URI.
- Images may only be loaded from
https://raw.githubusercontent.com
.
- Images may only be loaded from
- Absolutely no HTML tags. GitHub flavoured markdown supports some HTML tags such as
a
andimg
. We do not, these tags will not be rendered in the interface. - Custom JavaScript is not supported anywhere.
This example shows the simplest config.schema.json
example.
{
"pluginAlias": "BelkinWeMo",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"name": {
"title": "Name",
"type": "string",
"default": "WeMo Platform",
"required": true
}
}
}
}
This example shows the config schema for KhaosT/homebridge-camera-ffmpeg. The user interface will allow users to add to the array of cameras.
{
"pluginAlias": "Camera-ffmpeg",
"pluginType": "platform",
"headerDisplay": "The **ffmpeg** binary must be installed on your system for this plugin to work.",
"footerDisplay": "For help please see the [wiki](https://github.com/KhaosT/homebridge-camera-ffmpeg/wiki).",
"schema": {
"name": {
"title": "Name",
"type": "string",
"default": "Camera ffmpeg",
"required": true
},
"cameras": {
"type": "array",
"items": {
"title": "Camera Config",
"type": "object",
"properties": {
"source": {
"title": "Source",
"type": "string",
"default": "-re -i rtsp://myfancy_rtsp_stream",
"required": true
},
"stillImageSource": {
"title": "Still Image Source",
"type": "string",
"default": "-i http://faster_still_image_grab_url/this_is_optional.jpg"
},
"maxStreams": {
"title": "Maximum Number of Streams",
"type": "integer",
"default": 2,
"minimum": 1,
"description": "The maximum number of streams that will be generated for this camera"
},
"maxWidth": {
"title": "Maximum Width",
"type": "integer",
"default": 1280,
"minimum": 1,
"description": "The maximum width reported to HomeKit"
},
"maxHeight": {
"title": "Maximum Height",
"type": "integer",
"default": 720,
"minimum": 1,
"description": "The maximum height reported to HomeKit"
},
"maxFPS": {
"title": "Maximum Height",
"type": "integer",
"default": 10,
"minimum": 1,
"description": "The maximum frame rate of the stream"
},
"maxBitrate": {
"title": "Maximum Height",
"type": "integer",
"default": 300,
"minimum": 1,
"description": "The maximum bit rate of the stream"
},
"vcodec": {
"title": "Video Codec",
"type": "string",
"default": "libx264"
},
"packetSize": {
"title": "Packet Size",
"type": "number",
"default": 1316,
"multipleOf": 188.0
},
"audio": {
"title": "Enable Audio?",
"type": "boolean",
"default": false
},
"debug": {
"title": "Enable Debug Mode?",
"type": "boolean",
"default": false
}
}
}
}
}
}
A small number of existing plugin configs may not work with the automatically generated forms. Specifically, the JSON Schema patternProperties
attribute is not supported. The patternProperties
attribute would be used when the plugin requires user-defined keys. Since this is not supported plugin authors should swap such config blocks to use arrays
instead.
Here is an example Homebridge config block that we can't generate a form for because it depends on user-defined key names:
"platforms": [
{
"platform": "Some Platform",
"users": {
"user-one": "password",
"user-two": "password"
}
}
]
This can be fixed by changing the config to use an array
instead of an object
:
"platforms": [
{
"platform": "Some Platform",
"users": [
{ "key": "user-one", "value": "password" },
{ "key": "user-two", "value": "password" }
]
}
]
The config.schema.json
file would then look like this:
{
"pluginAlias": "Some Platform",
"pluginType": "platform",
"schema": {
"type": "object",
"properties": {
"users": {
"title": "Users",
"type": "array",
"items": {
"title": "User",
"type": "object",
"properties": {
"key": {
"title": "Username",
"type": "string",
"required": true
},
"value": {
"title": "Password",
"type": "string",
"required": true
}
}
}
}
}
}
}
If the plugin requires the config block to be put back into the original object
format they can easily transform the array
at runtime:
const users = {};
config.users.forEach(x => users[x.key] = x.value);
If you have more complex requirements than what the standard config.schema.json
syntax can support; for example, an OAUTH2 workflow, or exchanging username and password for a token, please reach out to me (@oznu) and we can work something out.
Examples of advanced implementations:
-
homebridge-ring - supports exchanging Ring credentials for a
refreshToken
directly from the user interface (with 2FA support). - homebridge-honeywell-home - supports an OAUTH2 workflow to retrieve a token.
- homebridge-gsh - supports an OAUTH2 workflow to get an access token.
These are examples of plugins that currently implement the Plugin Settings GUI using the config.schema.json
:
- homebridge-433-arduino
- homebridge-aladdin-connect-garage-door
- homebridge-alexa
- homebridge-apple-tv-remote
- homebridge-automation-chromecast
- homebridge-automower
- homebridge-blink
- homebridge-bravia
- homebridge-button-platform
- homebridge-camera-ffmpeg
- homebridge-canary
- homebridge-comelit-hub
- homebridge-config-ui-x
- homebridge-connex
- homebridge-chamberlain
- homebridge-daikin-esp8266
- homebridge-denon-tv
- homebridge-dummy
- homebridge-dummy-lock
- homebridge-dummy-thermostat
- homebridge-dyson-pure-cool
- homebridge-esp-irrigation-controller
- homebridge-esp-pir
- homebridge-esp8266-fan
- homebridge-ecoplug
- homebridge-eveatmo
- homebridge-g-on-alice
- homebridge-gogogate2
- homebridge-gsh
- homebridge-harmony
- homebridge-homeconnect
- homebridge-homeqtt-alarm
- homebridge-honeywell-home
- homebridge-honeywell-leak
- homebridge-hue
- homebridge-landroid
- homebridge-lgwebos-tv
- homebridge-luxtronik2
- homebridge-meross
- homebridge-mi-hygrothermograph
- homebridge-mqttthing
- homebridge-music
- homebridge-mysmartblinds-bridge
- homebridge-neato
- homebridge-nest
- homebridge-onkyo
- homebridge-openwebif-tv
- homebridge-otgw
- homebridge-p1
- homebridge-pihole
- homebridge-platform-maxcube
- homebridge-platform-wemo
- homebridge-ring
- homebridge-rpi
- homebridge-sengled
- homebridge-smartglass
- homebridge-smartthings-v2
- homebridge-sonos
- homebridge-sunricher-wifi
- homebridge-tesla
- homebridge-tion
- homebridge-tydom
- homebridge-ueboom
- homebridge-unifi-occupancy-sensor
- homebridge-videodoorbell
- homebridge-webos-tv
- homebridge-weather-plus
- homebridge-ws
- homebridge-xbox-tv
- homebridge-yalesmarthomealarm
- homebridge-zigbee
- homebridge-zp
homebridge-zp screenshot (dark mode theme):
homebridge-config-ui-x screenshot:
homebridge-alexa screenshot:
- Raspberry Pi
- Debian, Ubuntu
- CentOS, Fedora, Red Hat
- Arch, Manjaro
- macOS
- Windows 10 / 11 (Hyper-V)
- Docker
- Synology DSM 7
- Other Platforms
- Basic Troubleshooting
- Backup and Restore
- Child Bridges
- Config File
- Connect To HomeKit
- FFmpeg for Homebridge
- HomeKit Glossary of Terms
- iOS Homemanager App
- mDNS Options
- Remote Access
- Useful Links
- Basic Troubleshooting
- Config Options
- Enabling Accessory Control
- Enabling UI with Docker
- Homebridge Service Command
- Manual Configuration
- Reverse Proxy: Apache
- Reverse Proxy: Nginx and SSL
- Standalone Mode
- Swap From Standalone To Service Mode
- Developer Docs
- API Reference
- Plugin Templates
- Other Links (Internal)
- Other Links (External)