Skip to content

hap-fluent / getOrAddService

Function: getOrAddService()

ts
function getOrAddService<T>(
   platformAccessory, 
   serviceClass, 
   displayName?, 
subType?): FluentService<T>;

Defined in: packages/hap-fluent/src/FluentService.ts:206

Retrieve an existing service from an accessory, or create and attach a new one, then wrap it with the fluent helper interface.

Type Parameters

Type Parameter
T extends typeof Service

Parameters

ParameterTypeDescription
platformAccessoryPlatformAccessoryHomebridge PlatformAccessory that owns the service.
serviceClassWithUUID<T>HAP service constructor with a UUID (e.g., hap.Service.Lightbulb).
displayName?stringHuman-readable name shown in the Home app for this service.
subType?stringOptional stable identifier for disambiguating multiple services of the same class on the same accessory.

Returns

FluentService<T>

A FluentService wrapping the retrieved or newly-created service.

Remarks

This is the primary entry-point for working with HAP services in hap-fluent. It calls platformAccessory.getServiceById() (when subType is provided) or platformAccessory.getService() first, and only instantiates a new service when none is found. The newly-created service is immediately added to the accessory via platformAccessory.addService().

Use subType to differentiate multiple instances of the same service class (e.g., two Outlet services on a power strip). The subtype string must be stable across plugin restarts — HomeKit uses it to track the same logical service across accessory cache refreshes.

Throws

If serviceClass is not a constructor or lacks a UUID property.

Use When

  • Adding a service to an accessory in your plugin's constructor or configureAccessory() method.
  • Idempotently initializing a service that may already exist in the cached accessory state across Homebridge restarts.

Avoid When

  • You already hold a raw Service instance — use wrapService directly to avoid the extra lookup overhead.

Pitfalls

  • NEVER call getOrAddService() after the accessory has been published via api.registerPlatformAccessories() — adding services post-publish results in the new service being invisible to the iOS Home controller until the next full accessory cache eviction (which requires the user to remove and re-add the accessory).
  • NEVER use a dynamic or session-based subType — the subtype must be the same string on every Homebridge startup or HomeKit will treat the service as a new, duplicate service and duplicate entries appear in the Home app.

Example

typescript
import { getOrAddService } from 'hap-fluent';

// Single service
const lightbulb = getOrAddService(accessory, hap.Service.Lightbulb, 'Ceiling Light');

// Multiple outlets on a power strip, differentiated by subType
const outlet1 = getOrAddService(accessory, hap.Service.Outlet, 'Left Outlet', 'outlet-1');
const outlet2 = getOrAddService(accessory, hap.Service.Outlet, 'Right Outlet', 'outlet-2');

Released under the Apache-2.0 License.