Skip to Content
API Reference

API Reference

Channel Abstraction

All devices expose one or two independent channels. Each channel declares its own capabilities — consumer code never needs to check the device model.

YeelightDevice ├── main: LightChannel always present └── background: LightChannel | null dual-zone devices only

YeelightDevice

The main entry point. Handles discovery, connection, and exposes channels.

class YeelightDevice { static discover(opts?: { timeout?: number }): Promise<YeelightDevice[]> static scan(): Promise<YeelightDevice[]> static connect(ip: string, port?: number, opts?: { discover?: boolean }): Promise<YeelightDevice> readonly id: string readonly ip: string readonly model: string readonly name: string readonly support: string[] readonly capabilities: Capabilities readonly main: LightChannel readonly background: LightChannel | null connect(): Promise<void> disconnect(): void isConnected(): boolean setScene(scene: SceneConfig): Promise<void> // delegates to main setName(name: string): Promise<void> devToggle(): Promise<void> // dual-zone devices only cronAdd(minutes: number): Promise<void> cronDel(): Promise<void> cronGet(): Promise<CronTimer | null> // active timer or null getRawProps(props: string[]): Promise<Record<string, string>> on(event: 'props', listener: (props: Partial<ChannelState>) => void): this on(event: 'disconnect', listener: () => void): this off(event: string, listener: Function): this }

discover() uses SSDP multicast. scan() discovers via TCP port scan of the local /24 subnet — useful when SSDP multicast is blocked on the network. Both return devices that are not yet connected; call device.connect() before sending commands.

connect(ip) by default resolves device metadata (model, name, support list) via unicast SSDP; falls back to get_prop probe if SSDP times out. Pass { discover: false } to skip all discovery — pure TCP handshake, full capabilities assumed. Useful for single-shot CLI commands where the caller already knows what the device supports.

lamp15 extension — only present when capabilities.hasSegments:

setSegments( left: [number, number, number], right: [number, number, number] ): Promise<void>

LightChannel

Primary unit of interaction. Wraps Transport with a command prefix ("" for main, "bg_" for background).

class LightChannel { readonly type: 'main' | 'background' readonly capabilities: ChannelCapabilities setPower(on: boolean, opts?: PowerOptions): Promise<void> toggle(): Promise<void> setBrightness(value: number, opts?: TransitionOptions): Promise<void> // Requires capabilities.hasColorTemp — throws UnsupportedError otherwise setColorTemp(kelvin: number, opts?: TransitionOptions): Promise<void> // Require capabilities.hasColor — throw UnsupportedError otherwise setRGB( r: number, g: number, b: number, opts?: TransitionOptions ): Promise<void> setHSV( hue: number, saturation: number, opts?: TransitionOptions ): Promise<void> // Requires capabilities.hasFlow — throws UnsupportedError otherwise startFlow(flow: Flow): Promise<void> stopFlow(): Promise<void> // Turn on and apply state atomically (works on both main and background) setScene(scene: SceneConfig): Promise<void> setDefault(): Promise<void> // Relative adjustments — no need to know the current value setAdjust( action: 'increase' | 'decrease' | 'circle', prop: 'bright' | 'ct' ): Promise<void> setAdjust(action: 'circle', prop: 'color'): Promise<void> adjustBrightness(percentage: number, duration?: number): Promise<void> adjustColorTemp(percentage: number, duration?: number): Promise<void> adjustColor(duration?: number): Promise<void> getState(): Promise<ChannelState> }

Calling setRGB() on a CT-only channel throws UnsupportedError at call time, not silently at runtime.


Flow Builder

class Flow { static builder(): FlowBuilder // Presets static pulse( r: number, g: number, b: number, opts?: { count?: number; duration?: number } ): Flow static strobe( r: number, g: number, b: number, opts?: { count?: number } ): Flow static colorCycle(opts?: { duration?: number }): Flow static candle(): Flow static sunrise(durationMs: number): Flow } class FlowBuilder { repeat(count: number): this onEnd(action: 'recover' | 'stay' | 'off'): this rgb( r: number, g: number, b: number, opts: { duration: number; brightness?: number } ): this colorTemp( kelvin: number, opts: { duration: number; brightness?: number } ): this sleep(ms: number): this build(): Flow }

Errors

class UnsupportedError extends Error {} // method called on incapable channel class ConnectionError extends Error {} // TCP connect/send failure class DeviceError extends Error { code: number // device responded with error object }

Shared Types

interface TransitionOptions { effect?: 'smooth' | 'sudden' // default: 'smooth' duration?: number // ms, default: 300 } /** 0=normal, 1=CT, 2=RGB, 3=HSV, 4=color flow, 5=night (ceiling lights only) */ type PowerMode = 0 | 1 | 2 | 3 | 4 | 5 interface PowerOptions extends TransitionOptions { mode?: PowerMode } interface ChannelState { power: boolean brightness: number // 1–100 colorTemp: number | null // Kelvin, null if channel has no CT rgb: [number, number, number] | null // null if channel has no color flowing: boolean } type SceneConfig = | { type: 'color'; rgb: [number, number, number]; brightness: number } | { type: 'hsv'; hue: number; saturation: number; brightness: number } | { type: 'ct'; colorTemp: number; brightness: number } | { type: 'cf'; flow: Flow } | { type: 'auto_delay_off'; brightness: number; minutes: number } interface Capabilities { hasBackground: boolean hasSegments: boolean main: ChannelCapabilities background: ChannelCapabilities | null } interface ChannelCapabilities { hasColor: boolean hasColorTemp: boolean hasFlow: boolean } interface CronTimer { delay: number // remaining minutes until power-off }

Exports

export { YeelightDevice } from 'yeelight-client' export { Flow, FlowBuilder } from 'yeelight-client' export { UnsupportedError, ConnectionError, DeviceError } from 'yeelight-client' export type { ChannelState, TransitionOptions, PowerMode, PowerOptions, SceneConfig, ChannelCapabilities, CronTimer } from 'yeelight-client' export type { Capabilities } from 'yeelight-client'

LightChannel is not constructable directly — instances come from device.main / device.background only.

Last updated on