hap-fluent / getOrAddService
Function: getOrAddService()
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
| Parameter | Type | Description |
|---|---|---|
platformAccessory | PlatformAccessory | Homebridge PlatformAccessory that owns the service. |
serviceClass | WithUUID<T> | HAP service constructor with a UUID (e.g., hap.Service.Lightbulb). |
displayName? | string | Human-readable name shown in the Home app for this service. |
subType? | string | Optional stable identifier for disambiguating multiple services of the same class on the same accessory. |
Returns
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
Serviceinstance — use wrapService directly to avoid the extra lookup overhead.
Pitfalls
- NEVER call
getOrAddService()after the accessory has been published viaapi.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
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');