or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcore-api.mdhap-integration.mdindex.mdlogging.mdplatform-accessories.mdplugin-system.md
tile.json

hap-integration.mddocs/

HAP-NodeJS Integration

Homebridge provides complete integration with Apple's HomeKit Accessory Protocol (HAP) implementation through HAP-NodeJS. This integration includes direct exports of all const enums, type-only exports of classes and interfaces, and access to the complete HAP-NodeJS library through the API object.

Capabilities

HAP Library Access

Access to the complete HAP-NodeJS library through the API object.

/**
 * Complete HAP-NodeJS library type
 * Provides access to all HAP-NodeJS functionality
 */
type HAP = typeof import("hap-nodejs");

/**
 * Legacy HAP-NodeJS types for backward compatibility
 */
type HAPLegacyTypes = typeof import("hap-nodejs").LegacyTypes;

Usage Examples:

// Access HAP through the API
export = (api: API) => {
  const { Service, Characteristic, Categories } = api.hap;
  
  api.registerAccessory("my-plugin", "MyLight", class {
    constructor(log: Logger, config: any) {
      this.service = new Service.Lightbulb(config.name);
      this.service.getCharacteristic(Characteristic.On)
        .onGet(() => this.getState())
        .onSet((value) => this.setState(value));
    }
    
    getServices() {
      return [this.service];
    }
  });
};

// Access legacy types if needed
const legacyTypes = api.hapLegacyTypes;

Core HomeKit Enums

Directly exported const enums that are inlined at compile time for optimal performance.

Access Control & Security:

/** Access permissions for characteristics */
enum Access {
  READ = 0x01,
  WRITE = 0x02,
  NOTIFY = 0x04,
  BROADCAST_ENCRYPTION = 0x08,
  HIDDEN = 0x10,
  WRITE_RESPONSE = 0x20
}

/** Access control event types */
enum AccessControlEvent {
  CONFIGURATION_CHANGED = "configuration-changed"
}

/** User access levels */
enum AccessLevel {
  ADMIN = 0x00,
  USER = 0x01
}

Accessory & Service Events:

/** Accessory-level event types */
enum AccessoryEventTypes {
  IDENTIFY = "identify",
  LISTENING = "listening",
  ADVERTISED = "advertised",
  PAIRED = "paired",
  UNPAIRED = "unpaired",
  CHARACTERISTIC_CHANGE = "characteristic-change",
  SERVICE_CONFIGURATION_CHANGE = "service-configurationChange",
  SETUP_URI = "setupURI"
}

/** Service-level event types */
enum ServiceEventTypes {
  CHARACTERISTIC_CHANGE = "characteristic-change",
  SERVICE_CONFIGURATION_CHANGE = "service-configurationChange"
}

/** Characteristic-level event types */
enum CharacteristicEventTypes {
  GET = "get",
  SET = "set",
  SUBSCRIBE = "subscribe",
  UNSUBSCRIBE = "unsubscribe",
  CHANGE = "change"
}

Usage Examples:

// Using access permissions
service.getCharacteristic(Characteristic.Brightness)
  .setProps({
    minValue: 0,
    maxValue: 100,
    perms: [Access.READ, Access.WRITE, Access.NOTIFY]
  });

// Listening for accessory events
accessory.on(AccessoryEventTypes.IDENTIFY, () => {
  console.log("Accessory identification requested");
});

// Listening for characteristic changes
characteristic.on(CharacteristicEventTypes.CHANGE, ({ oldValue, newValue }) => {
  console.log("Value changed from", oldValue, "to", newValue);
});

HomeKit Categories

Device categories that determine the HomeKit icon and functionality.

/** HomeKit accessory categories */
enum Categories {
  OTHER = 1,
  BRIDGE = 2,
  FAN = 3,
  GARAGE_DOOR_OPENER = 4,
  LIGHTBULB = 5,
  DOOR_LOCK = 6,
  OUTLET = 7,
  SWITCH = 8,
  THERMOSTAT = 9,
  SENSOR = 10,
  SECURITY_SYSTEM = 11,
  DOOR = 12,
  WINDOW = 13,
  WINDOW_COVERING = 14,
  PROGRAMMABLE_SWITCH = 15,
  RANGE_EXTENDER = 16,
  IP_CAMERA = 17,
  VIDEO_DOORBELL = 18,
  AIR_PURIFIER = 19,
  HEATER = 20,
  AIR_CONDITIONER = 21,
  HUMIDIFIER = 22,
  DEHUMIDIFIER = 23,
  APPLE_TV = 24,
  HOMEPOD = 25,
  SPEAKER = 26,
  AIRPORT = 27,
  SPRINKLER = 28,
  FAUCET = 29,
  SHOWER_HEAD = 30,
  TELEVISION = 31,
  TARGET_CONTROLLER = 32,
  ROUTER = 33,
  AUDIO_RECEIVER = 34
}

