UNPKG

philtv-js

Version:

A simple library to pair and interact with Philips TV

679 lines 20 kB
import { HttpClient, RequestOptions } from "urllib"; import { z } from "zod"; //#region src/http-clients/http-digest-client.d.ts /** @internal */ type ApiResult<T = unknown> = { success: true; data: T; } | { success: false; error: Error; }; type GetHttpDigestClient = { user: string; password: string; baseUrl: string; options?: { rejectUnauthorized?: boolean; }; }; declare function getHttpDigestClient(config: GetHttpDigestClient): { client: HttpClient; request: <T = unknown>(url: string, reqOptions?: RequestOptions) => Promise<ApiResult<T>>; }; //#endregion //#region src/schemas/philtvApi.schema.d.ts declare const philTVApiParamsSchemas: z.ZodObject<{ apiUrl: z.ZodURL; user: z.ZodString; password: z.ZodString; }, z.core.$strip>; //#endregion //#region src/lib/api/ambilight/getFullInformation.d.ts type GetFullAmbilightInformationResult = { configuration: AmbilightCurrentConfiguration | null; brightness: MenuSettingValueInner | null; currentBrightness: number | null; mode: AmbilightModeResponse | null; cached: AmbilightPixelData | null; ambiHue: AmbiHueState | null; }; //#endregion //#region src/schemas/jointspace.schema.d.ts declare const inputKeysSchema: z.ZodEnum<{ Adjust: "Adjust"; AmbilightOnOff: "AmbilightOnOff"; Back: "Back"; BlueColour: "BlueColour"; ChannelStepDown: "ChannelStepDown"; ChannelStepUp: "ChannelStepUp"; Confirm: "Confirm"; CursorDown: "CursorDown"; CursorLeft: "CursorLeft"; CursorRight: "CursorRight"; CursorUp: "CursorUp"; Digit0: "Digit0"; Digit1: "Digit1"; Digit2: "Digit2"; Digit3: "Digit3"; Digit4: "Digit4"; Digit5: "Digit5"; Digit6: "Digit6"; Digit7: "Digit7"; Digit8: "Digit8"; Digit9: "Digit9"; Dot: "Dot"; FastForward: "FastForward"; Find: "Find"; GreenColour: "GreenColour"; Home: "Home"; Info: "Info"; Mute: "Mute"; Next: "Next"; Online: "Online"; Options: "Options"; Pause: "Pause"; PlayPause: "PlayPause"; Previous: "Previous"; Record: "Record"; RedColour: "RedColour"; Rewind: "Rewind"; Source: "Source"; Standby: "Standby"; Stop: "Stop"; Subtitle: "Subtitle"; Teletext: "Teletext"; Viewmode: "Viewmode"; VolumeDown: "VolumeDown"; VolumeUp: "VolumeUp"; WatchTV: "WatchTV"; YellowColour: "YellowColour"; }>; declare const ambilightFollowVideoModeSchema: z.ZodEnum<{ COMFORT: "COMFORT"; GAME: "GAME"; IMMERSIVE: "IMMERSIVE"; NATURAL: "NATURAL"; RELAX: "RELAX"; STANDARD: "STANDARD"; VIVID: "VIVID"; }>; declare const ambilightFollowAudioModeSchema: z.ZodEnum<{ ENERGY_ADAPTIVE_BRIGHTNESS: "ENERGY_ADAPTIVE_BRIGHTNESS"; ENERGY_ADAPTIVE_COLORS: "ENERGY_ADAPTIVE_COLORS"; KNIGHT_RIDER_ALTERNATING: "KNIGHT_RIDER_ALTERNATING"; MODE_RANDOM: "MODE_RANDOM"; RANDOM_PIXEL_FLASH: "RANDOM_PIXEL_FLASH"; SPECTRUM_ANALYSER: "SPECTRUM_ANALYSER"; VU_METER: "VU_METER"; SPECTRUM_ANALYZER: "SPECTRUM_ANALYZER"; KNIGHT_RIDER_CLOCKWISE: "KNIGHT_RIDER_CLOCKWISE"; STROBO: "STROBO"; PARTY: "PARTY"; }>; declare const ambilightBrightnessChoicesSchema: z.ZodLiteral<0 | 7 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10>; declare const ambilightModesSchema: z.ZodEnum<{ manual: "manual"; internal: "internal"; expert: "expert"; }>; //#endregion //#region src/types/jointspace.d.ts /** @internal */ type InputKey = z.infer<typeof inputKeysSchema>; /** @internal */ type AmbilightFollowVideoMode = z.infer<typeof ambilightFollowVideoModeSchema>; /** @internal */ type AmbilightFollowAudioMode = z.infer<typeof ambilightFollowAudioModeSchema>; /** @internal */ type AmbilightBrightnessChoices = z.infer<typeof ambilightBrightnessChoicesSchema>; /** @internal */ type AmbilightMode = z.infer<typeof ambilightModesSchema>; //#endregion //#region src/types/jointspace-api.types.d.ts type PowerState = 'On' | 'Off' | 'Standby'; type RGBColor = { r: number; g: number; b: number; }; type HSBColor = { hue: number; saturation: number; brightness: number; }; type ApiVersion = { Major: number; Minor: number; Patch: number; }; type JsonFeatures = { editfavorites?: string[]; recordings?: string[]; ambilight?: string[]; menuitems?: string[]; textentry?: string[]; applications?: string[]; pointer?: string[]; inputkey?: string[]; activities?: string[]; channels?: string[]; mappings?: string[]; }; type SystemFeatures = { tvtype?: 'consumer' | 'professional'; content?: string[]; tvsearch?: string; pairing_type?: 'digest_auth_pairing' | 'none'; secured_transport?: 'true' | 'false'; }; type SystemFeaturing = { jsonfeatures?: JsonFeatures; systemfeatures?: SystemFeatures; }; type SystemInfo = { menulanguage: string; name: string; country: string; serialnumber_encrypted?: string; softwareversion_encrypted?: string; model_encrypted?: string; deviceid_encrypted?: string; serialnumber?: string; softwareversion?: string; model?: string; deviceid?: string; nettvversion?: string; epgsource?: string; api_version: ApiVersion; featuring: SystemFeaturing; }; type SystemInfoEnriched = SystemInfo & { fullApiVersion: string; }; type AudioVolume = { muted: boolean; current: number; min: number; max: number; }; type AudioVolumeUpdate = { muted?: boolean; current?: number; }; type InputKeyPayload = { key: InputKey; }; type Source = { id: string; name?: string; }; type SourceList = { version: number; sources: Record<string, Source>; }; type CurrentSource = { id: string; }; type Channel = { ccid: number; preset: string; name: string; }; type ChannelList = { id: string; version: string; Channel: Channel[]; }; type ChannelListSummary = { id: string; version: string; listType: string; medium: 'mixed' | 'cable' | 'satellite' | 'antenna'; active: boolean; operator?: string; installCountry?: string; }; type ChannelLists = { version: number; channellists: ChannelListSummary[]; }; type CurrentChannel = { channel: Channel; channelList: { id: string; version: string; }; }; type SetCurrentChannel = { channel: Pick<Channel, 'ccid'>; channelList: { id: string; version: string; }; }; type AmbilightTopology = { layers: string | number; left: number; top: number; bottom: number; right: number; }; type AmbilightModeResponse = { current: AmbilightMode; }; type AmbilightModePayload = { current: AmbilightMode; }; type AmbilightSide = Record<string, RGBColor>; type AmbilightLayer = { left?: AmbilightSide; top?: AmbilightSide; right?: AmbilightSide; bottom?: AmbilightSide; }; type AmbilightPixelData = { layer1: AmbilightLayer; layer2?: AmbilightLayer; layer3?: AmbilightLayer; }; type AmbilightStyleName = 'OFF' | 'FOLLOW_VIDEO' | 'FOLLOW_AUDIO' | 'FOLLOW_COLOR' | 'LOUNGE' | 'MANUAL' | 'EXPERT' | 'GRID'; type AmbilightFollowColorAlgorithm = 'MANUAL_HUE' | 'AUTOMATIC_HUE'; type AmbilightCurrentConfiguration = { styleName: AmbilightStyleName; isExpert: boolean; menuSetting?: AmbilightFollowVideoMode | AmbilightFollowAudioMode | AmbilightFollowColorAlgorithm | string; stringValue?: string; algorithm?: AmbilightFollowAudioMode | AmbilightFollowColorAlgorithm; }; type AmbilightSupportedStyle = { styleName: AmbilightStyleName; algorithms?: string[]; maxTuning?: number; maxSpeed?: number; }; type AmbilightSupportedStyles = { supportedStyles: AmbilightSupportedStyle[]; }; type AmbilightPower = { power: 'On' | 'Off'; }; type AmbilightLounge = { color: HSBColor; colordelta: HSBColor; speed: number; mode: 'Default' | string; }; type AmbiHueState = { power?: 'On' | 'Off'; [key: string]: unknown; }; type AppIntent = { action: string; component: { packageName: string; className: string; }; }; type Application = { label: string; id: string; order?: number; type?: string; intent?: AppIntent; }; type ApplicationList = { version?: number; applications: Application[]; }; type ActivityComponent = { packageName: string; className: string; }; type ActivityIntent = { action?: string; data?: string; component: ActivityComponent; }; type CurrentActivity = { component: ActivityComponent; } | { channel: CurrentChannel; }; type PowerStateResponse = { powerstate: PowerState; }; type PowerStatePayload = { powerstate: PowerState; }; type FlatNodeType = 'SLIDER_NODE' | 'LIST_NODE' | 'TOGGLE_NODE' | (string & {}); type MenuItemNode = { node_id: number; type: FlatNodeType; string_id?: string; context?: string; data?: unknown; }; type MenuItemsSettingsResponse = { version: number; node: MenuItemNode; }; type MenuItemsSettingsRequest = { nodes: Array<{ nodeid: number; }>; }; type MenuSettingValueData = Record<string, unknown>; type MenuSettingValueInner = { Nodeid: number; Controllable?: 'true' | 'false'; Available?: 'true' | 'false'; data?: MenuSettingValueData; }; type MenuSettingValue = { value: MenuSettingValueInner; }; type MenuItemsCurrentResponseNode = { version: number; values: MenuSettingValue[]; }; type MenuItemsSettingsValue = { value: { Nodeid: number; Controllable?: 'true' | 'false'; Available?: 'true' | 'false'; data?: unknown; }; }; type MenuItemsSettingsUpdatePayload = { values: MenuItemsSettingsValue[]; }; type PairingRequestPayload = { scope: string[]; device: { app_id: string; id: string; device_name: string; device_os: string; app_name: string; type: string; }; }; type PairingRequestResponse = { error_id: 'SUCCESS' | string; error_text: string; auth_key?: string; timestamp?: number; timeout?: number; }; type PairingGrantPayload = { auth: { pin: string; auth_timestamp: number; auth_signature: string; }; device: { app_id: string; id: string; device_name: string; device_os: string; app_name: string; type: string; }; }; type PairingGrantResponse = { error_id: 'SUCCESS' | string; error_text: string; auth_key?: string; }; type GoogleAssistantPayload = { query: string; }; //#endregion //#region src/types/index.d.ts /** * Parameters required to initialize the `PhilTVApiBase` class. * * This object includes the API connection details and optional configuration settings. */ type PhilTVApiParams = z.infer<typeof philTVApiParamsSchemas>; //#endregion //#region src/lib/api/MenuApi.d.ts /** * Provides methods to interact with the Menu API, * including menu structure retrieval, item lookup, and setting updates. */ declare class MenuApi { private readonly digestClient; /** @internal */ constructor(digestClient: ReturnType<typeof getHttpDigestClient>); /** * Retrieves the full menu structure from the device. * @param opts - Options object. If `flat` is `true`, returns a flattened array of nodes instead of the raw tree. * @throws If the request fails. */ getMenuStructure(opts?: { flat: boolean; }): Promise<any>; /** * Finds a single menu item node by context string or node ID. * @param context - The context string to match against. Takes priority over `nodeId` if provided. * @param nodeId - The node ID to match against, used when `context` is not provided. * @returns The matching {@link MenuItemNode}. * @throws If no matching item is found or the structure request fails. */ getMenuStructureItem(context?: string, nodeId?: number): Promise<MenuItemNode>; /** * Updates the setting value of a given menu item node. * @param item - The menu item node to update. Throws if `undefined`. * @param value - The new value to apply. Automatically formatted based on the node type (`SLIDER_NODE`, `TOGGLE_NODE`, `LIST_NODE`). * @throws If the item is undefined or the request fails. */ setMenuItemSetting(item: MenuItemNode | undefined, value: unknown): Promise<void>; /** * Retrieves the current setting values for a given node ID. * @param nodeId - The ID of the node to query. * @returns The list of current setting values for the node. * @throws If the request fails. */ getCurrentSetting(nodeId: number): Promise<MenuSettingValue[]>; } //#endregion //#region src/lib/api/AmbilightApi.d.ts /** * Provides methods to interact with the Ambilight API, * including brightness control, mode management, color configuration, and state retrieval. */ declare class AmbilightApi { /** @internal */ readonly digestClient: ReturnType<typeof getHttpDigestClient>; private readonly menuApi; /** @internal */ constructor( /** @internal */ digestClient: ReturnType<typeof getHttpDigestClient>, menuApi: MenuApi); /** * Sets the Ambilight brightness to the given level. * @param brightness - The desired brightness level. */ setBrightness(brightness: AmbilightBrightnessChoices): Promise<void>; /** * Retrieves full brightness information including available choices and current value. */ getBrightnessInformation(): Promise<MenuSettingValueInner>; /** * Returns the current brightness value. */ getBrightnessValue(): Promise<number>; /** * Increases the Ambilight brightness by one step. */ increaseBrightness(): Promise<void>; /** * Decreases the Ambilight brightness by one step. */ decreaseBrightness(): Promise<void>; /** * Returns the current Ambilight mode. */ getMode(): Promise<AmbilightModeResponse>; /** * Sets the Ambilight mode. * @param mode - The Ambilight mode to apply. */ setMode(mode: AmbilightMode): Promise<void>; /** * Retrieves full Ambilight information including mode, brightness, and configuration. */ getFullInformation(): Promise<GetFullAmbilightInformationResult>; /** * Posts a new current configuration to the Ambilight API. * @param options - The configuration options including style name and menu setting. * @protected */ protected setCurrentConfiguration(options: AmbilightCurrentConfiguration): Promise<void>; /** * Sets the Ambilight to Follow Video mode. * @param mode - The follow video mode to apply. * @throws If the provided mode fails schema validation. */ setFollowVideoMode(mode: AmbilightFollowVideoMode): Promise<void>; /** * Sets the Ambilight to Follow Audio mode. * @param mode - The follow audio mode to apply. * @throws If the provided mode fails schema validation. */ setFollowAudioMode(mode: AmbilightFollowAudioMode): Promise<void>; /** * Turns off the Ambilight. */ turnOff(): Promise<void>; /** * Sets the Ambilight to a static color from a hex string. * @param hexColor - The target color as a hex string (e.g. `#FF8800`). * @param opt - Optional settings. If `brightness` is provided, it will be applied before setting the color. */ setStaticColor(hexColor: string, opt?: { brightness: AmbilightBrightnessChoices; }): Promise<void>; /** * Sends an RGB color to the Ambilight cached endpoint. * @param data - The RGB color to apply. * @throws If the request fails. */ setCachedColor(data: RGBColor): Promise<void>; /** * Retrieves the current cached Ambilight pixel state. * @returns The current pixel data. * @throws If the request fails. */ getCachedState(): Promise<AmbilightPixelData>; /** * Returns the current AmbiHue (Philips Hue sync) power state. * @throws If the request fails. */ getAmbiHue(): Promise<AmbiHueState>; /** * Retrieves the current Ambilight configuration from the API. * @throws If the request fails. */ getConfiguration(): Promise<AmbilightCurrentConfiguration>; } //#endregion //#region src/lib/api/InputApi.d.ts declare class InputApi { private readonly digestClient; /** @internal */ constructor(digestClient: ReturnType<typeof getHttpDigestClient>); /** * Sends a key press event to the device. * @param key - The input key to send. * @throws If the provided key fails schema validation or the request fails. */ sendKey(key: InputKey): Promise<void>; } //#endregion //#region src/lib/api/SystemApi.d.ts /** * Provides methods to interact with the System API, * including device information, current activity, and application listing. */ declare class SystemApi { private readonly digestClient; /** @internal */ constructor(digestClient: ReturnType<typeof getHttpDigestClient>); /** * Retrieves system information from the device. * @returns A {@link SystemInfoEnriched} object extending the raw system info with a formatted `fullApiVersion` string (e.g. `"6.2.0"`). * @throws If the request fails. */ getSystem(): Promise<SystemInfoEnriched>; /** * Retrieves the current activity running on the device (e.g. active app or source). * @throws If the request fails. */ getCurrentActivity(): Promise<CurrentActivity>; /** * Retrieves the list of installed applications on the device. * @throws If the request fails. */ getApplications(): Promise<ApplicationList>; } //#endregion //#region src/lib/api/PhilTVApi.d.ts declare class PhilTVApi { /** @internal */ readonly digestClient: ReturnType<typeof getHttpDigestClient>; readonly menu: MenuApi; readonly system: SystemApi; readonly input: InputApi; readonly ambilight: AmbilightApi; constructor(params: PhilTVApiParams); } //#endregion //#region src/utils/device.utils.d.ts declare function getDeviceObject(deviceId: string): { app_id: string; id: string; device_name: string; device_os: string; app_name: string; type: string; }; //#endregion //#region src/lib/pairing/PhilTVPairing.d.ts /** * @internal */ interface SystemInformation { apiVersion: number; systemFeatures: Record<string, unknown>; isSecureTransport: boolean; isGoodPairingType: boolean; isReady: boolean; } /** * @internal */ type PhilTVPairingParams = { tvIp: string; apiPort?: number; }; /** @internal */ declare class PhilTVPairing { private tvBase; readonly deviceId: string; readonly apiUrls: { secure: string; }; readonly deviceInformation: ReturnType<typeof getDeviceObject>; private httpClients; private startPairingResponse; private credentials; private apiVersion; pairingRequestUrl: string; constructor(initParams: PhilTVPairingParams); init(): Promise<ApiResult<SystemInformation>>; startPairing(): Promise<ApiResult<Record<string, unknown>>>; completePairing(pin: string): Promise<ApiResult<Record<string, unknown>>>; } //#endregion export { type ActivityComponent, type ActivityIntent, type AmbiHueState, type AmbilightApi, type AmbilightBrightnessChoices, type AmbilightCurrentConfiguration, type AmbilightFollowAudioMode, type AmbilightFollowColorAlgorithm, type AmbilightFollowVideoMode, type AmbilightLayer, type AmbilightLounge, type AmbilightMode, type AmbilightModePayload, type AmbilightModeResponse, type AmbilightPixelData, type AmbilightPower, type AmbilightSide, type AmbilightStyleName, type AmbilightSupportedStyle, type AmbilightSupportedStyles, type AmbilightTopology, type ApiVersion, type AppIntent, type Application, type ApplicationList, type AudioVolume, type AudioVolumeUpdate, type Channel, type ChannelList, type ChannelListSummary, type ChannelLists, type CurrentActivity, type CurrentChannel, type CurrentSource, type FlatNodeType, type GetFullAmbilightInformationResult, type GoogleAssistantPayload, type HSBColor, type InputApi, type InputKey, type InputKeyPayload, type JsonFeatures, type MenuApi, type MenuItemNode, type MenuItemsCurrentResponseNode, type MenuItemsSettingsRequest, type MenuItemsSettingsResponse, type MenuItemsSettingsUpdatePayload, type MenuItemsSettingsValue, type MenuSettingValue, type MenuSettingValueData, type MenuSettingValueInner, type PairingGrantPayload, type PairingGrantResponse, type PairingRequestPayload, type PairingRequestResponse, PhilTVApi, type PhilTVApiParams, PhilTVPairing, type PowerState, type PowerStatePayload, type PowerStateResponse, type RGBColor, type SetCurrentChannel, type Source, type SourceList, type SystemApi, type SystemFeatures, type SystemFeaturing, type SystemInfo, type SystemInfoEnriched };