import { Logger } from "homebridge"; import { UserInputConfig } from "./model/userInputConfig.js"; export declare enum PlejdCommand { OnOffState = "0097", StateBrightness = "00c8", Brightness = "0098",// 0-255 Scene = "0021", Time = "001b", RequestResponse = "0102", RequestNoResponse = "0110", RequestReadValue = "0103", ButtonClick = "0006", OutputSet = "0420", EventPrepare = "0015", EventFired = "0016" } export declare class PlejdService { private readonly config; readonly log: Logger; private readonly onUpdate; private readonly onButtonEvent?; private sendQueue; private pingInterval; private queueInterval; private discoverHandler; private loopGeneration; private failedDevices; private connectedSince; private static readonly PROBE_NEEDED; constructor(config: UserInputConfig, log: Logger, onUpdate: (identifier: number, isOn: boolean, dim?: number) => void, onButtonEvent?: ((deviceAddress: number, buttonIndex: number, action: "press" | "release") => void) | undefined); /** * @returns the current queue items */ readQueue(): Buffer[]; /** * Update the state of a device * * @param identifier: The device identifier * @param turnOn: The new state of the device * @param opt.targetBrightness: The new brightness of the device between 0-100 * @param opt.currentBrightness: The current brightness of the device between 0-100 * @param opt.transitionMs: split brightness into steps, adding a transition to the brightness change */ updateState: (identifier: number, turnOn: boolean, opt?: { targetBrightness?: number; currentBrightness?: number; transitionMs?: number; }) => Promise; /** * Trigger a Plejd scene * * @param sceneIndex - The scene index from sceneIndex mapping */ triggerScene: (sceneIndex: number) => void; configureBLE: () => void; /** * Cancel any in-flight connection loop by incrementing the generation counter. * Stops timers, scanning, and removes discover handler. */ private cancelLoop; /** * Main connection loop. Cancels any previous loop, then repeatedly * attempts to connect until the generation changes (poweredOff). */ private runLoop; /** * Single connection attempt: scan → connect → discover → auth → probe → run. * Throws on any failure so the outer loop can retry. */ private connectAndRun; /** * Scans for the first suitable Plejd peripheral. * Returns the peripheral and its resolved address (or PROBE_NEEDED). */ private scanForDevice; private discoverCharacteristics; private authenticate; /** * Determines the connected device's MAC by listening for mesh notifications * and trying to decode them with each known device's MAC. * A valid decode (known command code) identifies the correct MAC. */ private probeDeviceAddress; /** * Runs the connected session: ping, queue processing, and notification handling. * Returns a promise that rejects when the connection is lost. */ private runConnected; private startPing; private stopPing; private startQueue; private stopQueue; /** * Extracts the device MAC address from a peripheral using multiple strategies: * 1. peripheral.address (Linux - noble exposes it directly) * 2. Manufacturer data bytes 6-11 reversed (Plejd mesh advertisements) * 3. Single-device fallback (if only one device configured) */ private extractAddress; /** * Plejd manufacturer data (19 bytes): * [0-1] Company ID (0x0377) * [2-4] Header * [5] Varies * [6-11] Device MAC address (reversed byte order) * [12-17] Stable mesh identifier * [18] Padding (0x00) * * Bytes 6-11 may contain the advertising device's MAC or a relayed * device's MAC. We check against known devices to filter. */ private extractAddressFromManufacturerData; /** * Sends CMD_EVENT_PREPARE to enable (or re-arm) button event reporting. * Must be sent once after connection and again after each CMD_EVENT_FIRED. */ private sendEventPrepare; private handleNotification; private removeDiscoverHandler; private formatUptime; private tryDisconnect; }