Usage Examples:

// Create accessories with appropriate categories
const lightAccessory = new PlatformAccessory("Living Room Light", uuid, Categories.LIGHTBULB);
const fanAccessory = new PlatformAccessory("Ceiling Fan", uuid, Categories.FAN);
const cameraAccessory = new PlatformAccessory("Security Camera", uuid, Categories.IP_CAMERA);
const thermostatAccessory = new PlatformAccessory("Main Thermostat", uuid, Categories.THERMOSTAT);

Characteristic Properties

Data formats, permissions, and units for HomeKit characteristics.

/** Data formats for characteristic values */
enum Formats {
  BOOL = "bool",
  INT = "int",
  FLOAT = "float",
  STRING = "string",
  UINT8 = "uint8",
  UINT16 = "uint16",
  UINT32 = "uint32",
  UINT64 = "uint64",
  DATA = "data",
  TLV8 = "tlv8",
  ARRAY = "array",
  DICT = "dict"
}

/** Characteristic permissions */
enum Perms {
  PAIRED_READ = "pr",
  PAIRED_WRITE = "pw", 
  EVENTS = "ev",
  ADDITIONAL_AUTHORIZATION = "aa",
  TIMED_WRITE = "tw",
  HIDDEN = "hd",
  WRITE_RESPONSE = "wr"
}

/** Units of measurement */
enum Units {
  CELSIUS = "celsius",
  FAHRENHEIT = "fahrenheit",
  PERCENTAGE = "percentage",
  ARC_DEGREE = "arcdegrees",
  LUX = "lux",
  SECONDS = "seconds",
  PPM = "ppm",
  MICROGRAMS_PER_CUBIC_METER = "micrograms/m^3"
}

Usage Examples:

// Define characteristic properties
const temperatureCharacteristic = service.getCharacteristic(Characteristic.CurrentTemperature)
  .setProps({
    format: Formats.FLOAT,
    unit: Units.CELSIUS,
    minValue: -50,
    maxValue: 100,
    minStep: 0.1,
    perms: [Perms.PAIRED_READ, Perms.EVENTS]
  });

const brightnessCharacteristic = service.getCharacteristic(Characteristic.Brightness)
  .setProps({
    format: Formats.INT,
    unit: Units.PERCENTAGE,
    minValue: 0,
    maxValue: 100,
    perms: [Perms.PAIRED_READ, Perms.PAIRED_WRITE, Perms.EVENTS]
  });

Audio/Video Streaming

Enums for camera and audio streaming configuration.

/** H.264 video profiles */
enum H264Profile {
  BASELINE = 0x00,
  MAIN = 0x01,
  HIGH = 0x02
}

/** H.264 video levels */
enum H264Level {
  LEVEL3_1 = 0x00,
  LEVEL3_2 = 0x01,
  LEVEL4_0 = 0x02
}

/** Audio streaming codec types */
enum AudioStreamingCodecType {
  PCMU = 0x00,
  PCMA = 0x01, 
  AAC_ELD = 0x02,
  OPUS = 0x03
}

/** Audio streaming sample rates */
enum AudioStreamingSamplerate {
  KHZ_8 = 0x00,
  KHZ_16 = 0x01,
  KHZ_24 = 0x02,
  KHZ_32 = 0x03,
  KHZ_44_1 = 0x04,
  KHZ_48 = 0x05
}

/** SRTP crypto suites */
enum SRTPCryptoSuites {
  AES_CM_128_HMAC_SHA1_80 = 0x00,
  AES_CM_256_HMAC_SHA1_80 = 0x01,
  NONE = 0x02
}

Usage Examples:

// Configure camera streaming options
const streamingOptions = {
  supportedCryptoSuites: [SRTPCryptoSuites.AES_CM_128_HMAC_SHA1_80],
  video: {
    resolutions: [
      [320, 180, 30],
      [320, 240, 15], 
      [1280, 720, 30],
      [1920, 1080, 30]
    ],
    codec: {
      profiles: [H264Profile.BASELINE, H264Profile.MAIN, H264Profile.HIGH],
      levels: [H264Level.LEVEL3_1, H264Level.LEVEL3_2, H264Level.LEVEL4_0]
    }
  },
  audio: {
    twoWayAudio: true,
    codecs: [
      {
        type: AudioStreamingCodecType.AAC_ELD,
        samplerate: AudioStreamingSamplerate.KHZ_16
      },
      {
        type: AudioStreamingCodecType.OPUS,
        samplerate: AudioStreamingSamplerate.KHZ_24
      }
    ]
  }
};

HAP Protocol Status

Status codes and error handling for HomeKit communication.

