homebridge-virtual-accessories
Version:
Virtual HomeKit accessories for Homebridge.
1,173 lines • 70.6 kB
JSON
{
"pluginAlias": "VirtualAccessoriesForHomebridge",
"pluginType": "platform",
"singular": true,
"footerDisplay": "* = required fields",
"strictValidation": true,
"schema": {
"type": "object",
"$defs": {
"volume": {
"title": "Volume (0% - 100%) *",
"type": "integer",
"minimum": 0,
"maximum": 100
},
"duration": {
"type": "object",
"properties": {
"days": {
"title": "Days *",
"type": "integer",
"minimum": 0,
"maximum": 7
},
"hours": {
"title": "Hours *",
"type": "integer",
"minimum": 0,
"maximum": 23
},
"minutes": {
"title": "Minutes *",
"type": "integer",
"minimum": 0,
"maximum": 59
},
"seconds": {
"title": "Seconds *",
"type": "integer",
"minimum": 0,
"maximum": 59
}
}
},
"requireHoursMinutesSeconds": {
"if": {
"properties": {
"days": { "maximum": 6 }
},
"required": [ "days" ]
},
"then": {
"required": [ "hours", "minutes", "seconds" ]
}
},
"doorAndWindowAccessory": {
"type": "object",
"properties": {
"defaultState": {
"title": "Default State *",
"type": "string",
"oneOf": [
{ "title": "Closed", "enum": ["closed"] },
{ "title": "Open", "enum": ["open"] }
]
},
"transitionDuration": {
"title": "Transition Duration",
"description": "Open & close transition duration in seconds (default: 3 seconds)",
"type": "integer",
"minimum": 1,
"maximum": 60
}
}
}
},
"properties": {
"name": {
"title": "Platform Name",
"type": "string",
"required": true,
"default": "Virtual Accessories Platform",
"readonly": true
},
"sensorServer": {
"title": "Sensor Webhooks",
"type": "object",
"expandable": true,
"expanded": false,
"properties": {
"enabled": {
"title": "Enabled",
"description": "Update sensors via web calls",
"type": "boolean"
},
"port": {
"title": "Server Port",
"type": "string",
"pattern": "^(4915[2-9]|491[6-9][0-9]|49[2-9][0-9]{2}|5[0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$",
"placeholder": "60221"
}
}
},
"devices": {
"title": "Accessories",
"type": "array",
"orderable": true,
"uniqueItemProperties": [ "accessoryID" ],
"items": {
"title": " {{ value.accessoryName || 'New Accessory' }}",
"type": "object",
"expandable": true,
"expanded": false,
"properties": {
"accessoryID": {
"title": "Accessory ID",
"description": "Unique ID for the Accessory (https://www.random.org/). Do not modify once assigned!",
"type": "string",
"required": true,
"pattern": "^[A-Za-z0-9\\-]{5,}$"
},
"accessoryName": {
"title": "Accessory Name",
"description": "Accessory name as it will be displayed in HomeKit",
"type": "string",
"required": true
},
"accessoryType": {
"title": "Accessory Type",
"type": "string",
"required": true,
"oneOf": [
{ "title": "Air Purifier", "enum": ["airpurifier"] },
{ "title": "Battery", "enum": ["battery"] },
{ "title": "Door", "enum": ["door"] },
{ "title": "Doorbell", "enum": ["doorbell"] },
{ "title": "Fan", "enum": ["fan"] },
{ "title": "Filter Maintenance", "enum": ["filtermaintenance"] },
{ "title": "Garage Door", "enum": ["garagedoor"] },
{ "title": "Heater/Cooler (AC)", "enum": ["heatercooler"] },
{ "title": "Humidifier/Dehumidifier", "enum": ["humidifierdehumidifier"] },
{ "title": "Lightbulb", "enum": ["lightbulb"] },
{ "title": "Lock", "enum": ["lock"] },
{ "title": "Microphone", "enum": ["microphone"] },
{ "title": "Security System", "enum": ["securitysystem"] },
{ "title": "Sensor - Measurement", "enum": ["measurement"] },
{ "title": "Sensor - Triggered", "enum": ["sensor"] },
{ "title": "Speaker", "enum": ["speaker"] },
{ "title": "Switch", "enum": ["switch"] },
{ "title": "Television", "enum": ["television"] },
{ "title": "Valve", "enum": ["valve"] },
{ "title": "Window", "enum": ["window"] },
{ "title": "Window Covering (Blinds, Shades)", "enum": ["windowcovering"] }
]
},
"accessoryIsStateful": {
"title": "Accessory Is Stateful",
"description": "Accessory state survives Homebridge restart",
"type": "boolean",
"condition": {
"functionBody": "return ['airpurifier', 'door', 'fan', 'garagedoor', 'heatercooler', 'humidifierdehumidifier', 'lightbulb', 'lock', 'securitysystem', 'speaker', 'switch', 'television', 'valve', 'window', 'windowcovering'].includes(model.devices[arrayIndices].accessoryType);"
}
},
"airPurifier": {
"title": "Air Purifier",
"type": "object",
"properties": {
"rotationSpeed": {
"title": "Rotation Speed (0% - 100%) *",
"type": "integer",
"minimum": 0,
"maximum": 100
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'airpurifier';"
}
},
"battery": {
"title": "Battery",
"type": "object",
"properties": {
"isRechargeable": {
"title": "Is Rechargeable",
"type": "boolean"
},
"lowLevelThreshold": {
"title": "Battery low threshold (5% - 25%) *",
"type": "integer",
"minimum": 5,
"maximum": 25
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'battery';"
}
},
"door": {
"title": "Door",
"$ref": "#/$defs/doorAndWindowAccessory",
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'door';"
}
},
"doorbell": {
"title": "Doorbell",
"type": "object",
"properties": {
"volume": { "$ref": "#/$defs/volume" }
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'doorbell';"
}
},
"fan": {
"title": "Fan",
"type": "object",
"properties": {
"rotationDirection": {
"title": "Rotation Direction *",
"type": "string",
"oneOf": [
{ "title": "Clockwise", "enum": ["clockwise"] },
{ "title": "Counter Clockwise", "enum": ["counterclockwise"] }
]
},
"rotationSpeed": {
"title": "Rotation Speed (0% - 100%) *",
"type": "integer",
"minimum": 0,
"maximum": 100
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'fan';"
}
},
"filterMaintenance": {
"title": "Filter Maintenance",
"type": "object",
"description": "Filter Lifetime (30 days max)",
"properties": {
"lifespan": {
"title": " ",
"type": "object",
"properties": {
"days": {
"title": "Days *",
"type": "integer",
"minimum": 0,
"maximum": 30
},
"hours": {
"$ref": "#/$defs/duration/properties/hours",
"condition": {
"functionBody": "return model.devices[arrayIndices].filterMaintenance && model.devices[arrayIndices].filterMaintenance.lifespan && model.devices[arrayIndices].filterMaintenance.lifespan.days < 30;"
}
},
"minutes": {
"$ref": "#/$defs/duration/properties/minutes",
"condition": {
"functionBody": "return model.devices[arrayIndices].filterMaintenance && model.devices[arrayIndices].filterMaintenance.lifespan && model.devices[arrayIndices].filterMaintenance.lifespan.days < 30;"
}
},
"seconds": {
"$ref": "#/$defs/duration/properties/seconds",
"condition": {
"functionBody": "return model.devices[arrayIndices].filterMaintenance && model.devices[arrayIndices].filterMaintenance.lifespan && model.devices[arrayIndices].filterMaintenance.lifespan.days < 30;"
}
}
},
"allOf": [
{
"if": {
"properties": {
"days": { "maximum": 29 }
},
"required": [ "days" ]
},
"then": {
"required": [ "hours", "minutes", "seconds" ]
}
}
]
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'filtermaintenance';"
}
},
"garageDoor": {
"title": "Garage Door",
"$ref": "#/$defs/doorAndWindowAccessory",
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'garagedoor';"
}
},
"heaterCooler": {
"title": "Heater/Cooler",
"type": "object",
"properties": {
"type": {
"title": "Type *",
"type": "string",
"oneOf": [
{ "title": "Heater", "enum": ["heater"] },
{ "title": "Cooler (AC)", "enum": ["cooler"] },
{ "title": "Heater and Cooler (AC)", "enum": ["auto"] },
{ "title": "Sauna", "enum": ["sauna"] }
]
},
"hasFan": {
"title": "Has Fan",
"type": "boolean",
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && ['heater', 'cooler', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
}
},
"temperatureDisplayUnits": {
"title": "Temperature Display Units *",
"type": "string",
"oneOf": [
{ "title": "Celsius (ºC)", "enum": ["celsius"] },
{ "title": "Fahrenheit (ºF)", "enum": ["fahrenheit"] }
]
},
"heatingThresholdCelsius": {
"title": "Heating Threshold ºC *",
"description": "Temperature level below which the heater turns on (0ºC - 25ºC)",
"type": "integer",
"minimum": 0,
"maximum": 25,
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'celsius' && ['heater', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
}
},
"coolingThresholdCelsius": {
"title": "Cooling Threshold ºC *",
"description": "Temperature level above which the cooler (AC) turns on (10ºC - 35ºC)",
"type": "integer",
"minimum": 10,
"maximum": 35,
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'celsius' && ['cooler', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
}
},
"heatingThresholdFahrenheit": {
"title": "Heating Threshold ºF *",
"description": "Temperature level below which the heater turns on (32ºF - 77ºF)",
"type": "integer",
"minimum": 32,
"maximum": 77,
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'fahrenheit' && ['heater', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
}
},
"coolingThresholdFahrenheit": {
"title": "Cooling Threshold ºF *",
"description": "Temperature level above which the cooler (AC) turns on (50ºF - 95ºF)",
"type": "integer",
"minimum": 50,
"maximum": 95,
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'fahrenheit' && ['cooler', 'auto'].includes(model.devices[arrayIndices].heaterCooler.type);"
}
},
"saunaHeatingThresholdCelsius": {
"title": "Sauna Heating Threshold ºC *",
"description": "Temperature level below which the sauna heater turns on (15ºC - 90ºC)",
"type": "integer",
"minimum": 15,
"maximum": 90,
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'celsius' && ['sauna'].includes(model.devices[arrayIndices].heaterCooler.type);"
}
},
"saunaHeatingThresholdFahrenheit": {
"title": "Sauna Heating Threshold ºF *",
"description": "Temperature level below which the sauna heater turns on (59ºF - 194ºF)",
"type": "integer",
"minimum": 59,
"maximum": 194,
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.temperatureDisplayUnits === 'fahrenheit' && ['sauna'].includes(model.devices[arrayIndices].heaterCooler.type);"
}
},
"": {
"title": "",
"description": "Note: The heating threshold value **must be lower** than the cooling threshold value",
"type": "object",
"properties": {},
"condition": {
"functionBody": "return model.devices[arrayIndices].heaterCooler && model.devices[arrayIndices].heaterCooler.type === 'auto';"
}
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'heatercooler';"
},
"allOf": [
{
"if": {
"properties": {
"type": { "const": "heater" },
"temperatureDisplayUnits": { "const": "celsius" }
},
"required": [ "type", "temperatureDisplayUnits" ]
},
"then": {
"required": [ "heatingThresholdCelsius" ]
}
},
{
"if": {
"properties": {
"type": { "const": "cooler" },
"temperatureDisplayUnits": { "const": "celsius" }
},
"required": [ "type", "temperatureDisplayUnits" ]
},
"then": {
"required": [ "coolingThresholdCelsius" ]
}
},
{
"if": {
"properties": {
"type": { "const": "auto" },
"temperatureDisplayUnits": { "const": "celsius" }
},
"required": [ "type", "temperatureDisplayUnits" ]
},
"then": {
"required": [ "heatingThresholdCelsius", "coolingThresholdCelsius" ]
}
},
{
"if": {
"properties": {
"type": { "const": "heater" },
"temperatureDisplayUnits": { "const": "fahrenheit" }
},
"required": [ "type", "temperatureDisplayUnits" ]
},
"then": {
"required": [ "heatingThresholdFahrenheit" ]
}
},
{
"if": {
"properties": {
"type": { "const": "cooler" },
"temperatureDisplayUnits": { "const": "fahrenheit" }
},
"required": [ "type", "temperatureDisplayUnits" ]
},
"then": {
"required": [ "coolingThresholdFahrenheit" ]
}
},
{
"if": {
"properties": {
"type": { "const": "auto" },
"temperatureDisplayUnits": { "const": "fahrenheit" }
},
"required": [ "type", "temperatureDisplayUnits" ]
},
"then": {
"required": [ "heatingThresholdFahrenheit", "coolingThresholdFahrenheit" ]
}
}
]
},
"humidifierDehumidifier": {
"title": "Humidifier/Dehumidifier",
"type": "object",
"properties": {
"type": {
"title": "Type *",
"type": "string",
"oneOf": [
{ "title": "Humidifier", "enum": ["humidifier"] },
{ "title": "Dehumidifier", "enum": ["dehumidifier"] },
{ "title": "Humidifier and Dehumidifier", "enum": ["auto"] }
]
},
"humidifierThreshold": {
"title": "Humidifying Threshold *",
"description": "Humidity level below which the humidifier turns on (0% - 100%)",
"type": "integer",
"minimum": 0,
"maximum": 100,
"condition": {
"functionBody": "return model.devices[arrayIndices].humidifierDehumidifier && ['humidifier', 'auto'].includes(model.devices[arrayIndices].humidifierDehumidifier.type);"
}
},
"dehumidifierThreshold": {
"title": "Dehumidifying Threshold *",
"description": "Humidity level above which the dehumidifier turns on (0% - 100%)",
"type": "integer",
"minimum": 0,
"maximum": 100,
"condition": {
"functionBody": "return model.devices[arrayIndices].humidifierDehumidifier && ['dehumidifier', 'auto'].includes(model.devices[arrayIndices].humidifierDehumidifier.type);"
}
},
"": {
"title": "",
"description": "Note: The humidifier threshold value **must be lower** than the dehumidifier threshold value",
"type": "object",
"properties": {},
"condition": {
"functionBody": "return model.devices[arrayIndices].humidifierDehumidifier && model.devices[arrayIndices].humidifierDehumidifier.type === 'auto';"
}
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'humidifierdehumidifier';"
},
"allOf": [
{
"if": {
"properties": {
"type": { "const": "humidifier" }
},
"required": [ "type" ]
},
"then": {
"required": [ "humidifierThreshold" ]
}
},
{
"if": {
"properties": {
"type": { "const": "dehumidifier" }
},
"required": [ "type" ]
},
"then": {
"required": [ "dehumidifierThreshold" ]
}
},
{
"if": {
"properties": {
"type": { "const": "auto" }
},
"required": [ "type" ]
},
"then": {
"required": [ "humidifierThreshold", "dehumidifierThreshold" ]
}
}
]
},
"lightbulb": {
"title": "Lightbulb",
"type": "object",
"properties": {
"defaultState": {
"title": "Default State *",
"type": "string",
"oneOf": [
{ "title": "Off", "enum": ["off"] },
{ "title": "On", "enum": ["on"] }
]
},
"type": {
"title": "Type *",
"type": "string",
"oneOf": [
{ "title": "White", "enum": ["white"] },
{ "title": "White Ambiance", "enum": ["ambiance"] },
{ "title": "Color", "enum": ["color"] }
]
},
"brightness": {
"title": "Brightness (0% - 100%) *",
"type": "integer",
"minimum": 0,
"maximum": 100,
"condition": {
"functionBody": "return model.devices[arrayIndices].lightbulb && ['white', 'ambiance'].includes(model.devices[arrayIndices].lightbulb.type);"
}
},
"colorTemperatureKelvin": {
"title": "Color Temperature *",
"description": "Color temperature in Kelvin (2200 K to 6500 K)",
"type": "integer",
"minimum": 2200,
"maximum": 6500,
"placeholder": 2700,
"condition": {
"functionBody": "return model.devices[arrayIndices].lightbulb && model.devices[arrayIndices].lightbulb.type === 'ambiance';"
}
},
"colorHex": {
"title": "Color *",
"type": "string",
"format": "color",
"condition": {
"functionBody": "return model.devices[arrayIndices].lightbulb && model.devices[arrayIndices].lightbulb.type === 'color';"
}
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'lightbulb';"
},
"allOf": [
{
"if": {
"properties": {
"type": { "const": "white" }
},
"required": [ "type" ]
},
"then": {
"required": [ "brightness" ]
}
},
{
"if": {
"properties": {
"type": { "const": "ambiance" }
},
"required": [ "type" ]
},
"then": {
"required": [ "brightness", "colorTemperatureKelvin" ]
}
},
{
"if": {
"properties": {
"type": { "const": "color" }
},
"required": [ "type" ]
},
"then": {
"required": [ "colorHex" ]
}
}
]
},
"lock": {
"title": "Lock",
"type": "object",
"properties": {
"defaultState": {
"title": "Default State *",
"type": "string",
"oneOf": [
{ "title": "Locked", "enum": ["locked"] },
{ "title": "Unlocked", "enum": ["unlocked"] }
]
},
"autoSecurityTimeout": {
"title": "Auto Security Timeout *",
"description": "Lock auto-lock time in seconds (0 = off)",
"type": "integer",
"minimum": 0
},
"walletKeyColor": {
"title": "HomeKey Color",
"description": "HomeKey card color in Wallet app (default: Tan)",
"type": "string",
"oneOf": [
{ "title": "Tan", "enum": ["tan"] },
{ "title": "Gold", "enum": ["gold"] },
{ "title": "Silver", "enum": ["silver"] },
{ "title": "Black", "enum": ["black"] }
]
},
"": {
"description": "Note: HomeKey appears to currently be broken. If you are experiencing issues, set HomeKey Color to None.",
"type": "object",
"properties": {}
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'lock';"
}
},
"microphone": {
"title": "Microphone",
"type": "object",
"properties": {
"volume": { "$ref": "#/$defs/volume" }
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'microphone';"
}
},
"securitySystem": {
"title": "Security System",
"type": "object",
"properties": {
"armedModesTitle": {
"title": "Armed Modes",
"description": "Security system modes (Away and Home modes are required)",
"type": "object",
"properties": {}
},
"hasAwayMode": {
"title": "❎ Away Mode",
"type": "object",
"properties": {}
},
"hasHomeMode": {
"title": "❎ Home Mode",
"type": "object",
"properties": {}
},
"hasNightMode": {
"title": "Night Mode",
"type": "boolean"
},
"defaultState": {
"title": "Default State *",
"description": "The default state **must be** either 'Disarmed' or one of the available armed states",
"type": "string",
"oneOf": [
{ "title": "Armed - Away", "enum": ["armedaway"] },
{ "title": "Armed - Home", "enum": ["armedstay"] },
{ "title": "Disarmed", "enum": ["disarmed"] }
]
},
"awayArmingDelay": {
"title": "Away Arming Delay",
"description": "Away Mode arming delay in seconds (default 0 = immediate)",
"type": "integer",
"minimum": 0,
"maximum": 60
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'securitysystem';"
}
},
"speaker": {
"title": "Speaker",
"type": "object",
"properties": {
"mute": {
"title": "Muted",
"type": "boolean"
},
"volume": { "$ref": "#/$defs/volume" }
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'speaker';"
}
},
"switch": {
"title": "Switch",
"type": "object",
"properties": {
"defaultState": {
"title": "Default State *",
"type": "string",
"oneOf": [
{ "title": "Off", "enum": ["off"] },
{ "title": "On", "enum": ["on"] }
]
},
"hasResetTimer": {
"title": "Has a Reset Timer",
"description": "Switch resets to default state when timer ends",
"type": "boolean"
},
"hasCompanionSensor": {
"title": "Has a Companion Sensor",
"description": "Switch triggers a sensor when its state changes",
"type": "boolean"
},
"muteLogging" : {
"title": "Mute Logging",
"description": "Log information will only be visible when running in debug mode",
"type": "boolean"
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'switch';"
}
},
"television": {
"title": "Television Inputs",
"type": "object",
"properties": {
"inputs": {
"title": " ",
"type": "array",
"minItems": 1,
"orderable": true,
"uniqueItems": true,
"items": {
"title": "{{ $index ? ' Input ' + $index : 'Input' }}",
"type": "string",
"minLength": 1,
"placeholder": "HDMI"
}
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'television';"
}
},
"valve": {
"title": "Valve",
"type": "object",
"properties": {
"type": {
"title": "Type *",
"type": "string",
"oneOf": [
{ "title": "Generic Valve", "enum": ["generic"] },
{ "title": "Irrigation", "enum": ["irrigation"] },
{ "title": "Shower Head", "enum": ["showerhead"] },
{ "title": "Water Faucet", "enum": ["waterfaucet"] }
]
},
"duration": {
"title": "Runtime",
"description": "Valve auto shut-off time (1hr max - 0 = manual off)",
"type": "object",
"properties": {
"minutes": {
"title": "Minutes *",
"type": "integer",
"minimum": 0,
"maximum": 60
},
"seconds": {
"$ref": "#/$defs/duration/properties/seconds",
"condition": {
"functionBody": "return model.devices[arrayIndices].valve && model.devices[arrayIndices].valve.duration && model.devices[arrayIndices].valve.duration.minutes < 60;"
}
}
},
"allOf": [
{
"if": {
"properties": {
"minutes": { "maximum": 59 }
},
"required": [ "minutes" ]
},
"then": {
"required": [ "seconds" ]
}
}
]
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'valve';"
}
},
"window": {
"title": "Window",
"$ref": "#/$defs/doorAndWindowAccessory",
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'window';"
}
},
"windowCovering": {
"title": "Window Covering",
"$ref": "#/$defs/doorAndWindowAccessory",
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'windowcovering';"
}
},
"sensor": {
"title": "Sensor - Triggered",
"type": "object",
"properties": {
"type": {
"title": "Type *",
"description": "Sensor type (Critical sensor notifications bypass 'Do Not Disturb' focus mode)",
"type": "string",
"oneOf": [
{ "title": "Contact", "enum": ["contact"] },
{ "title": "Leak (critical)", "enum": ["leak"] },
{ "title": "Motion", "enum": ["motion"] },
{ "title": "Occupancy", "enum": ["occupancy"] },
{ "title": "Carbon Dioxide (critical)", "enum": ["carbonDioxide"] },
{ "title": "Carbon Monoxide (critical)", "enum": ["carbonMonoxide"] },
{ "title": "Smoke (critical)", "enum": ["smoke"] }
]
},
"trigger": {
"title": "Trigger *",
"type": "string",
"oneOf": [
{ "title": "Ping Host", "enum": ["ping"] },
{ "title": "Cron Schedule", "enum": ["cron"] },
{ "title": "Sun Events (Sunrise/Sunset)", "enum": ["sunevents"] },
{ "title": "Webhook", "enum": ["webhook"] },
{ "title": "Homebridge Startup Trigger", "enum": ["startup"] },
{ "title": "Ikea Matter Stock Trigger", "enum": ["ikeamatterstock"] }
]
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'sensor';"
}
},
"measurement": {
"title": "Sensor - Measurement",
"type": "object",
"properties": {
"type": {
"title": "Type *",
"description": "Sensor type (Critical sensor notifications bypass 'Do Not Disturb' focus mode)",
"type": "string",
"oneOf": [
{ "title": "Humidity", "enum": ["humidity"] },
{ "title": "Temperature", "enum": ["temperature"] }
]
},
"temperatureUnits": {
"title": "Temperature Units *",
"type": "string",
"oneOf": [
{ "title": "Celsius (ºC)", "enum": ["celsius"] },
{ "title": "Fahrenheit (ºF)", "enum": ["fahrenheit"] }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].measurement && model.devices[arrayIndices].measurement.type === 'temperature';"
}
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].accessoryType === 'measurement';"
},
"allOf": [
{
"if": {
"properties": {
"type": { "const": "temperature" }
},
"required": [ "type" ]
},
"then": {
"required": [ "temperatureUnits" ]
}
}
]
},
"resetTimer": {
"title": "Reset Timer",
"type": "object",
"properties": {
"durationIsRandom": {
"title": "Duration is Random",
"type": "boolean"
},
"duration": {
"title": "Duration",
"description": "Timer reset delay (7 days max)",
"type": "object",
"properties": {
"days": { "$ref": "#/$defs/duration/properties/days" },
"hours": {
"$ref": "#/$defs/duration/properties/hours",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.duration && model.devices[arrayIndices].resetTimer.duration.days < 7;"
}
},
"minutes": {
"$ref": "#/$defs/duration/properties/minutes",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.duration && model.devices[arrayIndices].resetTimer.duration.days < 7;"
}
},
"seconds": {
"$ref": "#/$defs/duration/properties/seconds",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.duration && model.devices[arrayIndices].resetTimer.duration.days < 7;"
}
}
},
"allOf": [
{ "$ref": "#/$defs/requireHoursMinutesSeconds" }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer.durationIsRandom !== true;"
}
},
"durationRandomMin": {
"title": "Min Duration",
"description": "Minimum timer reset delay (7 days max)",
"type": "object",
"properties": {
"days": { "$ref": "#/$defs/duration/properties/days" },
"hours": {
"$ref": "#/$defs/duration/properties/hours",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMin && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
}
},
"minutes": {
"$ref": "#/$defs/duration/properties/minutes",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMin && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
}
},
"seconds": {
"$ref": "#/$defs/duration/properties/seconds",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMin && model.devices[arrayIndices].resetTimer.durationRandomMin.days < 7;"
}
}
},
"allOf": [
{ "$ref": "#/$defs/requireHoursMinutesSeconds" }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.durationIsRandom === true;"
}
},
"durationRandomMax": {
"title": "Max Duration",
"description": "Maximum timer reset delay (7 days max)",
"type": "object",
"properties": {
"days": { "$ref": "#/$defs/duration/properties/days" },
"hours": {
"$ref": "#/$defs/duration/properties/hours",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMax && model.devices[arrayIndices].resetTimer.durationRandomMax.days < 7;"
}
},
"minutes": {
"$ref": "#/$defs/duration/properties/minutes",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMax && model.devices[arrayIndices].resetTimer.durationRandomMax.days < 7;"
}
},
"seconds": {
"$ref": "#/$defs/duration/properties/seconds",
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer.durationRandomMax && model.devices[arrayIndices].resetTimer.durationRandomMax.days < 7;"
}
}
},
"allOf": [
{ "$ref": "#/$defs/requireHoursMinutesSeconds" }
],
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.durationIsRandom === true;"
}
},
"": {
"title": "",
"description": "Note: The minimum duration value **must be shorter** than the maximum duration value",
"type": "object",
"properties": {},
"condition": {
"functionBody": "return model.devices[arrayIndices].resetTimer && model.devices[arrayIndices].resetTimer.durationIsRandom === true;"
}
},
"isResettable": {
"title": "Is Resettable",
"description": "The timer is reset every time the accessory is triggered, even if the state of the accessory does not change",
"type": "boolean"
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].switch && model.devices[arrayIndices].switch.hasResetTimer === true;"
},
"allOf": [
{
"if": {
"properties": {
"durationIsRandom": { "const": true }
},
"required": [ "durationIsRandom" ]
},
"then": {
"required": [ "durationRandomMin", "durationRandomMax" ],
"properties": {
"durationRandomMin": {
"required": [ "days" ]
},
"durationRandomMax": {
"required": [ "days" ]
}
}
},
"else": {
"required": [ "duration" ],
"properties": {
"duration": {
"required": [ "days" ]
}
}
}
}
]
},
"companionSensor": {
"title": "Companion Sensor",
"type": "object",
"properties": {
"name": {
"title": "Name *",
"description": "Sensor name as it will be displayed in HomeKit",
"type": "string"
},
"type": {
"title": "Type *",
"description": "Sensor type triggered by accessory state change (Critical sensor notifications bypass 'Do Not Disturb' focus mode)",
"type": "string",
"oneOf": [
{ "title": "Contact", "enum": ["contact"] },
{ "title": "Leak (critical)", "enum": ["leak"] },
{ "title": "Motion", "enum": ["motion"] },
{ "title": "Occupancy", "enum": ["occupancy"] },
{ "title": "Carbon Dioxide (critical)", "enum": ["carbonDioxide"] },
{ "title": "Carbon Monoxide (critical)", "enum": ["carbonMonoxide"] },
{ "title": "Smoke (critical)", "enum": ["smoke"] }
]
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].switch && model.devices[arrayIndices].switch.hasCompanionSensor === true;"
}
},
"pingTrigger": {
"title": "Ping Host Trigger",
"type": "object",
"properties": {
"host": {
"title": "Host *",
"description": "IP address (142.250.178.4) or domain name (www.google.com) of host to ping",
"placeholder": "192.168.0.1",
"type": "string"
},
"failureRetryCount": {
"title": "Retries Before Failure *",
"description": "Failed ping count before triggering the sensor",
"type": "integer",
"minimum": 0
},
"isDisabled": {
"title": "Disable Trigger",
"description": "Turn off/on trigger",
"type": "boolean"
}
},
"condition": {
"functionBody": "return model.devices[arrayIndices].sensor && model.devices[arrayIndices].sensor.trigger === 'ping';"
}
},
"cronTrigger": {
"title": "Cron Schedule Trigger",
"type": "object",
"properties": {
"pattern": {
"title": "Cron Pattern *",
"description": "Standard unix cron pattern - minute, hour, day, month, weekday (https://crontab.guru/)",
"type": "string",
"placeholder": "* * * * *",
"pattern": "(^((\\*\\/)?([0-5]?[0-9])((,|-|\\/)([0-5]?[0-9]))*|\\*)\\s((\\*\\/)?((2[0-3]|1[0-9]|[0-9]|00))((,|-|\\/)(2[0-3]|1[0-9]|[0-9]|00))*|\\*)\\s((\\*\\/)?([1-9]|[12][0-9]|3[01])((,|-|\\/)([1-9]|[12][0-9]|3[01]))*|\\*)\\s((\\*\\/)?([1-9]|1[0-2])((,|-|\\/)([1-9]|1[0-2]))*|\\*|(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec))\\s((\\*\\/)?[0-6]((,|-|\\/)[0-6])*|\\*|00|(sun|mon|tue|wed|thu|fri|sat))$)"
},
"zoneId": {
"title": "Zone Id",
"description": "Zone id (https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). Defaults to system zone id",
"placeholder": "America/Los_Angeles",
"type": "string",
"pattern": "^(?:(?:[A-Za-z_\\-]+\/[A-Za-z_\\-]+(?:\/[A-Za-z_\\-]+)?)|(?:Etc\/[A-Za-z0-9+\\-]