{"id":47641572,"url":"https://github.com/numberonebot/yeelight-client","last_synced_at":"2026-04-24T01:05:52.995Z","repository":{"id":346030926,"uuid":"1188166368","full_name":"NumberOneBot/yeelight-client","owner":"NumberOneBot","description":"TypeScript library + CLI for controlling 💡 Yeelight smart lights over LAN","archived":false,"fork":false,"pushed_at":"2026-03-30T14:44:45.000Z","size":682,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T00:39:02.713Z","etag":null,"topics":["bun","cli","home-automation","iot","lan","library","node","npm-package","smart-home","smart-lights","typescript","yeelight","yeelight-api","yeelight-devices","yeelight-lamp"],"latest_commit_sha":null,"homepage":"https://numberonebot.github.io/yeelight-client/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NumberOneBot.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"buy_me_a_coffee":"alexstrelets"}},"created_at":"2026-03-21T17:51:03.000Z","updated_at":"2026-03-30T14:44:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/NumberOneBot/yeelight-client","commit_stats":null,"previous_names":["numberonebot/yeelight-client"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/NumberOneBot/yeelight-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NumberOneBot%2Fyeelight-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NumberOneBot%2Fyeelight-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NumberOneBot%2Fyeelight-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NumberOneBot%2Fyeelight-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NumberOneBot","download_url":"https://codeload.github.com/NumberOneBot/yeelight-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NumberOneBot%2Fyeelight-client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31580507,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","cli","home-automation","iot","lan","library","node","npm-package","smart-home","smart-lights","typescript","yeelight","yeelight-api","yeelight-devices","yeelight-lamp"],"created_at":"2026-04-02T00:58:41.246Z","updated_at":"2026-04-09T01:01:11.229Z","avatar_url":"https://github.com/NumberOneBot.png","language":"TypeScript","funding_links":["https://buymeacoffee.com/alexstrelets"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"packages/docs/public/logo.svg\" width=\"80\" alt=\"yeelight-client\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eyeelight-client\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  TypeScript library for controlling Yeelight smart lights over LAN\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/NumberOneBot/yeelight-client/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/NumberOneBot/yeelight-client/actions/workflows/ci.yml/badge.svg\" alt=\"CI\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/yeelight-client\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/yeelight-client\" alt=\"npm version\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/NumberOneBot/yeelight-client/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/NumberOneBot/yeelight-client\" alt=\"license\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/NumberOneBot/yeelight-client\"\u003e\u003cimg src=\"https://img.shields.io/badge/TypeScript-5.7-blue\" alt=\"TypeScript\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003e **Zero-dependency** TypeScript library for Yeelight devices. SSDP discovery, dual-channel control, color flows, segment lighting — all over your local network.\n\n## Features\n\n- **Auto-discovery** — find devices on your LAN via SSDP multicast\n- **Direct connection** — connect by IP when you know the address\n- **Dual-channel** — independent control of main and background lights (`devToggle()` switches both at once)\n- **Segment control** — left/right colors on lamp15 (YLTD003)\n- **Color flows** — built-in presets (pulse, strobe, candle, sunrise, color cycle) and a chainable FlowBuilder\n- **Scenes** — `setScene()` atomically turns on the device and sets its state in one command (works on main and background channels)\n- **Relative adjustments** — `setAdjust()`, `adjustBrightness()`, `adjustColorTemp()`, `adjustColor()` without knowing the current value\n- **Sleep timer** — `cronAdd(minutes)` / `cronGet()` / `cronDel()` — built-in device timer\n- **Full state** — read power, brightness, color temp, RGB, flow status\n- **Real-time events** — property change notifications pushed from the device\n- **ESM + CJS** — works everywhere, ships with TypeScript declarations\n- **Zero dependencies** — only Node.js built-ins (`net`, `dgram`, `events`, `os`)\n\n## Requirements\n\n- Node.js 18+\n- LAN Control enabled on your Yeelight device (Yeelight app → device settings → LAN Control)\n\n## Install\n\n```bash\nnpm install yeelight-client\n```\n\n```bash\npnpm add yeelight-client\n```\n\n```bash\nyarn add yeelight-client\n```\n\n## Quick Start\n\n```ts\nimport { YeelightDevice } from 'yeelight-client'\n\n// Discover devices on the network\nconst devices = await YeelightDevice.discover({ timeout: 3000 })\nconst device = devices[0]\nawait device.connect()\n\n// Control the main light\nawait device.main.setPower(true)\nawait device.main.setBrightness(80)\nawait device.main.setColorTemp(4000)\nawait device.main.setRGB(255, 100, 0)\n\ndevice.disconnect()\n```\n\n## Usage\n\n### Connect by IP\n\n```ts\nconst device = await YeelightDevice.connect('192.168.1.42')\n```\n\nWhen connecting by IP, capabilities are auto-detected via a property probe.\n\n### Dual-Channel Devices\n\nSome Yeelight devices (ceiling lights, desk lamps) have a background channel:\n\n```ts\nif (device.background) {\n  await device.background.setRGB(0, 100, 255)\n  await device.background.setBrightness(50)\n}\n```\n\n### Segment Control\n\nThe lamp15 (YLTD003) supports independent left/right segment colors:\n\n```ts\nif (device.capabilities.hasSegments) {\n  await device.setSegments([255, 0, 0], [0, 0, 255])\n}\n```\n\n### Scenes\n\n`setScene()` turns the device on and applies the target state atomically. Useful when the device may be off.\nWorks on both main and background channels:\n\n```ts\nimport type { SceneConfig } from 'yeelight-client'\n\nawait device.setScene({ type: 'color', rgb: [255, 100, 0], brightness: 80 })\nawait device.setScene({ type: 'ct', colorTemp: 4000, brightness: 60 })\nawait device.setScene({ type: 'hsv', hue: 200, saturation: 80, brightness: 70 })\nawait device.setScene({ type: 'cf', flow: Flow.colorCycle() })\nawait device.setScene({ type: 'auto_delay_off', brightness: 50, minutes: 30 })\n\n// background channel too\nif (device.background) {\n  await device.background.setScene({\n    type: 'color',\n    rgb: [0, 0, 255],\n    brightness: 50\n  })\n}\n```\n\n### Relative Adjustments\n\nChange brightness or color temperature relative to the current value — no need to know the current state:\n\n```ts\nawait device.main.setAdjust('increase', 'bright') // step up brightness\nawait device.main.setAdjust('decrease', 'ct') // step down color temp\nawait device.main.setAdjust('circle', 'color') // cycle through hues\n\nawait device.main.adjustBrightness(+20) // +20% brightness\nawait device.main.adjustBrightness(-10, 500) // -10% over 500ms\nawait device.main.adjustColorTemp(-30) // -30% color temp\nawait device.main.adjustColor() // cycle through basic colors\nawait device.main.adjustColor(1000) // cycle over 1000ms\n```\n\n### Sleep Timer\n\nTurn off the device automatically after a number of minutes:\n\n```ts\nawait device.cronAdd(30) // turn off in 30 minutes\nconst timer = await device.cronGet() // { delay: 28 } or null\nawait device.cronDel() // cancel the timer\n```\n\n### Device Name\n\n```ts\nawait device.setName('Desk Light')\n```\n\n### Dual-Zone Toggle\n\nDevices with a background channel (Bedside Lamp 2, ceiling lights) can toggle both channels simultaneously:\n\n```ts\nawait device.devToggle() // toggles main + background in one command\n```\n\n### Color Flows\n\nBuilt-in presets for common animations:\n\n```ts\nimport { Flow } from 'yeelight-client'\n\nawait device.main.startFlow(Flow.pulse(255, 0, 0, { count: 3, duration: 400 }))\nawait device.main.startFlow(Flow.strobe(0, 255, 0, { count: 10 }))\nawait device.main.startFlow(Flow.colorCycle({ duration: 1000 }))\nawait device.main.startFlow(Flow.candle())\nawait device.main.startFlow(Flow.sunrise(5000))\n```\n\nBuild custom flows with the chainable API:\n\n```ts\nconst flow = Flow.builder()\n  .rgb(255, 0, 0, { duration: 500, brightness: 100 })\n  .colorTemp(4000, { duration: 500, brightness: 80 })\n  .sleep(200)\n  .repeat(0) // loop forever\n  .onEnd('recover') // restore previous state on stop\n  .build()\n\nawait device.main.startFlow(flow)\nawait device.main.stopFlow()\n```\n\n### Transition Options\n\nAll setter methods accept an optional `TransitionOptions` argument:\n\n```ts\nawait device.main.setBrightness(50, { effect: 'smooth', duration: 1000 })\nawait device.main.setRGB(255, 0, 0, { effect: 'sudden' })\n```\n\nDefault: `{ effect: 'smooth', duration: 300 }`.\n\n`setPower()` accepts `PowerOptions` which extends `TransitionOptions` with an optional `mode`:\n\n```ts\nimport type { PowerOptions } from 'yeelight-client'\n\nawait device.main.setPower(true, { mode: 5 }) // night mode (ceiling lights)\nawait device.main.setPower(true, { mode: 1, duration: 500 }) // turn on in CT mode\n```\n\n| Mode | Constant | Description                       |\n| ---- | -------- | --------------------------------- |\n| `0`  | normal   | Default mode                      |\n| `1`  | CT       | Color temperature mode            |\n| `2`  | RGB      | RGB color mode                    |\n| `3`  | HSV      | HSV color mode                    |\n| `4`  | CF       | Color flow mode                   |\n| `5`  | Night    | Night light (ceiling lights only) |\n\n### Events\n\n```ts\ndevice.on('props', (props) =\u003e {\n  console.log('State changed:', props)\n})\n\ndevice.on('disconnect', () =\u003e {\n  console.log('Device disconnected')\n})\n```\n\n| Event        | Payload                                                          | Description                     |\n| ------------ | ---------------------------------------------------------------- | ------------------------------- |\n| `props`      | `main: Partial\u003cChannelState\u003e, bg: Partial\u003cChannelState\u003e \\| null` | Device pushed a property change |\n| `disconnect` | —                                                                | Connection lost or closed       |\n| `tx`         | `string`                                                         | Outgoing JSON-RPC frame (debug) |\n| `rx`         | `string`                                                         | Incoming JSON-RPC frame (debug) |\n\n### Reading State\n\n```ts\nconst state = await device.main.getState()\n// { power: true, brightness: 80, colorTemp: 4000, rgb: null, flowing: false }\n```\n\n### Raw Properties\n\nQuery any Yeelight property by its protocol name:\n\n```ts\nconst raw = await device.getRawProps([\n  'power',\n  'bright',\n  'ct',\n  'rgb',\n  'color_mode'\n])\n// { power: 'on', bright: '80', ct: '4000', rgb: '16737280', color_mode: '2' }\n```\n\n### Capabilities\n\n```ts\ndevice.capabilities\n// {\n//   hasBackground: true,\n//   hasSegments: false,\n//   main: { hasColor: true, hasColorTemp: true, hasFlow: true },\n//   background: { hasColor: true, hasColorTemp: true, hasFlow: true }\n// }\n```\n\n## API\n\n### `YeelightDevice`\n\n|            | Signature                                                          | Description                                              |\n| ---------- | ------------------------------------------------------------------ | -------------------------------------------------------- |\n| **Static** | `discover(opts?: { timeout?: number }): Promise\u003cYeelightDevice[]\u003e` | Find devices via SSDP (default timeout: 3000ms)          |\n| **Static** | `connect(ip: string, port?: number): Promise\u003cYeelightDevice\u003e`      | Connect directly (default port: 55443)                   |\n|            | `connect(): Promise\u003cvoid\u003e`                                         | Reconnect a disconnected device                          |\n|            | `disconnect(): void`                                               | Close the connection                                     |\n|            | `isConnected(): boolean`                                           | Connection status                                        |\n|            | `setSegments(left, right): Promise\u003cvoid\u003e`                          | Set left/right segment colors (lamp15)                   |\n|            | `setScene(scene: SceneConfig): Promise\u003cvoid\u003e`                      | Turn on and apply state atomically (delegates to `main`) |\n|            | `setName(name: string): Promise\u003cvoid\u003e`                             | Persist device name to device memory                     |\n|            | `devToggle(): Promise\u003cvoid\u003e`                                       | Toggle main + background simultaneously                  |\n|            | `cronAdd(minutes: number): Promise\u003cvoid\u003e`                          | Set sleep timer (auto power-off)                         |\n|            | `cronDel(): Promise\u003cvoid\u003e`                                         | Cancel sleep timer                                       |\n|            | `cronGet(): Promise\u003cCronTimer \\| null\u003e`                            | Read active timer (remaining minutes), or `null`         |\n|            | `getRawProps(props: string[]): Promise\u003cRecord\u003cstring, string\u003e\u003e`    | Query raw Yeelight properties                            |\n\n**Properties:** `id`, `ip`, `model`, `name`, `support`, `capabilities`, `main`, `background`\n\n### `LightChannel`\n\n| Method                                    | Description                                             |\n| ----------------------------------------- | ------------------------------------------------------- |\n| `setPower(on, opts?)`                     | Turn on/off; `opts` is `PowerOptions` (supports `mode`) |\n| `toggle()`                                | Toggle power                                            |\n| `setBrightness(1–100, opts?)`             | Set brightness                                          |\n| `setColorTemp(kelvin, opts?)`             | Color temperature (1700–6500 K)                         |\n| `setRGB(r, g, b, opts?)`                  | RGB color (0–255 each)                                  |\n| `setHSV(hue, sat, opts?)`                 | HSV color (hue 0–359, sat 0–100)                        |\n| `startFlow(flow)`                         | Start a color flow animation                            |\n| `stopFlow()`                              | Stop the current flow                                   |\n| `setDefault()`                            | Save current state as power-on default                  |\n| `setScene(scene)`                         | Turn on and apply state atomically                      |\n| `setAdjust(action, prop)`                 | Relative adjustment (no current value needed)           |\n| `adjustBrightness(percentage, duration?)` | Change brightness by ±% (−100…+100)                     |\n| `adjustColorTemp(percentage, duration?)`  | Change color temp by ±% (−100…+100)                     |\n| `adjustColor(duration?)`                  | Cycle through basic colors                              |\n| `getState()`                              | Read `ChannelState`                                     |\n\nMethods that require specific hardware throw `UnsupportedError` if the capability is missing.\n\n### `Flow`\n\n| Factory                       | Description                              |\n| ----------------------------- | ---------------------------------------- |\n| `Flow.pulse(r, g, b, opts?)`  | Pulsing RGB (default: 3×, 500ms)         |\n| `Flow.strobe(r, g, b, opts?)` | Fast strobe (default: 10×, 50ms)         |\n| `Flow.colorCycle(opts?)`      | Rainbow loop (default: 1000ms per step)  |\n| `Flow.candle()`               | Warm flicker (1700–1900 K)               |\n| `Flow.sunrise(durationMs)`    | Gradual warm-up to daylight              |\n| `Flow.builder()`              | Returns a `FlowBuilder` for custom flows |\n\n### `FlowBuilder`\n\nChainable: `.rgb()` → `.colorTemp()` → `.sleep()` → `.repeat()` → `.onEnd()` → `.build()`\n\n### Error Classes\n\n| Class              | When                                         |\n| ------------------ | -------------------------------------------- |\n| `UnsupportedError` | Device/channel doesn't support the operation |\n| `ConnectionError`  | Network failure, timeout, or disconnection   |\n| `DeviceError`      | Device rejected the RPC call (has `.code`)   |\n\n### Types\n\n```ts\ninterface ChannelState {\n  power: boolean\n  brightness: number // 1–100\n  colorTemp: number | null // Kelvin\n  rgb: [number, number, number] | null // [R, G, B]\n  flowing: boolean\n}\n\ninterface TransitionOptions {\n  effect?: 'smooth' | 'sudden'\n  duration?: number // ms\n}\n\ntype PowerMode = 0 | 1 | 2 | 3 | 4 | 5\n// 0 = normal, 1 = CT, 2 = RGB, 3 = HSV, 4 = CF, 5 = night\n\ninterface PowerOptions extends TransitionOptions {\n  mode?: PowerMode\n}\n\ntype SceneConfig =\n  | { type: 'color'; rgb: [number, number, number]; brightness: number }\n  | { type: 'hsv'; hue: number; saturation: number; brightness: number }\n  | { type: 'ct'; colorTemp: number; brightness: number }\n  | { type: 'cf'; flow: Flow }\n  | { type: 'auto_delay_off'; brightness: number; minutes: number }\n\ninterface Capabilities {\n  hasBackground: boolean\n  hasSegments: boolean\n  main: ChannelCapabilities\n  background: ChannelCapabilities | null\n}\n\ninterface ChannelCapabilities {\n  hasColor: boolean\n  hasColorTemp: boolean\n  hasFlow: boolean\n}\n\ninterface CronTimer {\n  delay: number // remaining minutes\n}\n```\n\n---\n\n## Packages\n\n| Package                                                            | Description                                                 |\n| ------------------------------------------------------------------ | ----------------------------------------------------------- |\n| [`yeelight-client`](https://www.npmjs.com/package/yeelight-client) | Core library — this package                                 |\n| [`yeelight-cli`](https://www.npmjs.com/package/yeelight-cli)       | Terminal tool (`ylc`) — interactive TUI + one-shot commands |\n\n## CLI\n\nThe companion [`yeelight-cli`](https://www.npmjs.com/package/yeelight-cli) package provides a terminal tool:\n\n```bash\nnpm install -g yeelight-cli\n```\n\nOr download a precompiled binary from [Releases](https://github.com/NumberOneBot/yeelight-client/releases).\n\n```bash\nylc discover                         # find devices on the network\nylc interactive                      # TUI with device picker + controls\nylc status --ip 192.168.1.42         # show device state\nylc power on                         # turn on\nylc brightness 50 --duration 1000    # set brightness with transition\nylc ct 3000                          # color temperature\nylc color \"#ff6400\"                  # hex color\nylc color \"#ff640080\"                # hex with alpha → brightness\nylc segment \"#ff0000\" \"#0000ff\"      # lamp15 left/right\nylc power on --bg                    # background channel\nylc toggle                           # toggle main + background at once\nylc name \"Desk Light\"                # set device name\nylc timer set 30                     # sleep timer (auto power-off)\nylc timer status                     # check remaining time\nylc timer cancel                     # cancel timer\nylc adjust brightness 20             # relative adjust (+/- 1..100)\nylc adjust ct -10\nylc adjust color\n```\n\n## Development\n\n```bash\npnpm install\n\npnpm dev                                    # library watch mode\npnpm build                                  # build library (ESM + CJS + DTS)\npnpm --filter yeelight-cli dev              # CLI dev\npnpm --filter yeelight-client-docs dev      # docs dev server\n```\n\n## Contributing\n\n1. Fork the repo\n2. Create your feature branch (`git checkout -b feat/my-feature`)\n3. Commit your changes (`git commit -m 'feat: add something'`)\n4. Push to the branch (`git push origin feat/my-feature`)\n5. Open a Pull Request\n\n## License\n\n[MIT](LICENSE) © Alex Strelets\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnumberonebot%2Fyeelight-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnumberonebot%2Fyeelight-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnumberonebot%2Fyeelight-client/lists"}