Skip to content

Getting Started

Build your first Haptique OS driver in about 10 minutes. No prior knowledge of the HOS codebase required.


Prerequisites

  • Node.js 20 or later installed (nodejs.org)
  • A running HOS server — see Dev Setup if you need to spin one up locally, or point at any existing HOS instance on your network

Set the server WebSocket URL before running any driver:

bash
export HOS_WS_URL=ws://localhost:8080/driver

8080 is the default port. Adjust if your server uses a different DRIVER_WS_PORT.


1. Install the SDK

bash
npm install @haptique/driver-sdk

This installs HosDriver — the TypeScript client class that wraps the WebSocket protocol for you.


2. Run the Sample Driver

Create a file my-driver.ts and paste the minimal driver below (or see the full sample in Driver Lifecycle):

typescript
import { HosDriver } from '@haptique/driver-sdk';

const driver = new HosDriver({
    driverKey: 'SIMULATED',
    instanceId: 'simulated-001',
    wsUrl: process.env.HOS_WS_URL ?? 'ws://localhost:8080/driver',
});

driver.on('registered', () => {
    driver.sendEvent('DEVICE_DISCOVERED', {
        device_id: 'sim-light-001',
        data: {
            name: 'Simulated Light',
            deviceType: 'light',
            properties: {
                commandCatalog: [
                    { key: 'turn_on',  label: 'Turn On'  },
                    { key: 'turn_off', label: 'Turn Off' },
                ],
            },
        },
    });
    driver.sendEvent('STATE_UPDATE', {
        device_id: 'sim-light-001',
        data: { power: false, brightness: 0 },
    });
});

driver.connect();

Run it:

bash
npx ts-node my-driver.ts

You should see:

[simulated] Starting simulated device driver...
[simulated] Connected to HOS server
[simulated] Registered with HOS server
[simulated] Discovered sim-light-001, initial state: power=false

The driver is now live. Open the HOS mobile app or admin panel — you'll see a device named "Simulated Light" appear.


3. Understand the Four Calls

Every HOS driver is built on the same four operations:

Construct the driver

typescript
import { HosDriver } from '@haptique/driver-sdk';

const driver = new HosDriver({
    driverKey: 'MY_DRIVER',        // Unique identifier: [A-Z0-9_], 2-64 chars
    instanceId: 'my-driver-001',   // Runtime instance ID: [a-zA-Z0-9:_-], 1-128 chars
    wsUrl: process.env.HOS_WS_URL ?? 'ws://localhost:8080/driver',
    name: 'My First Driver',       // Display name shown in HOS UI
});

driver.connect();

Announce devices after registration

typescript
driver.on('registered', () => {
    driver.sendEvent('DEVICE_DISCOVERED', {
        device_id: 'my-light-001',
        data: {
            name: 'Living Room Light',
            deviceType: 'light',
            properties: {
                commandCatalog: [
                    { key: 'turn_on',  label: 'Turn On'  },
                    { key: 'turn_off', label: 'Turn Off' },
                ],
            },
        },
    });

    driver.sendEvent('STATE_UPDATE', {
        device_id: 'my-light-001',
        data: { power: false, brightness: 0 },
    });
});

Handle commands

typescript
driver.onAction((msg) => {
    const action = msg.data.action;

    driver.sendEvent('ACTION_RESULT', {
        device_id: msg.device_id,
        data: { success: true, requestId: msg.data.requestId as string | undefined },
    });

    if (action === 'turn_on') {
        driver.sendEvent('STATE_UPDATE', {
            device_id: msg.device_id,
            data: { power: true, brightness: 100 },
        });
    } else if (action === 'turn_off') {
        driver.sendEvent('STATE_UPDATE', {
            device_id: msg.device_id,
            data: { power: false, brightness: 0 },
        });
    }
});

Shut down cleanly

typescript
process.on('SIGTERM', () => driver.disconnect());
process.on('SIGINT',  () => driver.disconnect());

4. Want to Upload a Driver Package?

If you want to ship a driver as an uploadable OS-local package (ZIP file) rather than running an external WebSocket process, see Driver Manifest — it covers the package format for Python, Lua, and JavaScript local drivers.


What's Next

  • Driver Lifecycle — Full walkthrough of every phase: startup, registration, discovery, commands, reconnection, and shutdown
  • Driver Architecture — How commands flow from mobile app → HOS → your driver and back
  • Domain Reference — Device types, state fields, and command names for Lighting, AV/Media, Climate, Security, and Robot Vacuums
  • Driver Manifest — Building an uploadable OS-local driver package