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.
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;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);
});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);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]
});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
}
]
}
};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);
}
}
});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);
}
}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');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);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;