Skip to content

Driver Manifest

The driver manifest is the metadata file that describes an OS-local driver package. It controls how HOS displays your integration in the UI, generates the setup form, builds the command catalog, and launches the driver at runtime.

This page covers the OS-local package path — drivers uploaded as a ZIP through the Integration Manager. If you are building an external WebSocket driver (using the SDK), you do not need a manifest; see Getting Started.


Package Structure

An uploadable driver package is a ZIP file containing:

my-driver.zip
├── my-driver.driver.json   ← manifest (required, exactly one *.driver.json)
├── driver.js               ← implementation (required, one of .js / .py / .lua)
└── README.md               ← optional documentation

A package.json may be included for JavaScript drivers that require external npm dependencies. Prefer dependency-free packages for v1 — use Node 20+ built-ins (fetch, net, dgram, readline) where possible.


Runtime Targets

RuntimeFile extensionNotes
javascript.jsFirst-class local driver. Node-compatible CommonJS, newline-delimited JSON over stdin/stdout.
python.pySame JSON-line process contract as JavaScript.
lua.luaCommand-oriented local runtime.
typescriptcompiled .jsAuthoring option only — raw .ts is not accepted in ZIP uploads. Compile to .js first.

Manifest Fields

Top-level

jsonc
{
    "driverKey": "MY_DEVICE",           // Required. Uppercase [A-Z0-9_], 2-64 chars
    "driverType": "javascript",         // Required. "javascript" | "python" | "lua"
    "driverFile": "driver.js",          // Required. Points to the implementation file
    "name": "My Device Integration",   // Display name in Integration Manager
    "version": "1.0.0",                 // Semver version string
    "description": "Controls My Device via HTTP API",
    "author": "Your Name",
    "properties": [ ... ],              // Setup form fields (see below)
    "commands": [ ... ],               // User-visible command catalog (see below)
    "io": { ... },                      // Integration topology (see below)
    "envMap": { ... }                   // Maps setup properties → env vars (see below)
}

properties — Setup Form

properties defines the fields shown in the Integration Manager setup form when a user installs your driver. Each entry becomes an environment variable available to the driver at runtime (via envMap).

jsonc
"properties": [
    {
        "key": "DEVICE_IP",
        "label": "Device IP Address",
        "type": "text",
        "required": true,
        "placeholder": "192.168.1.100",
        "description": "Local IP address of the device on your network"
    },
    {
        "key": "API_KEY",
        "label": "API Key",
        "type": "password",
        "required": true
    },
    {
        "key": "POLL_INTERVAL",
        "label": "Poll Interval (seconds)",
        "type": "number",
        "required": false,
        "default": "5"
    }
]

Field types: text, password, number, boolean, select


commands — Command Catalog

commands defines the user-visible actions exposed in the HOS mobile app and admin UI. These must correspond to ACTION keys your driver handles.

jsonc
"commands": [
    {
        "key": "turn_on",
        "label": "Turn On",
        "description": "Power on the device"
    },
    {
        "key": "set_brightness",
        "label": "Set Brightness",
        "description": "Set brightness 0-100",
        "payloadSchema": {
            "type": "object",
            "properties": {
                "level": { "type": "number", "minimum": 0, "maximum": 100 }
            },
            "required": ["level"]
        }
    }
]

io — Integration Topology

io describes the integration's inputs and outputs for display in the topology/wiring UI.

jsonc
"io": {
    "inputs": [
        { "key": "trigger", "label": "Trigger", "type": "event" }
    ],
    "outputs": [
        { "key": "state", "label": "Device State", "type": "state" }
    ]
}

envMap — Property → Environment Variable Mapping

envMap maps properties keys to the environment variable names your driver reads at runtime. This keeps credentials out of source code.

jsonc
"envMap": {
    "DEVICE_IP":      "DEVICE_IP",
    "API_KEY":        "MY_DEVICE_API_KEY",
    "POLL_INTERVAL":  "POLL_INTERVAL_SECS"
}

At runtime, your driver reads these as process.env.DEVICE_IP, process.env.MY_DEVICE_API_KEY, etc.


Complete Example

jsonc
{
    "driverKey": "SMART_BULB",
    "driverType": "javascript",
    "driverFile": "driver.js",
    "name": "Smart Bulb",
    "version": "1.0.0",
    "description": "Controls Smart Bulb lights via local HTTP API",
    "author": "Haptique",
    "properties": [
        {
            "key": "BRIDGE_IP",
            "label": "Bridge IP",
            "type": "text",
            "required": true,
            "placeholder": "192.168.1.100"
        },
        {
            "key": "BRIDGE_KEY",
            "label": "Bridge API Key",
            "type": "password",
            "required": true
        }
    ],
    "commands": [
        { "key": "turn_on",  "label": "Turn On"  },
        { "key": "turn_off", "label": "Turn Off" },
        {
            "key": "set_brightness",
            "label": "Set Brightness",
            "payloadSchema": {
                "type": "object",
                "properties": {
                    "level": { "type": "number", "minimum": 0, "maximum": 100 }
                },
                "required": ["level"]
            }
        }
    ],
    "io": {
        "inputs": [],
        "outputs": [
            { "key": "state", "label": "Light State", "type": "state" }
        ]
    },
    "envMap": {
        "BRIDGE_IP":  "BRIDGE_IP",
        "BRIDGE_KEY": "BRIDGE_API_KEY"
    }
}

JavaScript Driver Protocol

JavaScript local drivers use newline-delimited JSON over stdin/stdout — the same protocol contract as Python drivers.

From HOS to driver (stdin):

json
{"event":"ACTION","device_id":"bulb-001","data":{"action":"turn_on","requestId":"req-123"}}

From driver to HOS (stdout):

json
{"event":"DEVICE_DISCOVERED","device_id":"bulb-001","data":{"name":"Bedroom Bulb","deviceType":"light","properties":{"commandCatalog":[{"key":"turn_on","label":"Turn On"}]}}}
{"event":"STATE_UPDATE","device_id":"bulb-001","data":{"power":false,"brightness":0}}
{"event":"ACTION_RESULT","device_id":"bulb-001","data":{"success":true,"requestId":"req-123"}}

Each line is a complete JSON object. Do not emit multi-line JSON.


AI Driver Builder

The AI Driver Builder can generate a complete driver package — manifest + implementation + README — from a plain-language description of the device protocol. This is the fastest path if you are building a net-new integration.


What's Next