/** HAP status codes */
enum HAPStatus {
  SUCCESS = 0x00,
  INSUFFICIENT_PRIVILEGES = 0x01,
  SERVICE_COMMUNICATION_FAILURE = 0x02,
  RESOURCE_BUSY = 0x03,
  READ_ONLY_CHARACTERISTIC = 0x04,
  WRITE_ONLY_CHARACTERISTIC = 0x05,
  NOTIFICATION_NOT_SUPPORTED = 0x06,
  OUT_OF_RESOURCE = 0x07,
  OPERATION_TIMED_OUT = 0x08,
  RESOURCE_DOES_NOT_EXIST = 0x09,
  INVALID_VALUE_IN_REQUEST = 0x0A,
  INSUFFICIENT_AUTHORIZATION = 0x0B
}

Usage Examples:

// Handle characteristic operations with proper status codes
characteristic.onSet(async (value) => {
  try {
    await this.setDeviceValue(value);
    return; // Implicit HAPStatus.SUCCESS
  } catch (error) {
    if (error.code === 'DEVICE_BUSY') {
      throw new this.api.hap.HapStatusError(HAPStatus.RESOURCE_BUSY);
    } else if (error.code === 'INVALID_VALUE') {
      throw new this.api.hap.HapStatusError(HAPStatus.INVALID_VALUE_IN_REQUEST);
    } else {
      throw new this.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
    }
  }
});

Controller and Service Classes

Type-only exports of HAP-NodeJS classes for advanced functionality.

/** Core HomeKit classes (type-only exports) */
type Characteristic = import("hap-nodejs").Characteristic;
type Service = import("hap-nodejs").Service;
type HAPServer = import("hap-nodejs").HAPServer;
type HapStatusError = import("hap-nodejs").HapStatusError;

/** Controller classes for advanced accessories */
type CameraController = import("hap-nodejs").CameraController;
type AdaptiveLightingController = import("hap-nodejs").AdaptiveLightingController;
type DoorbellController = import("hap-nodejs").DoorbellController;
type RemoteController = import("hap-nodejs").RemoteController;
type StreamController = import("hap-nodejs").StreamController;

/** Data stream classes */
type DataStreamConnection = import("hap-nodejs").DataStreamConnection;
type DataStreamServer = import("hap-nodejs").DataStreamServer;
type DataStreamManagement = import("hap-nodejs").DataStreamManagement;

Usage Examples:

// Type annotations for HAP classes
class MyCameraAccessory {
  private cameraController: CameraController;
  private streamingDelegate: CameraStreamingDelegate;
  
  constructor(private api: API) {
    this.cameraController = new api.hap.CameraController({
      cameraStreamCount: 2,
      delegate: this.streamingDelegate,
      streamingOptions: this.getStreamingOptions()
    });
  }
}

// Error handling with HAP status errors
async handleCharacteristicGet(): Promise<CharacteristicValue> {
  try {
    return await this.getDeviceState();
  } catch (error) {
    throw new this.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
  }
}

Utility Functions

Type-only exports of HAP-NodeJS utility functions.

/** TLV encoding/decoding functions */
type encode = typeof import("hap-nodejs").encode;
type decode = typeof import("hap-nodejs").decode;
type decodeList = typeof import("hap-nodejs").decodeList;

/** Utility functions */
type clone = typeof import("hap-nodejs").clone;
type once = typeof import("hap-nodejs").once;

/** Time conversion utilities */
type epochMillisFromMillisSince2001_01_01 = typeof import("hap-nodejs").epochMillisFromMillisSince2001_01_01;

Usage Examples:

// Using TLV encoding utilities
const tlvData = api.hap.encode(0x01, Buffer.from("Hello"));
const decoded = api.hap.decode(tlvData);

// Using utility functions  
const clonedObject = api.hap.clone(originalObject);
const onceListener = api.hap.once(emitter, 'event');

Variable Exports

Type-only exports of HAP-NodeJS variables and constants.

/** HAP status codes and constants */
type Codes = typeof import("hap-nodejs").Codes;
type Status = typeof import("hap-nodejs").Status;

/** UUID utilities */
type uuid = typeof import("hap-nodejs").uuid;

/** Legacy type definitions */
type LegacyTypes = typeof import("hap-nodejs").LegacyTypes;

Usage Examples:

// Generate UUIDs for services and characteristics
const customServiceUUID = api.hap.uuid.generate("MyCustomService");
const customCharacteristicUUID = api.hap.uuid.generate("MyCustomCharacteristic");

// Access status codes
const statusCodes = api.hap.Status;
console.log("Success code:", statusCodes.SUCCESS);

Types

type CharacteristicValue = string | number | boolean | null | undefined;
type ServiceId = string;
type SessionIdentifier = string;
type WithUUID<T> = T & { UUID: string };
type Nullable<T> = T | null;
type VoidCallback = (error?: Error | null) => void;
type NodeCallback<T> = (error: Error | null, value?: T) => void;