import type { Constructor } from 'type-fest'; import type { Command } from './Definitions/Global/Commands.js'; import type { Driver } from './Definitions/Global/Drivers.js'; import type { Event } from './Definitions/Global/Events.js'; import type { Feature } from './Definitions/Global/Features.js'; import type { Category, Family } from './Definitions/index.js'; import type { CompositeDevice } from './Devices/CompositeDevice.js'; import type { DynamicNode } from './Devices/DynamicNode.js'; import { ISYDeviceNode } from './Devices/ISYDeviceNode.js'; import type { ISYNode } from './ISYNode.js'; import type { ISYScene } from './Scenes/ISYScene.js'; import type { Factory as BaseFactory } from './Utils.js'; export interface Queryable { query(): Promise; } /** * Represents an ISY device with specific properties and methods. * * @template T - The family type of the device. * @template D - The type of the drivers associated with the device. * @template C - The type of the commands associated with the device. * @template E - The type of the events associated with the device. * * @extends ISYDeviceInfo * * @property {string} address - The address of the device. * @property {T extends Family.Insteon ? Category.Insteon : Category.Home.Category} category - The category of the device based on its family. * @property {C} commands - The commands associated with the device. * @property {any} deviceClass - The class of the device. * @property {D} drivers - The drivers associated with the device. * @property {E} events - The events associated with the device. * @property {boolean} enabled - Indicates whether the device is enabled. * @property {T} family - The family of the device. * @property {boolean} hidden - Indicates whether the device is hidden. * @property {boolean} isDimmable - Indicates whether the device is dimmable. * @property {string} label - The label of the device. * @property {string} model - The model of the device. * @property {string} modelNumber - The model number of the device. * @property {any} name - The name of the device. * @property {any} parentAddress - The parent address of the device. * @property {ISYScene[]} scenes - The scenes associated with the device. * @property {number} subCategory - The sub-category of the device. * @property {any} type - The type of the device. * @property {string} typeCode - The type code of the device. * @property {string} version - The version of the device. * @property {string} location - The location of the device. * @property {string} folder - The folder to which the device belongs. */ export interface ISYDevice extends ISYDeviceInfo { // #region Properties (22) address: string; category: T extends Family.Insteon ? Category.Insteon : Category.Home.Category; commands: C; deviceClass: any; drivers: D; events: E; enabled: boolean; family: T; hidden: boolean; label: string; model: string; modelNumber: string; name: any; parentAddress: any; scenes: ISYScene[]; subCategory: number; type: any; typeCode: string; version: string; features: Feature; location: string; folder?: string; // Optional folder property to group devices initialized: boolean; refreshState(): Promise; // #endregion Properties (22) // #region Public Methods (18) // #endregion Public Methods (18) } export namespace ISYDevice { export function isDevice< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, >( device: ISYNode ): device is ISYDevice, Command.ForAll, Event.ForAll> & ISYNode { return device instanceof ISYDeviceNode; } export type Factory> = T extends ISYNode ? ISYNode.Factory : T extends CompositeDevice ? CompositeDevice.Factory : never; type Node< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, > = ISYNode & ISYDevice, Command.ForAll, Event.ForAll>; export function isNode< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, >( factory: BaseFactory, Command.ForAll, any>> ): factory is ISYNode.Factory>; export function isNode< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, >(device: ISYDevice, Command.ForAll, any>): device is Node; export function isNode< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, >( factoryOrDevice: | ISYDevice, Command.ForAll, any> | BaseFactory, Command.ForAll, any>> ): factoryOrDevice is Node | ISYNode.Factory> { if ('Class' in factoryOrDevice) { return 'Drivers' in factoryOrDevice; } return factoryOrDevice instanceof ISYDeviceNode; } export function isDynamic(node: ISYDevice.Any): node is DynamicNode { return 'nodeTypeId' in node; } export function isNodeFactory< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, >( factory: BaseFactory, Command.ForAll, any>> ): factory is ISYNode.Factory> { return 'Drivers' in factory; } export function isComposite< T extends Family, D extends Record, C extends Record, E extends Record, >( factory: BaseFactory> ): factory is CompositeDevice.Factory }, any>; export function isComposite< T extends Family, D extends Record, C extends Record, E extends Record, >( device: ISYDevice ): device is ISYDevice & CompositeDevice }>; export function isComposite< T extends Family = Family, D extends Record = {}, C extends Record = {}, E extends Record = {}, >( deviceOrFactory: ISYDevice | BaseFactory> ): deviceOrFactory is | (ISYDevice & CompositeDevice }>) | CompositeDevice.Factory }, any> { if ('Class' in deviceOrFactory) return 'Nodes' in deviceOrFactory; return 'root' in deviceOrFactory; } export type DriverNamesOf = T extends { Class: Constructor> } ? CompositeDevice.DriverNamesOf> : ISYNode.DriverNamesOf; export type ChildrenOf = T extends CompositeDevice.Factory ? N : never; export type CommandNamesOf = T extends BaseFactory> | CompositeDevice ? CompositeDevice.CommandNamesOf : ISYNode.CommandNamesOf; export type Any = ISYDevice; export type EventNamesOf> = InstanceTypeOf extends CompositeDevice ? CompositeDevice.EventNamesOf> : T extends ISYNode ? ISYNode.EventNamesOf : never; export function isQueryable(device: ISYDevice.Any): device is Queryable & ISYDevice.Any { if (device?.commands && typeof device.commands == 'object') return 'QUERY' in device.commands; return false; } export type InstanceTypeOf = T extends ISYDevice.Any ? T : T extends BaseFactory & { Node: Constructor } ? InstanceType : T extends { Device: Constructor } ? InstanceType : never; } export function isDevice< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, >(device: ISYNode): device is ISYDevice & ISYNode { return device instanceof ISYDeviceNode; } export function isDeviceClass< T extends Family, D extends ISYNode.DriverSignatures, C extends ISYNode.CommandSignatures, E extends ISYNode.EventSignatures, >(device: typeof ISYNode): device is (new (...args) => ISYDevice) & typeof ISYNode { return device.prototype instanceof ISYDeviceNode; } export interface ISYDeviceInfo { type: string; deviceClass: any; productName: string; productId: string | number; model: string; modelName: string; modelNumber: string; version: string; category: Category.Insteon | Category.Home.Category; subCategory: number; manufacturer: string; }