divoom-timesgate-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +371 -0
- package/dist/common-D8oHDNi6.d.cts +54 -0
- package/dist/common-D8oHDNi6.d.ts +54 -0
- package/dist/image/index.cjs +515 -0
- package/dist/image/index.cjs.map +1 -0
- package/dist/image/index.d.cts +279 -0
- package/dist/image/index.d.ts +279 -0
- package/dist/image/index.js +498 -0
- package/dist/image/index.js.map +1 -0
- package/dist/index.cjs +1021 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +921 -0
- package/dist/index.d.ts +921 -0
- package/dist/index.js +991 -0
- package/dist/index.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/constants.ts","../src/utils.ts","../src/commands/animation.ts","../src/commands/batch.ts","../src/commands/dial.ts","../src/commands/draw.ts","../src/commands/system.ts","../src/commands/tool.ts","../src/transport.ts","../src/client.ts","../src/cloud.ts","../src/discovery.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Error hierarchy for the Divoom Times Gate SDK.\n *\n * Every error thrown by the SDK extends {@link DivoomError}, so you can catch\n * the whole family with a single `instanceof DivoomError` check, or narrow to a\n * specific subclass when you need to react differently (e.g. retry on a\n * timeout, but surface a validation mistake to the user).\n *\n * @packageDocumentation\n */\n\n/** Base class for every error thrown by the SDK. */\nexport class DivoomError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options as ErrorOptions | undefined);\n this.name = 'DivoomError';\n }\n}\n\n/** Thrown when arguments fail validation before a request is ever sent. */\nexport class DivoomValidationError extends DivoomError {\n constructor(message: string) {\n super(message);\n this.name = 'DivoomValidationError';\n }\n}\n\n/** Thrown when the device cannot be reached (DNS, connection refused, etc.). */\nexport class DivoomConnectionError extends DivoomError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'DivoomConnectionError';\n }\n}\n\n/** Thrown when a request does not complete within the configured timeout. */\nexport class DivoomTimeoutError extends DivoomError {\n /** The command that timed out. */\n readonly command: string;\n /** The timeout budget, in milliseconds, that was exceeded. */\n readonly timeoutMs: number;\n\n constructor(command: string, timeoutMs: number) {\n super(`Command \"${command}\" timed out after ${timeoutMs}ms.`);\n this.name = 'DivoomTimeoutError';\n this.command = command;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/** Thrown when the device responds with a non-2xx HTTP status. */\nexport class DivoomHttpError extends DivoomError {\n /** The HTTP status code returned by the device. */\n readonly status: number;\n /** The command that produced the error. */\n readonly command: string;\n /** The full request URL. */\n readonly url: string;\n\n constructor(status: number, command: string, url: string) {\n super(`Times Gate returned HTTP ${status} for command \"${command}\" (${url}).`);\n this.name = 'DivoomHttpError';\n this.status = status;\n this.command = command;\n this.url = url;\n }\n}\n\n/**\n * Thrown when a Divoom **cloud** API (`app.divoom-gz.com`) reports a non-zero\n * `ReturnCode`.\n */\nexport class DivoomCloudError extends DivoomError {\n /** The non-zero `ReturnCode` reported by the cloud API. */\n readonly returnCode: number;\n /** The cloud endpoint path that failed. */\n readonly endpoint: string;\n /** The `ReturnMessage`, when provided. */\n readonly returnMessage?: string;\n\n constructor(returnCode: number, endpoint: string, returnMessage?: string) {\n super(\n `Divoom cloud endpoint \"${endpoint}\" failed with ReturnCode ${returnCode}` +\n (returnMessage ? `: ${returnMessage}` : '.'),\n );\n this.name = 'DivoomCloudError';\n this.returnCode = returnCode;\n this.endpoint = endpoint;\n this.returnMessage = returnMessage;\n }\n}\n\n/**\n * Thrown when the device accepts the request but reports a non-zero\n * `error_code` in the response body.\n */\nexport class DivoomDeviceError extends DivoomError {\n /** The non-zero `error_code` reported by the device. */\n readonly errorCode: number;\n /** The command that was rejected. */\n readonly command: string;\n /** The raw response body returned by the device. */\n readonly response: unknown;\n\n constructor(errorCode: number, command: string, response: unknown) {\n super(\n `Times Gate rejected command \"${command}\" with error_code ${errorCode}. ` +\n `This often means the LocalToken is missing or incorrect for a command that requires it.`,\n );\n this.name = 'DivoomDeviceError';\n this.errorCode = errorCode;\n this.command = command;\n this.response = response;\n }\n}\n","/**\n * Device-level constants for the Divoom Times Gate.\n *\n * @packageDocumentation\n */\n\n/** The Times Gate has five individually-addressable LCD panels. */\nexport const PANEL_COUNT = 5;\n\n/** Each panel renders a square {@link PANEL_SIZE}×{@link PANEL_SIZE} image. */\nexport const PANEL_SIZE = 128;\n\n/** Default HTTP port for hardware version 400 devices. */\nexport const DEFAULT_PORT = 80;\n\n/** Default request path for hardware version 400 devices (`http://IP:80/post`). */\nexport const DEFAULT_PATH = '/post';\n\n/** HTTP port for hardware version 402 devices. */\nexport const HARDWARE_402_PORT = 9000;\n\n/** Request path for hardware version 402 devices (`http://IP:9000/divoom_api`). */\nexport const HARDWARE_402_PATH = '/divoom_api';\n\n/**\n * Divoom's cloud endpoint that returns every Divoom device currently visible\n * on the same LAN as the caller. Used by {@link discoverDevices}.\n */\nexport const LAN_DISCOVERY_URL = 'https://app.divoom-gz.com/Device/ReturnSameLANDevice';\n","/**\n * Small, dependency-free helpers shared across the SDK: argument validation,\n * panel-mask construction, and a monotonic PicID generator.\n *\n * @packageDocumentation\n */\n\nimport { PANEL_COUNT } from './constants';\nimport { DivoomValidationError } from './errors';\nimport type { LcdArray, PanelIndex } from './types/common';\n\n/** Resolves after `ms` milliseconds. */\nexport const delay = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\n/**\n * Best-effort release of a fetch `Response` body on error paths where it is\n * never read, so the underlying socket returns to the connection pool instead of\n * being pinned until garbage collection. Never throws.\n */\nexport async function drainBody(response: {\n body?: { cancel?: () => Promise<unknown> } | null;\n}): Promise<void> {\n try {\n await response.body?.cancel?.();\n } catch {\n // ignore — releasing the body is best-effort\n }\n}\n\n/**\n * Asserts that `value` is an integer within `[min, max]`, throwing a\n * {@link DivoomValidationError} otherwise.\n */\nexport function assertIntInRange(value: number, min: number, max: number, label: string): void {\n if (!Number.isInteger(value) || value < min || value > max) {\n throw new DivoomValidationError(\n `${label} must be an integer between ${min} and ${max} (received ${String(value)}).`,\n );\n }\n}\n\n/** Asserts that `value` is a valid {@link PanelIndex} (`0`–`4`). */\nexport function assertPanelIndex(value: number): asserts value is PanelIndex {\n if (!Number.isInteger(value) || value < 0 || value >= PANEL_COUNT) {\n throw new DivoomValidationError(\n `panel must be an integer between 0 and ${PANEL_COUNT - 1} (received ${String(value)}).`,\n );\n }\n}\n\n/** Asserts that `value` is a non-empty string after trimming. */\nexport function assertNonEmptyString(value: unknown, label: string): asserts value is string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new DivoomValidationError(`${label} must be a non-empty string.`);\n }\n}\n\n/**\n * Builds a panel selection mask for a single panel.\n *\n * @example\n * ```ts\n * panelToLcdArray(2); // → [0, 0, 1, 0, 0]\n * ```\n */\nexport function panelToLcdArray(panel: PanelIndex): LcdArray {\n assertPanelIndex(panel);\n const arr: LcdArray = [0, 0, 0, 0, 0];\n arr[panel] = 1;\n return arr;\n}\n\n/**\n * Builds a panel selection mask from a set of panels.\n *\n * @example\n * ```ts\n * panelsToLcdArray([0, 4]); // → [1, 0, 0, 0, 1]\n * ```\n */\nexport function panelsToLcdArray(panels: Iterable<PanelIndex>): LcdArray {\n const arr: LcdArray = [0, 0, 0, 0, 0];\n for (const panel of panels) {\n assertPanelIndex(panel);\n arr[panel] = 1;\n }\n return arr;\n}\n\n/**\n * Generates strictly-increasing PicIDs for image uploads. The Times Gate caches\n * frames by ID, so every pushed frame needs a fresh, monotonically growing ID.\n *\n * Uniqueness within a single generator comes from the `+10` step taken on every\n * `next()` call; the per-panel offset only spaces consecutive IDs apart and is\n * not what prevents collisions. The generator is seeded from the current time in\n * seconds, so two *separate* generators created within the same second can\n * produce overlapping IDs — share one generator if you need cross-instance\n * uniqueness (or seed from the device via `Draw/GetHttpGifId`).\n */\nexport class PicIdGenerator {\n private base: number;\n\n constructor(seed: number = Math.floor(Date.now() / 1000)) {\n this.base = seed;\n }\n\n /** Returns the next unique PicID for the given panel. */\n next(panel = 0): number {\n this.base += 10;\n return this.base + panel;\n }\n}\n","/**\n * Animation & on-device text commands: play stored Divoom GIFs, stream GIF URLs\n * (uniformly or per-panel), overlay scrolling text, and compose data-rich item\n * lists.\n *\n * @packageDocumentation\n */\n\nimport { DivoomValidationError } from '../errors';\nimport type { HttpTransport } from '../transport';\nimport type { DivoomBaseResponse, PanelIndex } from '../types/common';\nimport {\n assertIntInRange,\n assertNonEmptyString,\n assertPanelIndex,\n panelsToLcdArray,\n} from '../utils';\n\n/** Text scroll direction. */\nexport type TextDirection = 'left' | 'right';\n/** Horizontal text alignment. */\nexport type TextAlign = 'left' | 'center' | 'right';\n\nconst DIRECTION: Record<TextDirection, number> = { left: 0, right: 1 };\nconst ALIGN: Record<TextAlign, number> = { left: 1, center: 2, right: 3 };\n\n/** Options for {@link AnimationCommands.sendText} (`Draw/SendHttpText`). */\nexport interface SendTextOptions {\n /** Unique text id (reused id replaces the text). Must be < 20. Defaults to `1`. */\n textId?: number;\n /** X start position. Defaults to `0`. */\n x?: number;\n /** Y start position. Defaults to `40`. */\n y?: number;\n /** Scroll direction. Defaults to `\"left\"`. */\n direction?: TextDirection;\n /** App animation font, 0–7. Defaults to `4`. */\n font?: number;\n /** Text area width in points (16–64). Defaults to `56`. */\n width?: number;\n /** Scroll speed: ms per step. Defaults to `100`. */\n speed?: number;\n /** Hex color, e.g. `\"#FFFF00\"`. Defaults to `\"#FFFFFF\"`. */\n color?: string;\n /** Horizontal alignment. Defaults to `\"left\"`. */\n align?: TextAlign;\n}\n\n/**\n * A single element in a {@link AnimationCommands.sendItemList} composition.\n * Field names/casing match the device protocol verbatim (including the\n * misspelled `Textheight`).\n */\nexport interface DisplayItem {\n /** Unique id for in-place replacement (max 40). */\n TextId: number;\n /** Display type: 1–21 = data fields, 22 = static text, 23 = URL text. */\n type: number;\n /** Horizontal start position. */\n x: number;\n /** Vertical start position. */\n y: number;\n /** Scroll direction: `0` = left, `1` = right. */\n dir?: number;\n /** Font id from {@link DivoomCloudClient.getFontList}. */\n font?: number;\n /** Text area width in pixels. */\n TextWidth?: number;\n /** Text area height in pixels (protocol spelling). */\n Textheight?: number;\n /** Text (type 22) or URL (type 23); UTF-8, max 512 chars. */\n TextString?: string;\n /** Scroll speed in ms per step. */\n speed?: number;\n /** Hex color, e.g. `\"#FFFF00\"`. */\n color?: string;\n /** Refresh interval in seconds (type 23). */\n update_time?: number;\n /** Alignment: `1` = left, `2` = center, `3` = right (firmware ≥ 90102). */\n align?: number;\n}\n\n/** Options for {@link AnimationCommands.sendItemList}. */\nexport interface SendItemListOptions {\n /** `true` (default) replaces all items; `false` appends. */\n replace?: boolean;\n /** Optional background GIF URL for the panel. */\n backgroundGif?: string;\n}\n\n/** Animation & on-device text commands. Access via {@link TimesGateClient.animation}. */\nexport class AnimationCommands {\n constructor(private readonly transport: HttpTransport) {}\n\n /**\n * Plays a stored Divoom GIF (by `FileId`) on the given panels\n * (`Draw/SendRemote`). Obtain `fileId` from\n * {@link DivoomCloudClient.getLikedImages} or\n * {@link DivoomCloudClient.getUploadedImages}.\n */\n async playStoredGif(panels: PanelIndex[], fileId: string): Promise<DivoomBaseResponse> {\n assertNonEmptyString(fileId, 'fileId');\n if (panels.length === 0) {\n throw new DivoomValidationError('playStoredGif requires at least one panel.');\n }\n panels.forEach(assertPanelIndex);\n return this.transport.send({\n Command: 'Draw/SendRemote',\n FileId: fileId,\n LcdArray: panelsToLcdArray(panels),\n });\n }\n\n /**\n * Plays one or more GIF URLs on the given panels (`Device/PlayGif`).\n *\n * @param urls - Up to 10 GIF URLs (dimensions 16/32/64/128).\n */\n async playGifUrls(panels: PanelIndex[], urls: string[]): Promise<DivoomBaseResponse> {\n if (panels.length === 0) {\n throw new DivoomValidationError('playGifUrls requires at least one panel.');\n }\n panels.forEach(assertPanelIndex);\n if (urls.length === 0 || urls.length > 10) {\n throw new DivoomValidationError(`playGifUrls accepts 1–10 URLs (received ${urls.length}).`);\n }\n return this.transport.send({\n Command: 'Device/PlayGif',\n LcdArray: panelsToLcdArray(panels),\n FileName: urls,\n });\n }\n\n /**\n * Plays a distinct list of GIF URLs on each panel (`Device/PlayGifLCDs`).\n *\n * @param perPanel - GIF URL lists keyed by panel index (0–4).\n *\n * @example\n * ```ts\n * await client.animation.playGifPerPanel({\n * 0: ['http://f.divoom-gz.com/Kirby.gif'],\n * 1: ['http://f.divoom-gz.com/loz.gif'],\n * });\n * ```\n */\n async playGifPerPanel(\n perPanel: Partial<Record<PanelIndex, string[]>>,\n ): Promise<DivoomBaseResponse> {\n const payload: Record<string, unknown> = { Command: 'Device/PlayGifLCDs' };\n let any = false;\n for (let panel = 0; panel < 5; panel += 1) {\n const urls = perPanel[panel as PanelIndex];\n if (urls && urls.length > 0) {\n payload[`LCD${panel}GifFile`] = urls;\n any = true;\n }\n }\n if (!any) {\n throw new DivoomValidationError('playGifPerPanel requires URLs for at least one panel.');\n }\n return this.transport.send(payload as { Command: string });\n }\n\n /**\n * Overlays a single scrolling/aligned text string on a panel\n * (`Draw/SendHttpText`).\n *\n * @param panel - Panel index 0–4.\n * @param text - UTF-8 string (< 512 chars).\n */\n async sendText(\n panel: PanelIndex,\n text: string,\n options: SendTextOptions = {},\n ): Promise<DivoomBaseResponse> {\n assertPanelIndex(panel);\n assertNonEmptyString(text, 'text');\n if (options.textId !== undefined) assertIntInRange(options.textId, 0, 19, 'textId');\n if (options.font !== undefined) assertIntInRange(options.font, 0, 7, 'font');\n if (options.width !== undefined) assertIntInRange(options.width, 16, 64, 'width');\n return this.transport.send({\n Command: 'Draw/SendHttpText',\n LcdIndex: panel,\n TextId: options.textId ?? 1,\n x: options.x ?? 0,\n y: options.y ?? 40,\n dir: DIRECTION[options.direction ?? 'left'],\n font: options.font ?? 4,\n TextWidth: options.width ?? 56,\n speed: options.speed ?? 100,\n TextString: text,\n color: options.color ?? '#FFFFFF',\n align: ALIGN[options.align ?? 'left'],\n });\n }\n\n /**\n * Composes a panel from a list of display items — static text, live data\n * fields, and URL-backed text — over an optional background GIF\n * (`Draw/SendHttpItemList`).\n *\n * @param panel - Panel index 0–4.\n * @param items - The display elements to render.\n */\n async sendItemList(\n panel: PanelIndex,\n items: DisplayItem[],\n options: SendItemListOptions = {},\n ): Promise<DivoomBaseResponse> {\n assertPanelIndex(panel);\n if (items.length === 0) {\n throw new DivoomValidationError('sendItemList requires at least one item.');\n }\n const payload: Record<string, unknown> = {\n Command: 'Draw/SendHttpItemList',\n LcdIndex: panel,\n NewFlag: options.replace === false ? 0 : 1,\n ItemList: items,\n };\n if (options.backgroundGif !== undefined) {\n // Protocol field is misspelled \"BackgroudGif\".\n payload.BackgroudGif = options.backgroundGif;\n }\n return this.transport.send(payload as { Command: string });\n }\n}\n","/**\n * Batch-execution commands: run several commands in one request, or have the\n * device fetch a command list from a URL. Requires firmware ≥ 90102.\n *\n * @packageDocumentation\n */\n\nimport type { HttpTransport } from '../transport';\nimport type { DivoomBaseResponse, DivoomCommandRequest } from '../types/common';\nimport { assertNonEmptyString } from '../utils';\n\n/** Batch-execution commands. Access via {@link TimesGateClient.batch}. */\nexport class BatchCommands {\n constructor(private readonly transport: HttpTransport) {}\n\n /**\n * Runs multiple commands in sequence in a single request (`Draw/CommandList`).\n *\n * @example\n * ```ts\n * await client.batch.run([\n * { Command: 'Channel/SetBrightness', Brightness: 100 },\n * { Command: 'Channel/OnOffScreen', OnOff: 1 },\n * ]);\n * ```\n */\n run(commands: DivoomCommandRequest[]): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Draw/CommandList', CommandList: commands });\n }\n\n /**\n * Tells the device to fetch and execute a command-array file from a URL\n * (`Draw/UseHTTPCommandSource`).\n */\n async useCommandSource(commandUrl: string): Promise<DivoomBaseResponse> {\n assertNonEmptyString(commandUrl, 'commandUrl');\n return this.transport.send({ Command: 'Draw/UseHTTPCommandSource', CommandUrl: commandUrl });\n }\n}\n","/**\n * Dial / channel-control commands (device-side). These switch what each panel\n * displays — a single \"whole\" dial spanning all five panels, or independent\n * per-panel sub-dials and visualizers.\n *\n * Discovering the `ClockId` / `LcdIndependence` values these methods need is a\n * cloud operation — see {@link DivoomCloudClient}.\n *\n * @packageDocumentation\n */\n\nimport { DivoomValidationError } from '../errors';\nimport type { HttpTransport } from '../transport';\nimport type { DivoomBaseResponse, PanelIndex } from '../types/common';\nimport { assertPanelIndex } from '../utils';\n\n/** Channel/dial display mode. `whole` spans all panels; `independent` is per-panel. */\nexport type ChannelMode = 'whole' | 'independent';\n\n/** Response from {@link DialCommands.getIndex} (`Channel/GetIndex`). */\nexport interface GetIndexResponse extends DivoomBaseResponse {\n /**\n * The currently-selected channel index. On Pixoo-class devices:\n * `0` = Faces/Clock, `1` = Cloud, `2` = Visualizer/EQ, `3` = Custom.\n */\n SelectIndex: number;\n}\n\n/** Dial-control commands. Access via {@link TimesGateClient.dial}. */\nexport class DialCommands {\n constructor(private readonly transport: HttpTransport) {}\n\n /**\n * Selects a \"whole\" dial that spans all five panels\n * (`Channel/Set5LcdWholeClockId`).\n *\n * @param clockId - A whole-dial id from\n * {@link DivoomCloudClient.getWholeDialList}.\n */\n selectWholeDial(clockId: number): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Channel/Set5LcdWholeClockId', ClockId: clockId });\n }\n\n /**\n * Switches between whole and independent dial modes\n * (`Channel/Set5LcdChannelType`).\n *\n * @param mode - `\"whole\"` (one dial across all panels) or `\"independent\"`.\n * @param lcdIndependence - Required for `\"independent\"` mode; the group id from\n * {@link DivoomCloudClient.getChannelInfo}.\n */\n async setChannelMode(mode: ChannelMode, lcdIndependence?: number): Promise<DivoomBaseResponse> {\n if (mode === 'independent' && lcdIndependence === undefined) {\n throw new DivoomValidationError(\n \"setChannelMode('independent') requires an lcdIndependence id (from DivoomCloudClient.getChannelInfo).\",\n );\n }\n const payload: { Command: string; ChannelType: number; LcdIndependence?: number } = {\n Command: 'Channel/Set5LcdChannelType',\n ChannelType: mode === 'independent' ? 1 : 0,\n };\n if (lcdIndependence !== undefined) {\n payload.LcdIndependence = lcdIndependence;\n }\n return this.transport.send(payload);\n }\n\n /**\n * Selects a sub-dial for a single panel (`Channel/SetClockSelectId`).\n *\n * @param panel - Panel index 0–4.\n * @param clockId - A sub-dial id from {@link DivoomCloudClient.getDialList}.\n * @param lcdIndependence - The group id from {@link DivoomCloudClient.getChannelInfo}.\n */\n async selectSubDial(\n panel: PanelIndex,\n clockId: number,\n lcdIndependence: number,\n ): Promise<DivoomBaseResponse> {\n assertPanelIndex(panel);\n return this.transport.send({\n Command: 'Channel/SetClockSelectId',\n ClockId: clockId,\n LcdIndex: panel,\n LcdIndependence: lcdIndependence,\n });\n }\n\n /**\n * Selects a sub-visualizer (EQ) component for a panel\n * (`Channel/SetEqPosition`).\n *\n * @param panel - Panel index 0–4.\n * @param eqPosition - Visualizer index, starting at 0.\n * @param lcdIndependence - The group id from {@link DivoomCloudClient.getChannelInfo}.\n */\n async selectVisualizer(\n panel: PanelIndex,\n eqPosition: number,\n lcdIndependence: number,\n ): Promise<DivoomBaseResponse> {\n assertPanelIndex(panel);\n return this.transport.send({\n Command: 'Channel/SetEqPosition',\n EqPosition: eqPosition,\n LcdIndex: panel,\n LcdIndependence: lcdIndependence,\n });\n }\n\n /** Reads the currently-selected channel index (`Channel/GetIndex`). */\n getIndex(): Promise<GetIndexResponse> {\n return this.transport.send<GetIndexResponse>({ Command: 'Channel/GetIndex' });\n }\n}\n","/**\n * The image pipeline: push base64-encoded frames to panels (`Draw/SendHttpGif`),\n * manage the device's frame cache (`Draw/ResetHttpGifId`), and query the current\n * PicID (`Draw/GetHttpGifId`).\n *\n * PicIDs must strictly increase or the device caches a stale frame; this class\n * manages them automatically while still letting you override when needed.\n *\n * @packageDocumentation\n */\n\nimport { PANEL_SIZE } from '../constants';\nimport { DivoomError, DivoomValidationError } from '../errors';\nimport type { HttpTransport } from '../transport';\nimport type { DivoomBaseResponse, LcdArray, PanelIndex } from '../types/common';\nimport { PicIdGenerator, assertPanelIndex, panelToLcdArray, panelsToLcdArray } from '../utils';\n\n/** The raw `Draw/SendHttpGif` payload (minus `Command`), for full manual control. */\nexport interface SendHttpGifRequest {\n /** 5-element panel mask (`1` = draw, `0` = skip). */\n LcdArray: LcdArray;\n /** Total frame count in the animation (must be < 60). */\n PicNum: number;\n /** Frame pixel dimension. The Times Gate accepts `128`. */\n PicWidth: number;\n /** Zero-based frame index (`0`…`PicNum-1`). */\n PicOffset: number;\n /** Unique, strictly-increasing animation id. */\n PicID: number;\n /** Per-frame playback duration, in milliseconds. */\n PicSpeed: number;\n /** Base64-encoded JPEG/PNG frame data. */\n PicData: string;\n}\n\n/** Options for {@link DrawCommands.sendImage} / {@link DrawCommands.sendImageToPanels}. */\nexport interface SendImageOptions {\n /** Frame pixel dimension. Defaults to `128`. */\n picWidth?: number;\n /** Playback duration in ms (irrelevant for a single still). Defaults to `1000`. */\n picSpeed?: number;\n /** Override the auto-generated PicID. */\n picId?: number;\n}\n\n/** Options for {@link DrawCommands.sendAnimation}. */\nexport interface SendAnimationOptions {\n /** Frame pixel dimension. Defaults to `128`. */\n picWidth?: number;\n /** Per-frame duration in ms. Defaults to `100`. */\n picSpeed?: number;\n /** Override the auto-generated PicID (shared by every frame). */\n picId?: number;\n}\n\n/** Response from {@link DrawCommands.getPicId} (`Draw/GetHttpGifId`). */\nexport interface GetPicIdResponse extends DivoomBaseResponse {\n /** The device's current picture/animation id. */\n PicId: number;\n}\n\n/** Maximum number of frames the device accepts in a single animation. */\nconst MAX_FRAMES = 59;\n\n/** Image-pipeline commands. Access via {@link TimesGateClient.draw}. */\nexport class DrawCommands {\n private readonly picIds: PicIdGenerator;\n\n constructor(\n private readonly transport: HttpTransport,\n picIdSeed?: number,\n ) {\n this.picIds = new PicIdGenerator(picIdSeed);\n }\n\n /**\n * Pushes a single still image to one panel.\n *\n * @param panel - Panel index 0–4.\n * @param picData - Base64-encoded JPEG/PNG (e.g. {@link EncodedFrame.data}).\n *\n * @example\n * ```ts\n * import { encodePanel } from 'divoom-timesgate-sdk/image';\n * const frame = await encodePanel('./cover.jpg');\n * await client.draw.sendImage(0, frame.data);\n * ```\n */\n async sendImage(\n panel: PanelIndex,\n picData: string,\n options: SendImageOptions = {},\n ): Promise<DivoomBaseResponse> {\n assertPanelIndex(panel);\n return this.pushStill(panelToLcdArray(panel), picData, panel, options);\n }\n\n /**\n * Pushes the same still image to several panels at once.\n *\n * @param panels - Panel indices to target.\n * @param picData - Base64-encoded JPEG/PNG.\n */\n async sendImageToPanels(\n panels: PanelIndex[],\n picData: string,\n options: SendImageOptions = {},\n ): Promise<DivoomBaseResponse> {\n if (panels.length === 0) {\n throw new DivoomValidationError('sendImageToPanels requires at least one panel.');\n }\n panels.forEach(assertPanelIndex);\n return this.pushStill(panelsToLcdArray(panels), picData, panels[0] ?? 0, options);\n }\n\n /**\n * Pushes a multi-frame animation to one or more panels. Each frame is sent as\n * a separate `Draw/SendHttpGif` request sharing one PicID, per the protocol.\n *\n * @param panels - Panel indices to target.\n * @param frames - Base64-encoded frames, in order (1–59 frames).\n * @returns One response per frame.\n */\n async sendAnimation(\n panels: PanelIndex[],\n frames: string[],\n options: SendAnimationOptions = {},\n ): Promise<DivoomBaseResponse[]> {\n if (panels.length === 0) {\n throw new DivoomValidationError('sendAnimation requires at least one panel.');\n }\n panels.forEach(assertPanelIndex);\n if (frames.length === 0) {\n throw new DivoomValidationError('sendAnimation requires at least one frame.');\n }\n if (frames.length > MAX_FRAMES) {\n throw new DivoomValidationError(\n `An animation may contain at most ${MAX_FRAMES} frames (received ${frames.length}).`,\n );\n }\n\n const lcdArray = panelsToLcdArray(panels);\n const picId = options.picId ?? this.picIds.next(panels[0] ?? 0);\n const picWidth = options.picWidth ?? PANEL_SIZE;\n const picSpeed = options.picSpeed ?? 100;\n\n const responses: DivoomBaseResponse[] = [];\n for (let offset = 0; offset < frames.length; offset += 1) {\n responses.push(\n await this.sendFrame({\n LcdArray: lcdArray,\n PicNum: frames.length,\n PicWidth: picWidth,\n PicOffset: offset,\n PicID: picId,\n PicSpeed: picSpeed,\n PicData: frames[offset] ?? '',\n }),\n );\n }\n return responses;\n }\n\n /** Sends a fully-specified `Draw/SendHttpGif` frame — maximum control. */\n sendFrame(request: SendHttpGifRequest): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Draw/SendHttpGif', ...request });\n }\n\n /** Clears the device's image cache and resets the PicID counter (`Draw/ResetHttpGifId`). */\n resetCache(): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Draw/ResetHttpGifId' });\n }\n\n /** Reads the device's current PicID (`Draw/GetHttpGifId`). */\n async getPicId(): Promise<number> {\n const response = await this.transport.send<GetPicIdResponse>({ Command: 'Draw/GetHttpGifId' });\n if (typeof response.PicId !== 'number') {\n throw new DivoomError('Draw/GetHttpGifId did not return a numeric PicId.');\n }\n return response.PicId;\n }\n\n /** Returns the next locally-generated, strictly-increasing PicID. */\n nextPicId(panel: PanelIndex = 0): number {\n return this.picIds.next(panel);\n }\n\n private pushStill(\n lcdArray: LcdArray,\n picData: string,\n offsetPanel: number,\n options: SendImageOptions,\n ): Promise<DivoomBaseResponse> {\n return this.sendFrame({\n LcdArray: lcdArray,\n PicNum: 1,\n PicWidth: options.picWidth ?? PANEL_SIZE,\n PicOffset: 0,\n PicID: options.picId ?? this.picIds.next(offsetPanel),\n PicSpeed: options.picSpeed ?? 1000,\n PicData: picData,\n });\n }\n}\n","/**\n * System-setting commands: brightness, screen power, time, time zone, weather\n * location, display modes, and the device's current configuration/weather.\n *\n * @packageDocumentation\n */\n\nimport { DivoomValidationError } from '../errors';\nimport type { HttpTransport } from '../transport';\nimport type { DivoomBaseResponse } from '../types/common';\nimport { assertIntInRange, assertNonEmptyString } from '../utils';\n\n/** Temperature unit for {@link SystemCommands.setTemperatureMode}. */\nexport type TemperatureUnit = 'celsius' | 'fahrenheit';\n\n/** Response from {@link SystemCommands.getAllConfig} (`Channel/GetAllConf`). */\nexport interface GetAllConfigResponse extends DivoomBaseResponse {\n /** System brightness, 0–100. */\n Brightness: number;\n /** `1` if the device rotates between faces and GIFs. */\n RotationFlag: number;\n /** The configured date format, e.g. `\"YYYY-MM-DD\"`. */\n DateFormat: string;\n /** `1` for 24-hour clock, `0` for 12-hour. */\n Time24Flag: number;\n /** `0` for Celsius, `1` for Fahrenheit. */\n TemperatureMode: number;\n /** `1` if mirror mode is enabled. */\n MirrorFlag: number;\n /** `1` if the screen is on. */\n LightSwitch: number;\n}\n\n/** Response from {@link SystemCommands.getDeviceTime} (`Device/GetDeviceTime`). */\nexport interface GetDeviceTimeResponse extends DivoomBaseResponse {\n /** Device time as a UTC epoch (seconds). */\n UTCTime: number;\n /** Device local time, e.g. `\"2022-03-14 03:40:28\"`. */\n LocalTime: string;\n}\n\n/** Response from {@link SystemCommands.getWeather} (`Device/GetWeatherInfo`). */\nexport interface GetWeatherResponse extends DivoomBaseResponse {\n /** Condition text, e.g. `\"Sunny\"`, `\"Cloudy\"`. */\n Weather: string;\n /** Current temperature, in the device's configured unit. */\n CurTemp: number;\n /** Minimum temperature. */\n MinTemp: number;\n /** Maximum temperature. */\n MaxTemp: number;\n /** Atmospheric pressure (hPa). */\n Pressure: number;\n /** Relative humidity (%). */\n Humidity: number;\n /** Visibility (metres). */\n Visibility: number;\n /** Wind speed (m/s). */\n WindSpeed: number;\n}\n\n/**\n * System-setting commands. Access via {@link TimesGateClient.system}.\n *\n * @remarks Several of these settings (temperature mode, mirror mode, hour mode)\n * are not persisted by the device and reset on power-off.\n */\nexport class SystemCommands {\n constructor(private readonly transport: HttpTransport) {}\n\n /** Sets the LCD brightness (`Channel/SetBrightness`). @param brightness 0–100. */\n async setBrightness(brightness: number): Promise<DivoomBaseResponse> {\n assertIntInRange(brightness, 0, 100, 'brightness');\n return this.transport.send({ Command: 'Channel/SetBrightness', Brightness: brightness });\n }\n\n /** Reads every device setting (`Channel/GetAllConf`). */\n getAllConfig(): Promise<GetAllConfigResponse> {\n return this.transport.send<GetAllConfigResponse>({ Command: 'Channel/GetAllConf' });\n }\n\n /** Turns the screen on or off (`Channel/OnOffScreen`). */\n setScreen(on: boolean): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Channel/OnOffScreen', OnOff: on ? 1 : 0 });\n }\n\n /**\n * Sets the weather location (`Sys/LogAndLat`). Coordinates drive the on-device\n * weather readout.\n */\n setWeatherLocation(\n longitude: number | string,\n latitude: number | string,\n ): Promise<DivoomBaseResponse> {\n return this.transport.send({\n Command: 'Sys/LogAndLat',\n Longitude: String(longitude),\n Latitude: String(latitude),\n });\n }\n\n /** Sets the time zone (`Sys/TimeZone`). @param timeZone e.g. `\"GMT-5\"`. */\n async setTimeZone(timeZone: string): Promise<DivoomBaseResponse> {\n assertNonEmptyString(timeZone, 'timeZone');\n return this.transport.send({ Command: 'Sys/TimeZone', TimeZoneValue: timeZone });\n }\n\n /**\n * Sets the system clock (`Device/SetUTC`).\n *\n * @param time - A `Date` or a UTC epoch in **seconds**.\n */\n async setSystemTime(time: Date | number): Promise<DivoomBaseResponse> {\n const utc = time instanceof Date ? Math.floor(time.getTime() / 1000) : Math.floor(time);\n if (!Number.isFinite(utc)) {\n throw new DivoomValidationError(\n 'setSystemTime requires a valid Date or a finite epoch-seconds number.',\n );\n }\n return this.transport.send({ Command: 'Device/SetUTC', Utc: utc });\n }\n\n /** Reads the device's UTC and local time (`Device/GetDeviceTime`). */\n getDeviceTime(): Promise<GetDeviceTimeResponse> {\n return this.transport.send<GetDeviceTimeResponse>({ Command: 'Device/GetDeviceTime' });\n }\n\n /** Sets the temperature unit (`Device/SetDisTempMode`). */\n setTemperatureMode(unit: TemperatureUnit): Promise<DivoomBaseResponse> {\n return this.transport.send({\n Command: 'Device/SetDisTempMode',\n Mode: unit === 'fahrenheit' ? 1 : 0,\n });\n }\n\n /** Enables or disables mirror mode (`Device/SetMirrorMode`). */\n setMirrorMode(enabled: boolean): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Device/SetMirrorMode', Mode: enabled ? 1 : 0 });\n }\n\n /** Selects 24-hour (`true`) or 12-hour (`false`) clock (`Device/SetTime24Flag`). */\n setHourMode(use24Hour: boolean): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Device/SetTime24Flag', Mode: use24Hour ? 1 : 0 });\n }\n\n /** Reads the current on-device weather (`Device/GetWeatherInfo`). */\n getWeather(): Promise<GetWeatherResponse> {\n return this.transport.send<GetWeatherResponse>({ Command: 'Device/GetWeatherInfo' });\n }\n}\n","/**\n * Built-in tool commands: countdown timer, stopwatch, scoreboard, noise meter,\n * and the buzzer.\n *\n * @packageDocumentation\n */\n\nimport type { HttpTransport } from '../transport';\nimport type { DivoomBaseResponse } from '../types/common';\nimport { assertIntInRange } from '../utils';\n\n/** Stopwatch action for {@link ToolCommands.setStopwatch}. */\nexport type StopwatchAction = 'start' | 'stop' | 'reset';\n\nconst STOPWATCH_STATUS: Record<StopwatchAction, number> = { stop: 0, start: 1, reset: 2 };\n\n/** Options for {@link ToolCommands.playBuzzer}. */\nexport interface BuzzerOptions {\n /** On-time per cycle, in milliseconds. Defaults to `500`. */\n activeMs?: number;\n /** Off-time per cycle, in milliseconds. Defaults to `500`. */\n offMs?: number;\n /** Total duration to buzz, in milliseconds. Defaults to `1000`. */\n totalMs?: number;\n}\n\n/** Built-in tool commands. Access via {@link TimesGateClient.tool}. */\nexport class ToolCommands {\n constructor(private readonly transport: HttpTransport) {}\n\n /**\n * Starts or stops a countdown timer (`Tools/SetTimer`).\n *\n * @param minutes - Countdown minutes (0–99).\n * @param seconds - Countdown seconds (0–59).\n * @param start - `true` to start, `false` to stop. Defaults to `true`.\n */\n async setCountdown(minutes: number, seconds: number, start = true): Promise<DivoomBaseResponse> {\n assertIntInRange(minutes, 0, 99, 'minutes');\n assertIntInRange(seconds, 0, 59, 'seconds');\n return this.transport.send({\n Command: 'Tools/SetTimer',\n Minute: minutes,\n Second: seconds,\n Status: start ? 1 : 0,\n });\n }\n\n /** Controls the stopwatch (`Tools/SetStopWatch`). */\n setStopwatch(action: StopwatchAction): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Tools/SetStopWatch', Status: STOPWATCH_STATUS[action] });\n }\n\n /**\n * Sets the scoreboard (`Tools/SetScoreBoard`).\n *\n * @param redScore - Red team score (0–999).\n * @param blueScore - Blue team score (0–999).\n */\n async setScoreboard(redScore: number, blueScore: number): Promise<DivoomBaseResponse> {\n assertIntInRange(redScore, 0, 999, 'redScore');\n assertIntInRange(blueScore, 0, 999, 'blueScore');\n return this.transport.send({\n Command: 'Tools/SetScoreBoard',\n RedScore: redScore,\n BlueScore: blueScore,\n });\n }\n\n /** Starts or stops the noise meter (`Tools/SetNoiseStatus`). */\n setNoiseMeter(start: boolean): Promise<DivoomBaseResponse> {\n return this.transport.send({ Command: 'Tools/SetNoiseStatus', NoiseStatus: start ? 1 : 0 });\n }\n\n /**\n * Plays the buzzer (`Device/PlayBuzzer`). Requires firmware ≥ 90109.\n *\n * @example\n * ```ts\n * await client.tool.playBuzzer({ activeMs: 200, offMs: 100, totalMs: 900 });\n * ```\n */\n async playBuzzer(options: BuzzerOptions = {}): Promise<DivoomBaseResponse> {\n const activeMs = options.activeMs ?? 500;\n const offMs = options.offMs ?? 500;\n const totalMs = options.totalMs ?? 1000;\n assertIntInRange(activeMs, 0, 3_600_000, 'activeMs');\n assertIntInRange(offMs, 0, 3_600_000, 'offMs');\n assertIntInRange(totalMs, 0, 3_600_000, 'totalMs');\n return this.transport.send({\n Command: 'Device/PlayBuzzer',\n ActiveTimeInCycle: activeMs,\n OffTimeInCycle: offMs,\n PlayTotalTime: totalMs,\n });\n }\n}\n","/**\n * The HTTP transport that every command flows through. It builds the request\n * URL, injects the `LocalToken`, enforces timeouts, retries transient failures\n * with exponential backoff, and maps failures onto the SDK's typed\n * {@link DivoomError | error hierarchy}.\n *\n * @packageDocumentation\n */\n\nimport { DEFAULT_PATH, DEFAULT_PORT } from './constants';\nimport {\n DivoomConnectionError,\n DivoomDeviceError,\n DivoomHttpError,\n DivoomTimeoutError,\n DivoomValidationError,\n} from './errors';\nimport type { DivoomBaseResponse, FetchLike } from './types/common';\nimport { delay, drainBody } from './utils';\n\ntype FetchResponse = Awaited<ReturnType<FetchLike>>;\n\n/** Configuration for the {@link HttpTransport}. */\nexport interface TransportOptions {\n /** The device's IP address or hostname, e.g. `\"192.168.1.50\"`. */\n host: string;\n /** TCP port. Defaults to `80` (hardware version 400). */\n port?: number;\n /** Request path. Defaults to `\"/post\"` (hardware version 400). */\n path?: string;\n /** URL scheme. Defaults to `\"http\"`. */\n protocol?: 'http' | 'https';\n /**\n * The device's local authentication token, read from the Divoom app\n * (device → Settings). Injected into every request body. Defaults to `0`,\n * which is accepted by read-only commands but rejected by commands that\n * require authentication (e.g. `Channel/SetBrightness`).\n */\n localToken?: number;\n /** Per-request timeout in milliseconds. Defaults to `8000`. */\n timeoutMs?: number;\n /** Number of automatic retries for transient failures. Defaults to `2`. */\n retries?: number;\n /** Base backoff delay in milliseconds (doubled each retry). Defaults to `300`. */\n retryDelayMs?: number;\n /** A custom `fetch` implementation. Defaults to the global `fetch`. */\n fetch?: FetchLike;\n /** Extra HTTP headers to send with every request. */\n headers?: Record<string, string>;\n}\n\nconst DEFAULTS = {\n port: DEFAULT_PORT,\n path: DEFAULT_PATH,\n protocol: 'http' as const,\n localToken: 0,\n timeoutMs: 8000,\n retries: 2,\n retryDelayMs: 300,\n};\n\n/**\n * Low-level HTTP transport. Most users interact with the high-level\n * {@link TimesGateClient} instead, but the transport is exported for advanced\n * scenarios and testing.\n */\nexport class HttpTransport {\n /** The fully-resolved endpoint URL every request is POSTed to. */\n readonly endpoint: string;\n\n private readonly localToken: number;\n private readonly timeoutMs: number;\n private readonly retries: number;\n private readonly retryDelayMs: number;\n private readonly fetchImpl: FetchLike;\n private readonly headers: Record<string, string>;\n\n constructor(options: TransportOptions) {\n const host = options.host?.trim();\n if (!host) {\n throw new DivoomValidationError('A device `host` (IP address or hostname) is required.');\n }\n if (/[\\s/\\\\?#@]/.test(host)) {\n throw new DivoomValidationError(\n `Invalid device host \"${host}\": expected a bare IP address or hostname.`,\n );\n }\n\n const port = options.port ?? DEFAULTS.port;\n const rawPath = options.path ?? DEFAULTS.path;\n const path = rawPath.startsWith('/') ? rawPath : `/${rawPath}`;\n const protocol = options.protocol ?? DEFAULTS.protocol;\n\n this.endpoint = `${protocol}://${host}:${port}${path}`;\n this.localToken = options.localToken ?? DEFAULTS.localToken;\n this.timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;\n this.retries = Math.max(0, options.retries ?? DEFAULTS.retries);\n this.retryDelayMs = options.retryDelayMs ?? DEFAULTS.retryDelayMs;\n this.fetchImpl = options.fetch ?? globalThis.fetch;\n this.headers = { 'Content-Type': 'application/json', ...options.headers };\n\n if (typeof this.fetchImpl !== 'function') {\n throw new DivoomValidationError(\n 'No `fetch` implementation is available. Use Node 18+ or pass a custom `fetch`.',\n );\n }\n }\n\n /**\n * Sends a command payload to the device and returns the parsed response.\n *\n * The configured `LocalToken` is merged in automatically (an explicit\n * `LocalToken` on the payload wins). Transient network errors, timeouts, and\n * 5xx responses are retried with exponential backoff; device-level errors and\n * 4xx responses are thrown immediately.\n *\n * @typeParam TResponse - The expected response shape.\n * @throws {@link DivoomTimeoutError} when the request exceeds the timeout.\n * @throws {@link DivoomHttpError} on a non-2xx HTTP status.\n * @throws {@link DivoomDeviceError} when the device reports a non-zero `error_code`.\n * @throws {@link DivoomConnectionError} when the device cannot be reached.\n */\n async send<TResponse extends DivoomBaseResponse = DivoomBaseResponse>(\n payload: { Command: string } & Record<string, unknown>,\n ): Promise<TResponse> {\n const body = JSON.stringify({ LocalToken: this.localToken, ...payload });\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.retries; attempt += 1) {\n if (attempt > 0) {\n await delay(this.retryDelayMs * 2 ** (attempt - 1));\n }\n try {\n return await this.attempt<TResponse>(body, payload.Command);\n } catch (error) {\n lastError = error;\n if (!isRetryable(error)) {\n throw error;\n }\n }\n }\n\n throw lastError;\n }\n\n private async attempt<TResponse extends DivoomBaseResponse>(\n body: string,\n command: string,\n ): Promise<TResponse> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n\n // The timeout covers the whole exchange — connection *and* body read.\n try {\n let response: FetchResponse;\n try {\n response = await this.fetchImpl(this.endpoint, {\n method: 'POST',\n headers: this.headers,\n body,\n signal: controller.signal,\n });\n } catch (error) {\n if (controller.signal.aborted) {\n throw new DivoomTimeoutError(command, this.timeoutMs);\n }\n throw new DivoomConnectionError(`Failed to reach Times Gate at ${this.endpoint}.`, {\n cause: error,\n });\n }\n\n if (!response.ok) {\n await drainBody(response);\n throw new DivoomHttpError(response.status, command, this.endpoint);\n }\n\n let text: string;\n try {\n text = await response.text();\n } catch (error) {\n if (controller.signal.aborted) {\n throw new DivoomTimeoutError(command, this.timeoutMs);\n }\n throw new DivoomConnectionError(\n `Failed to read the response body from Times Gate for command \"${command}\".`,\n { cause: error },\n );\n }\n\n const data = parseDeviceBody<TResponse>(text, command);\n if (typeof data.error_code === 'number' && data.error_code !== 0) {\n throw new DivoomDeviceError(data.error_code, command, data);\n }\n return data;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\n/**\n * Parses a device response body into a typed object. An empty body is treated\n * as a successful ack (some write commands return no payload); a non-empty body\n * that isn't a JSON object is surfaced as a typed {@link DivoomConnectionError}\n * rather than leaking a raw `SyntaxError` or a `null`/primitive value.\n */\nfunction parseDeviceBody<T extends DivoomBaseResponse>(text: string, command: string): T {\n if (text.trim() === '') {\n return { error_code: 0 } as T;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (error) {\n throw new DivoomConnectionError(\n `Times Gate returned a malformed (non-JSON) response for command \"${command}\".`,\n { cause: error },\n );\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new DivoomConnectionError(\n `Times Gate returned an unexpected (non-object) response for command \"${command}\".`,\n );\n }\n return parsed as T;\n}\n\n/** Determines whether a failed attempt should be retried. */\nfunction isRetryable(error: unknown): boolean {\n if (error instanceof DivoomTimeoutError || error instanceof DivoomConnectionError) {\n return true;\n }\n if (error instanceof DivoomHttpError) {\n return error.status >= 500;\n }\n return false;\n}\n","/**\n * The high-level {@link TimesGateClient} — one object that exposes every\n * device-side command, grouped by area, over a single configured transport.\n *\n * @packageDocumentation\n */\n\nimport { AnimationCommands } from './commands/animation';\nimport { BatchCommands } from './commands/batch';\nimport { DialCommands } from './commands/dial';\nimport { DrawCommands } from './commands/draw';\nimport { SystemCommands } from './commands/system';\nimport { ToolCommands } from './commands/tool';\nimport { HttpTransport, type TransportOptions } from './transport';\nimport type { DivoomBaseResponse } from './types/common';\n\n/** Options for constructing a {@link TimesGateClient}. */\nexport interface TimesGateClientOptions extends TransportOptions {\n /**\n * Optional seed for the PicID generator used by {@link TimesGateClient.draw}.\n * Mostly useful for deterministic tests.\n */\n picIdSeed?: number;\n}\n\n/**\n * The main entry point for controlling a Times Gate on your local network.\n *\n * @example\n * ```ts\n * import { TimesGateClient } from 'divoom-timesgate-sdk';\n *\n * const client = new TimesGateClient({\n * host: '192.168.1.50',\n * localToken: 229930, // from the Divoom app → device → Settings\n * });\n *\n * if (await client.ping()) {\n * await client.system.setBrightness(80);\n * }\n * ```\n */\nexport class TimesGateClient {\n /** The underlying HTTP transport. */\n readonly transport: HttpTransport;\n /** System settings: brightness, screen, time, weather, display modes. */\n readonly system: SystemCommands;\n /** Dial/channel control: whole vs independent dials, sub-dials, visualizers. */\n readonly dial: DialCommands;\n /** Built-in tools: countdown, stopwatch, scoreboard, noise meter, buzzer. */\n readonly tool: ToolCommands;\n /** The image pipeline: push frames/animations, manage the device cache. */\n readonly draw: DrawCommands;\n /** Animations & text: stored GIFs, GIF URLs, text overlays, item lists. */\n readonly animation: AnimationCommands;\n /** Batch execution: run multiple commands or a remote command list. */\n readonly batch: BatchCommands;\n\n constructor(options: TimesGateClientOptions) {\n this.transport = new HttpTransport(options);\n this.system = new SystemCommands(this.transport);\n this.dial = new DialCommands(this.transport);\n this.tool = new ToolCommands(this.transport);\n this.draw = new DrawCommands(this.transport, options.picIdSeed);\n this.animation = new AnimationCommands(this.transport);\n this.batch = new BatchCommands(this.transport);\n }\n\n /** The resolved endpoint URL this client talks to. */\n get endpoint(): string {\n return this.transport.endpoint;\n }\n\n /**\n * Sends a raw command payload — an escape hatch for commands the typed API\n * doesn't cover yet. The configured `LocalToken` is still injected.\n */\n send<TResponse extends DivoomBaseResponse = DivoomBaseResponse>(\n payload: { Command: string } & Record<string, unknown>,\n ): Promise<TResponse> {\n return this.transport.send<TResponse>(payload);\n }\n\n /**\n * Checks whether the device is reachable by issuing `Channel/GetIndex`.\n * Returns `false` instead of throwing on failure.\n */\n async ping(): Promise<boolean> {\n try {\n await this.dial.getIndex();\n return true;\n } catch {\n return false;\n }\n }\n}\n","/**\n * The Divoom **cloud** API client (`app.divoom-gz.com`). These endpoints don't\n * touch your device directly — they discover the `ClockId`, `FileId`, and font\n * ids you then feed to on-device {@link DialCommands} / {@link AnimationCommands}.\n *\n * Cloud responses use `ReturnCode` (0 = success) rather than `error_code`.\n *\n * @packageDocumentation\n */\n\nimport { DivoomCloudError, DivoomConnectionError, DivoomTimeoutError } from './errors';\nimport type { FetchLike } from './types/common';\nimport { delay, drainBody } from './utils';\n\n/** Default Divoom cloud base URL. */\nexport const DEFAULT_CLOUD_BASE_URL = 'https://app.divoom-gz.com';\n\n/** Base shape of every Divoom cloud response. */\nexport interface CloudResponse {\n /** `0` indicates success. */\n ReturnCode: number;\n /** Human-readable status message. */\n ReturnMessage?: string;\n [key: string]: unknown;\n}\n\n/** Configuration for {@link DivoomCloudClient} and {@link cloudPost}. */\nexport interface CloudClientOptions {\n /** Cloud base URL. Defaults to {@link DEFAULT_CLOUD_BASE_URL}. */\n baseUrl?: string;\n /** Custom `fetch`. Defaults to the global `fetch`. */\n fetch?: FetchLike;\n /** Per-request timeout in ms. Defaults to `10000`. */\n timeoutMs?: number;\n /** Retry count for transient failures. Defaults to `2`. */\n retries?: number;\n /** Base backoff in ms (doubled per retry). Defaults to `300`. */\n retryDelayMs?: number;\n /** Extra HTTP headers. */\n headers?: Record<string, string>;\n}\n\n/** A liked/uploaded image entry. */\nexport interface CloudImage {\n /** Display name. */\n FileName: string;\n /** File identifier — pass to {@link AnimationCommands.playStoredGif}. */\n FileId: string;\n}\n\n/** A sub-dial entry from {@link DivoomCloudClient.getDialList}. */\nexport interface SubDial {\n /** Dial identifier. */\n ClockId: number;\n /** Display name. */\n Name: string;\n}\n\n/** A whole-dial entry from {@link DivoomCloudClient.getWholeDialList}. */\nexport interface WholeDial {\n /** Dial identifier. */\n ClockId: number;\n /** Display name. */\n ClockName: string;\n /** Description. */\n ClockExPlain: string;\n}\n\n/** A font entry from {@link DivoomCloudClient.getFontList}. */\nexport interface CloudFont {\n /** Font id — use as `font` in {@link DisplayItem}. */\n id: number;\n /** Font name. */\n name: string;\n /** Glyph width. */\n width: string;\n /** Glyph height. */\n high: string;\n /** Included character set. */\n charset: string;\n /** `0` = scrolls when too wide, `1` = no scroll. */\n type: number;\n}\n\n/** An independent dial group from {@link DivoomCloudClient.getChannelInfo}. */\nexport interface IndependentDialGroup {\n /** Group display name. */\n IndependenceName: string;\n /** Group id — used as `lcdIndependence` in {@link DialCommands}. */\n LcdIndependence: number;\n /** Per-panel clock ids. */\n LcdList: Array<{ LcdClockId: number }>;\n}\n\n/** Response from {@link DivoomCloudClient.getDialTypes}. */\nexport interface DialTypesResponse extends CloudResponse {\n /** Available sub-dial category names. */\n DialTypeList: string[];\n}\n\n/** Response from {@link DivoomCloudClient.getDialList}. */\nexport interface DialListResponse extends CloudResponse {\n /** Total available dials in this category. */\n TotalNum: number;\n /** This page of sub-dials (30 per page). */\n DialList: SubDial[];\n}\n\n/** Response from {@link DivoomCloudClient.getWholeDialList}. */\nexport interface WholeDialListResponse extends CloudResponse {\n /** Total available whole dials. */\n TotalNum: number;\n /** This page of whole dials (30 per page). */\n ClockList: WholeDial[];\n}\n\n/** Response from {@link DivoomCloudClient.getChannelInfo}. */\nexport interface ChannelInfoResponse extends CloudResponse {\n /** Current mode: `0` = whole, `1` = independent. */\n ChannelType: number;\n /** Selected independent group id. */\n LcdIndependence: number;\n /** Selected whole-dial id. */\n ClockId: number;\n /** All independent dial groups. */\n LcdIndependenceList: IndependentDialGroup[];\n /** The device id. */\n DeviceId: number;\n}\n\n/** Response from {@link DivoomCloudClient.getLikedImages} / {@link DivoomCloudClient.getUploadedImages}. */\nexport interface ImageListResponse extends CloudResponse {\n /** The returned images. */\n ImgList: CloudImage[];\n}\n\n/** Response from {@link DivoomCloudClient.getFontList}. */\nexport interface FontListResponse extends CloudResponse {\n /** Available fonts. */\n FontList: CloudFont[];\n}\n\n/**\n * Parses a cloud response body into a typed object: empty body → success ack,\n * non-JSON or non-object body → a typed {@link DivoomConnectionError} instead\n * of a raw `SyntaxError` or a `null`/primitive leaking through.\n */\nfunction parseCloudBody<T extends CloudResponse>(text: string, url: string): T {\n if (text.trim() === '') {\n return { ReturnCode: 0 } as T;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (error) {\n throw new DivoomConnectionError(\n `Cloud endpoint ${url} returned a malformed (non-JSON) response.`,\n {\n cause: error,\n },\n );\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new DivoomConnectionError(\n `Cloud endpoint ${url} returned an unexpected (non-object) response.`,\n );\n }\n return parsed as T;\n}\n\n/**\n * POSTs JSON to a Divoom cloud URL with timeout, retry, and `ReturnCode`\n * checking. Exported for advanced use (e.g. {@link discoverDevices}).\n */\nexport async function cloudPost<T extends CloudResponse>(\n url: string,\n body: Record<string, unknown>,\n options: CloudClientOptions = {},\n): Promise<T> {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n const timeoutMs = options.timeoutMs ?? 10000;\n const retries = Math.max(0, options.retries ?? 2);\n const retryDelayMs = options.retryDelayMs ?? 300;\n const headers = { 'Content-Type': 'application/json', ...options.headers };\n const payload = JSON.stringify(body);\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= retries; attempt += 1) {\n if (attempt > 0) await delay(retryDelayMs * 2 ** (attempt - 1));\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n // Network/abort failures are retryable, so they're handled here and the loop\n // continues. Response-level decisions happen *outside* this try so a\n // fail-fast `throw` can't be swallowed by the catch.\n let response: Awaited<ReturnType<FetchLike>>;\n try {\n response = await fetchImpl(url, {\n method: 'POST',\n headers,\n body: payload,\n signal: controller.signal,\n });\n } catch (error) {\n lastError = controller.signal.aborted\n ? new DivoomTimeoutError(url, timeoutMs)\n : new DivoomConnectionError(`Failed to reach cloud endpoint ${url}.`, { cause: error });\n continue;\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n await drainBody(response);\n const httpError = new DivoomConnectionError(\n `Cloud request to ${url} failed: HTTP ${response.status}.`,\n );\n // 4xx is a client error — fail fast. 5xx is transient — remember and retry.\n if (response.status < 500) throw httpError;\n lastError = httpError;\n continue;\n }\n\n let text: string;\n try {\n text = await response.text();\n } catch (error) {\n lastError = new DivoomConnectionError(`Failed to read cloud response body from ${url}.`, {\n cause: error,\n });\n continue;\n }\n\n let data: T;\n try {\n data = parseCloudBody<T>(text, url);\n } catch (error) {\n // A malformed/non-object body may be a transient hiccup — retry like a\n // read failure rather than failing fast.\n lastError = error;\n continue;\n }\n if (typeof data.ReturnCode === 'number' && data.ReturnCode !== 0) {\n throw new DivoomCloudError(data.ReturnCode, url, data.ReturnMessage);\n }\n return data;\n }\n\n throw lastError instanceof Error\n ? lastError\n : new DivoomConnectionError(`Cloud request to ${url} failed.`);\n}\n\n/** Client for the Divoom cloud discovery APIs. */\nexport class DivoomCloudClient {\n private readonly baseUrl: string;\n private readonly options: CloudClientOptions;\n\n constructor(options: CloudClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_CLOUD_BASE_URL).replace(/\\/$/, '');\n this.options = options;\n }\n\n private post<T extends CloudResponse>(\n path: string,\n body: Record<string, unknown> = {},\n ): Promise<T> {\n return cloudPost<T>(`${this.baseUrl}${path}`, body, this.options);\n }\n\n /** Lists sub-dial category names (`Channel/GetDialType`). */\n getDialTypes(): Promise<DialTypesResponse> {\n return this.post<DialTypesResponse>('/Channel/GetDialType');\n }\n\n /** Lists sub-dials in a category, paged 30 at a time (`Channel/GetDialList`). */\n getDialList(dialType: string, page = 1, deviceType = 'LCD'): Promise<DialListResponse> {\n return this.post<DialListResponse>('/Channel/GetDialList', {\n DialType: dialType,\n DeviceType: deviceType,\n Page: page,\n });\n }\n\n /** Lists whole (5-panel) dials, paged (`Channel/Get5LcdClockListForCommon`). */\n getWholeDialList(page = 1): Promise<WholeDialListResponse> {\n return this.post<WholeDialListResponse>('/Channel/Get5LcdClockListForCommon', { Page: page });\n }\n\n /** Gets channel info incl. independent dial groups (`Channel/Get5LcdInfoV2`). */\n getChannelInfo(deviceId: number, deviceType = 'LCD'): Promise<ChannelInfoResponse> {\n return this.post<ChannelInfoResponse>('/Channel/Get5LcdInfoV2', {\n DeviceId: deviceId,\n DeviceType: deviceType,\n });\n }\n\n /** Lists the account's liked images (`Device/GetImgLikeList`). */\n getLikedImages(deviceId: number, deviceMac: string, page = 1): Promise<ImageListResponse> {\n return this.post<ImageListResponse>('/Device/GetImgLikeList', {\n DeviceId: deviceId,\n DeviceMac: deviceMac,\n Page: page,\n });\n }\n\n /** Lists the account's uploaded images (`Device/GetImgUploadList`). */\n getUploadedImages(deviceId: number, deviceMac: string, page = 1): Promise<ImageListResponse> {\n return this.post<ImageListResponse>('/Device/GetImgUploadList', {\n DeviceId: deviceId,\n DeviceMac: deviceMac,\n Page: page,\n });\n }\n\n /** Lists fonts usable in {@link AnimationCommands.sendItemList} (`Device/GetTimeDialFontList`). */\n getFontList(): Promise<FontListResponse> {\n return this.post<FontListResponse>('/Device/GetTimeDialFontList');\n }\n}\n","/**\n * LAN device discovery. Divoom's cloud reports every device bound to the\n * caller's public IP, which is how you find a Times Gate's local IP address\n * without scanning the network yourself.\n *\n * @packageDocumentation\n */\n\nimport { type CloudClientOptions, type CloudResponse, cloudPost } from './cloud';\nimport { LAN_DISCOVERY_URL } from './constants';\n\n/** A device returned by {@link discoverDevices}. */\nexport interface DiscoveredDevice {\n /** Friendly device name, e.g. `\"Times Gate\"`. */\n name: string;\n /** Divoom device id. */\n id: number;\n /** The device's private (LAN) IP — use this as the client `host`. */\n ip: string;\n /** The device's MAC address. */\n mac: string;\n}\n\ninterface LanDeviceListResponse extends CloudResponse {\n DeviceList?: Array<{\n DeviceName?: string;\n DeviceId?: number;\n DevicePrivateIP?: string;\n DeviceMac?: string;\n }>;\n}\n\n/**\n * Discovers Divoom devices on the same network as this machine.\n *\n * @example\n * ```ts\n * const devices = await discoverDevices();\n * const gate = devices.find((d) => d.name.includes('Times Gate'));\n * const client = new TimesGateClient({ host: gate!.ip, localToken: 229930 });\n * ```\n *\n * @remarks Requires outbound internet access (the lookup goes through Divoom's\n * cloud). It returns devices seen from your public IP, so it won't work across\n * different networks or some VPNs.\n */\nexport async function discoverDevices(\n options: CloudClientOptions = {},\n): Promise<DiscoveredDevice[]> {\n const response = await cloudPost<LanDeviceListResponse>(LAN_DISCOVERY_URL, {}, options);\n return (response.DeviceList ?? []).map((device) => ({\n name: device.DeviceName ?? '',\n id: device.DeviceId ?? 0,\n ip: device.DevicePrivateIP ?? '',\n mac: device.DeviceMac ?? '',\n }));\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "divoom-timesgate-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A fully type-safe Node.js & TypeScript SDK for controlling the Divoom Times Gate over your local network — high-resolution image & animation pipeline, complete command coverage, and zero-guesswork docs.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"divoom",
|
|
7
|
+
"times-gate",
|
|
8
|
+
"timesgate",
|
|
9
|
+
"pixoo",
|
|
10
|
+
"led-matrix",
|
|
11
|
+
"smart-display",
|
|
12
|
+
"iot",
|
|
13
|
+
"sdk",
|
|
14
|
+
"typescript",
|
|
15
|
+
"now-playing"
|
|
16
|
+
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "Jason Praful",
|
|
19
|
+
"homepage": "https://github.com/jasonpraful/divoom-timesgate-sdk#readme",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/jasonpraful/divoom-timesgate-sdk.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/jasonpraful/divoom-timesgate-sdk/issues"
|
|
26
|
+
},
|
|
27
|
+
"type": "module",
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js",
|
|
33
|
+
"require": "./dist/index.cjs"
|
|
34
|
+
},
|
|
35
|
+
"./image": {
|
|
36
|
+
"types": "./dist/image/index.d.ts",
|
|
37
|
+
"import": "./dist/image/index.js",
|
|
38
|
+
"require": "./dist/image/index.cjs"
|
|
39
|
+
},
|
|
40
|
+
"./package.json": "./package.json"
|
|
41
|
+
},
|
|
42
|
+
"main": "./dist/index.cjs",
|
|
43
|
+
"module": "./dist/index.js",
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"README.md",
|
|
48
|
+
"LICENSE"
|
|
49
|
+
],
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"sharp": "^0.33.5"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@changesets/cli": "^2.27.11",
|
|
58
|
+
"@eslint/js": "^9.17.0",
|
|
59
|
+
"@types/node": "^22.10.2",
|
|
60
|
+
"@vitest/coverage-v8": "^3.2.6",
|
|
61
|
+
"eslint": "^9.17.0",
|
|
62
|
+
"eslint-config-prettier": "^9.1.0",
|
|
63
|
+
"prettier": "^3.4.2",
|
|
64
|
+
"tsup": "^8.3.5",
|
|
65
|
+
"typedoc": "^0.27.5",
|
|
66
|
+
"typescript": "^5.7.2",
|
|
67
|
+
"typescript-eslint": "^8.18.1",
|
|
68
|
+
"vitest": "^3.2.6"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsup",
|
|
72
|
+
"dev": "tsup --watch",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"test": "vitest run",
|
|
75
|
+
"test:watch": "vitest",
|
|
76
|
+
"test:coverage": "vitest run --coverage",
|
|
77
|
+
"lint": "eslint .",
|
|
78
|
+
"lint:fix": "eslint . --fix",
|
|
79
|
+
"format": "prettier --write .",
|
|
80
|
+
"format:check": "prettier --check .",
|
|
81
|
+
"docs": "typedoc",
|
|
82
|
+
"check": "pnpm run typecheck && pnpm run lint && pnpm run format:check && pnpm run test",
|
|
83
|
+
"changeset": "changeset",
|
|
84
|
+
"version-packages": "changeset version",
|
|
85
|
+
"release": "pnpm run build && changeset publish"
|
|
86
|
+
}
|
|
87
|
+
}
|