UNPKG

@pmouli/isy-matter-server

Version:

Service to expose an ISY device as a Matter Border router

934 lines (904 loc) 35.3 kB
import { Category as BaseCat } from '../../Definitions/Global/Categories.js'; import { isFamily, NodeInfo, parseDeviceInfo } from '../../Model/NodeInfo.js'; import * as Insteon from './index.js'; import { DeviceMap } from './InsteonDeviceMap.js'; import { writeFileSync } from 'fs'; import type { Constructor } from 'type-fest'; import { factory } from 'typescript'; import { Family } from '../../Definitions/index.js'; import type { ISYDevice } from '../../ISYDevice.js'; import { ISYNode } from '../../ISYNode.js'; import { DeviceDef, type CategoryDef, type FamilyDef } from '../DeviceMap.js'; import { NodeFactory } from '../NodeFactory.js'; import { Num } from '../../Definitions/Insteon/index.js'; import type { Factory, ISY } from '../../ISY.js'; import type { ISYDeviceNode } from '../ISYDeviceNode.js'; let Category = BaseCat.Insteon; type InsteonDeviceMap = typeof DeviceMap; export class InsteonDeviceFactory { public static async create(isy: ISY, nodeInfo: NodeInfo<Family.Insteon>): Promise<ISYDevice<Family.Insteon, any, any, any>> { let d = parseDeviceInfo(nodeInfo); let dm = DeviceMap; //let deviceClass = dm.categories[Category[d.category]].devices[d.model].class; let device = null as ISYDevice<Family.Insteon, any, any, any>; let deviceInfo = dm.categories[BaseCat.Insteon[d.category] as keyof typeof BaseCat.Insteon].devices[d.model]; let deviceCls = deviceInfo?.class; if (deviceCls) { let c = Insteon[deviceCls as any].Class; device = new c(isy, nodeInfo) as ISYDevice<Family.Insteon, any, any, any>; } else { device = (await NodeFactory.create(nodeInfo, isy)) as ISYDeviceNode<Family.Insteon, any, any, any>; } if (device && deviceInfo) { device.modelNumber = deviceInfo.modelNumber; device.productName = deviceInfo.name; device.model = `(${device.modelNumber}) ${deviceInfo.name} v.${d.firmwareVersion}`; device.manufacturer = 'Insteon Technologies, Inc.'; device.version = d.firmwareVersion; if (deviceInfo.features) device.features |= deviceInfo.features; } return device; } // public static buildDeviceMap() { // var fams = new Map<Family, FamilyDef<Family>>(); // s.forEach((item) => { // var id = item.id as Family; // fams.set(id, { id: item.id, description: item.description, name: item.name, categories: new Map<string, CategoryDef<typeof id>>() }); // var famDef = fams[id] as FamilyDef<Family>; // item.categories.forEach((element) => { // var catDef = { id: element.id, name: element.name, devices: new Map<string, DeviceDef<Family>> }; // element.devices.forEach( // device => { // const r = this.getDeviceDetails({ // family: item.id, // type: `${element.id}.${device.id}.0.0`, // address: '0 0 0 1', // nodeDefId: '', // enabled: undefined, // pnode: undefined, // name: '', // startDelay: 0, // hint: '', // endDelay: 0, // wattage: 0, // dcPeriod: 0 // }); // if (!r.unsupported) { // device.name = r.name; // device.modelNumber = r.modelNumber; // device.class = r.class.name; // } // catDef.devices.set(`${device.id}`, { id: device.id, modelNumber: device.modelNumber, name: device.name, class: r.class }); // } // ); // famDef.categories.set(element.name, catDef); // element.devices = element.devices.sort((a, b) => a.id - b.id); // }); // } // ); // writeFileSync("DeviceMapClean.json", JSON.stringify(fams)); // } static getDeviceDetails(node: NodeInfo): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<Family.Insteon, any, any>> | Constructor<ISYDevice<Family.Insteon, any, any, any>>; unsupported?: true } { const family = Number(node.family ?? '1'); //let insteonFamilyDef = s[0] as FamilyDef<Family.Insteon>; if (isFamily(node, Family.Insteon)) { //insteonFamilyDef.categories.forEach(callbackfn)) let n = this.getInsteonDeviceDetails(node); if (n.class) { if ('Node' in n.class) { return { ...n, class: n.class.Node }; } if ('Device' in n.class) { return { ...n, class: n.class.Device }; } if (n.class instanceof Function) { return n as any; } } } return { name: 'Unsupported Device', class: Insteon.Base, unsupported: true }; } public static getInsteonDeviceDetails(node: NodeInfo<Family.Insteon>): { name: string; modelNumber?: string; version?: string; class: { Node: Constructor<ISYNode<Family.Insteon, any, any>> } | { Device: Constructor<ISYDevice<Family.Insteon, any, any, any>> } | Constructor<ISYNode<Family.Insteon, any, any>>; unsupported?: true } { const type = parseDeviceInfo(node); const subAddress = node.address.split(' ').pop(); // const typeArray = typeCode.split('.'); const category = type.category; const deviceCode = type.model; let deviceDetails = null; if (category === Category.Controller) { deviceDetails = InsteonDeviceFactory.getControllerInfo(deviceCode); } else if (category === 1) { deviceDetails = InsteonDeviceFactory.getDimLightInfo(deviceCode, subAddress, node); } else if (category === 2) { deviceDetails = InsteonDeviceFactory.getSwitchLightInfo(deviceCode, subAddress); } else if (category === 3) { deviceDetails = InsteonDeviceFactory.getNetworkBridgeInfo(deviceCode); } else if (category === 5) { deviceDetails = InsteonDeviceFactory.getClimateControlInfo(deviceCode); } else if (category === 4) { deviceDetails = InsteonDeviceFactory.getIrrigationControlInfo(deviceCode); } else if (category === 7) { deviceDetails = InsteonDeviceFactory.getIOControlInfo(deviceCode); } else if (category === 15) { deviceDetails = InsteonDeviceFactory.getAccessControlInfo(deviceCode); } else if (category === 16) { deviceDetails = InsteonDeviceFactory.getSHS(deviceCode, subAddress, node); } else if (category === 9) { deviceDetails = InsteonDeviceFactory.getEnergyManagement(deviceCode); } else if (category === 14) { deviceDetails = InsteonDeviceFactory.getWindowsCovering(deviceCode); } if (deviceDetails) { deviceDetails.version = type.firmwareVersion; if (deviceDetails.class === Insteon.OnOffOutlet && subAddress !== '1') { deviceDetails.class = Insteon.RelayLampSwitch.Node; } } if (!deviceDetails) { deviceDetails = { name: 'Unsupported Insteon Device', class: null, unsupported: true }; } if (!deviceDetails.class) { deviceDetails.class = Insteon.Base; deviceDetails.unsupported = true; } return deviceDetails; // deviceDetails = deviceDetails + version.toString(16); } public static getNetworkBridgeInfo(deviceCode: number): { name: string; modelNumber: string; version: string; class: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = null; switch (c) { case String.fromCharCode(1): retVal = { name: 'PowerLinc Serial', modelNumber: '2414S' }; break; case String.fromCharCode(2): retVal = { name: 'PowerLinc USB', modelNumber: '2414U' }; break; case String.fromCharCode(3): retVal = { name: 'Icon PowerLinc Serial', modelNumber: '2814S' }; break; case String.fromCharCode(4): retVal = { name: 'Icon PowerLinc USB', modelNumber: '2814U' }; break; case String.fromCharCode(5): retVal = { name: 'PowerLine Modem', modelNumber: '2412S' }; break; case String.fromCharCode(6): retVal = { name: 'IRLinc Receiver', modelNumber: '2411R' }; break; case String.fromCharCode(7): retVal = { name: 'IRLinc Transmitter', modelNumber: '2411T' }; break; case String.fromCharCode(11): retVal = { name: 'PowerLine Modem USB', modelNumber: '2412U' }; break; case '\r': retVal = { name: 'EZX10-RF' }; break; case String.fromCharCode(15): retVal = { name: 'EZX10-IR' }; break; case 'O': retVal = { name: 'PowerLine Modem', modelNumber: '12237DB' }; } return retVal; } public static getIrrigationControlInfo(deviceCode: number): { name: string; modelNumber?: string; version?: string; class?: typeof Insteon.Base } { const c = String.fromCharCode(deviceCode); return c === String.fromCharCode(0) ? { name: 'EZRain/EZFlora Irrigation Controller' } : null; } public static getSwitchLightInfo(deviceCode: number, subAddress: string): { name: string; modelNumber?: string; version?: string; class?: typeof Insteon.RelayLampSwitch.Node | typeof Insteon.KeypadRelay.Node | typeof Insteon.KeypadButton.Node | typeof Insteon.OnOffOutlet } { const c = String.fromCharCode(deviceCode); let retVal = { name: 'Generic Insteon Relay' } as { name: string; modelNumber?: string; version?: string; class?: typeof Insteon.RelayLampSwitch.Node | typeof Insteon.KeypadRelay.Node | typeof Insteon.KeypadButton.Node | typeof Insteon.OnOffOutlet }; switch (c) { case String.fromCharCode(6): retVal = { name: 'ApplianceLinc - Outdoor Plugin Module', modelNumber: '2456S3E' }; break; case String.fromCharCode(7): retVal = { name: 'TimerLinc', modelNumber: '2456S3T' }; break; case '\t': retVal = { name: 'ApplianceLinc', modelNumber: '2456S3' }; break; case '\n': retVal = { name: 'SwitchLinc Relay', modelNumber: '2476ST', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(11): retVal.class = Insteon.RelayLampSwitch.Node; retVal.name = 'Icon On/Off Switch'; retVal.modelNumber = '2876S'; break; case '\f': retVal = { name: 'Icon Appliance Adapter', modelNumber: '2856S3' }; break; case '\r': retVal = { name: 'ToggleLinc Relay', modelNumber: '2466S', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(26): retVal = { name: 'ToggleLinc Relay', modelNumber: '2466S', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(14): break; case ')': retVal = { name: 'SwitchLinc Relay Timer', modelNumber: '2476ST', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(17): retVal = { name: 'EZSwitch30', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(15): retVal = { name: 'KeypadLinc Relay', modelNumber: '2486S/WH6', class: Insteon.KeypadRelay.Node }; break; case String.fromCharCode(5): retVal = { name: 'KeypadLinc Relay (8 buttons)', modelNumber: '2486S/WH8', class: Insteon.KeypadRelay.Node }; break; case String.fromCharCode(16): retVal = { name: 'In-LineLinc Relay', modelNumber: '2475S' }; break; case String.fromCharCode(20): retVal = { name: 'In-LineLinc Relay W/ Sense', modelNumber: 'B2475S' }; break; case String.fromCharCode(19): retVal = { name: 'Icon SwitchLinc Relay for Bell Canada', modelNumber: 'B2475S' }; break; case '\b': retVal = { name: 'OutletLinc', modelNumber: '2473', class: Insteon.OnOffOutlet }; break; case String.fromCharCode(18): retVal = { name: 'Companion Switch', modelNumber: '2474S', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(21): retVal = { name: 'SwitchLinc Relay W/ Sense', modelNumber: '2476S', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(23): retVal = { name: 'Icon Relay 3-Pin', modelNumber: '2856S3B', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(22): retVal = { name: ' Icon Relay Switch', modelNumber: '2876SB', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(24): retVal = { name: 'SwitchLinc Relay 220 V.', modelNumber: '2494S220', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(25): retVal = { name: 'SwitchLinc Relay 220 V. w/Beeper', modelNumber: '2494S220', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(28): retVal = { name: 'SwitchLinc Relay - Remote Control On/Off Switch', modelNumber: '2476S', class: Insteon.RelayLampSwitch.Node }; break; case '%': retVal = { name: 'KeypadLinc Timer Relay (8 buttons)', modelNumber: '2484S/WH8', class: Insteon.KeypadRelay.Node }; break; case ' ': retVal = { name: 'KeypadLinc Relay', modelNumber: '2486S/WH6-SP', class: Insteon.KeypadRelay.Node }; break; case '!': retVal = { name: 'OutletLinc', modelNumber: '2473-SP', class: Insteon.OnOffOutlet }; break; case '#': retVal = { name: 'SwitchLinc Relay - Remote Control On/Off Switch', modelNumber: '2476S-SP', class: Insteon.RelayLampSwitch.Node }; case '"': retVal = { name: 'In-LineLinc Relay', modelNumber: '2475S-SP', class: Insteon.RelayLampSwitch.Node }; break; case String.fromCharCode(30): retVal = { name: 'KeypadLinc Relay', modelNumber: '2487S', class: Insteon.KeypadRelay.Node }; break; case ',': retVal = { name: 'Dual Band KeypadLinc Relay', modelNumber: '2487S', class: Insteon.KeypadRelay.Node }; break; case String.fromCharCode(31): retVal = { name: 'Dual Band InlineLinc On/Off Switch', modelNumber: '2475SDB', class: Insteon.RelayLampSwitch.Node }; break; case '*': retVal = { name: 'Dual Band SwitchLinc On/Off Switch', modelNumber: '2477S', class: Insteon.RelayLampSwitch.Node }; break; case '/': retVal = { name: 'Micro Module On/Off', modelNumber: '2443-222' }; break; case '1': retVal = { name: 'Micro Module On/Off', modelNumber: '2443-422' }; break; case '2': retVal = { name: 'Micro Module On/Off', modelNumber: '2443-422' }; break; case '<': retVal = { name: 'Micro Module On/Off', modelNumber: '2443-522' }; break; case '.': retVal = { name: 'Din Rail Relay', modelNumber: '2453-222', class: Insteon.RelayLampSwitch.Node }; break; case '3': retVal = { name: 'Din Rail Relay', modelNumber: '2453-422', class: Insteon.RelayLampSwitch.Node }; break; case '4': retVal = { name: 'Din Rail Relay', modelNumber: '2453-522', class: Insteon.RelayLampSwitch.Node }; break; case '=': retVal = { name: 'Din Rail Relay', modelNumber: '2453-522', class: Insteon.RelayLampSwitch.Node }; break; case '7': retVal = { name: 'On/Off Module', modelNumber: '2635-222' }; break; case '8': retVal = { name: 'On/Off Outdoor Module', modelNumber: '2634-222' }; break; case '9': retVal = { name: 'On/Off Outlet', modelNumber: '2663-222' }; break; case '-': retVal = { name: 'Plugin Relay', modelNumber: '2633-422' }; break; case '0': retVal = { name: 'Plugin Relay', modelNumber: '2633-432' }; break; case '5': retVal = { name: 'Plugin Relay', modelNumber: '2633-442' }; break; case '6': retVal = { name: 'Plugin Relay', modelNumber: '2633-522' }; } if (subAddress != '1' && retVal.class === Insteon.KeypadRelay.Node) { retVal.class = Insteon.KeypadButton.Node as any; } if (retVal.class === undefined) { retVal.class = Insteon.RelayLampSwitch.Node; } return retVal; } private static getDimLightInfo(deviceCode: number, subAddress: string, node: NodeInfo): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = { name: 'Generic Insteon Dimmer' } as { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<any, any, any, any>>; }; switch (c) { case String.fromCharCode(0): retVal = { name: 'LampLinc', modelNumber: '2456D3' }; break; case String.fromCharCode(1): retVal = { name: 'SwitchLinc Dimmer', modelNumber: '2476D', class: Insteon.DimmerLampSwitch.Node }; break; case String.fromCharCode(2): retVal = { name: 'In-LineLinc Dimmable', modelNumber: '2475D' }; break; case String.fromCharCode(3): retVal = { name: 'Icon Switch Dimmer', modelNumber: '2876D3' }; break; case String.fromCharCode(4): retVal = { name: 'SwitchLinc Dimmer', modelNumber: '2476DH', class: Insteon.DimmerLampSwitch.Node }; break; case String.fromCharCode(6): retVal = { name: 'LampLinc 2 Pin', modelNumber: '2456D2' }; break; case '\t': retVal = { name: 'KeypadLinc Dimmer', modelNumber: '2486D' }; break; case String.fromCharCode(7): retVal = { name: 'Icon LampLinc 2 Pin', modelNumber: '2856D2' }; break; case '\n': retVal = { name: 'Icon In-Wall Controller', modelNumber: '2886D' }; break; case '\r': retVal = { name: 'SocketLinc', modelNumber: '2454D' }; break; case '\f': retVal = { name: 'KeypadLinc Dimmer 8 Button', modelNumber: '2486DWH8', class: Insteon.KeypadDimmer.Node }; break; case String.fromCharCode(19): retVal = { name: 'Icon SwitchLinc Dimmer for Bell Canada' }; break; case String.fromCharCode(23): break; case String.fromCharCode(31): retVal = { name: 'ToggleLinc Dimmer', modelNumber: '2466D', class: Insteon.DimmerLampSwitch.Node }; break; case String.fromCharCode(24): retVal = { name: 'Companion Dimmer', modelNumber: '2474D' }; break; case String.fromCharCode(26): retVal = { name: 'InlineLinc Dimmer', modelNumber: '2475D', class: Insteon.DimmerLampSwitch.Node }; break; case String.fromCharCode(5): retVal = { name: 'KeypadLinc Countdown Timer', modelNumber: '2484DWH8' }; break; case String.fromCharCode(27): retVal = { name: 'KeypadLinc Dimmer 6 Buttons', modelNumber: '2486D', class: Insteon.KeypadDimmer.Node }; break; case String.fromCharCode(28): retVal = { name: 'KeypadLinc Dimmer 8 Buttons', modelNumber: '2486D', class: Insteon.KeypadDimmer.Node }; break; case String.fromCharCode(25): retVal = { name: 'SwitchLinc Dimmer W/Beeper', modelNumber: '2476D' }; break; case String.fromCharCode(14): retVal = { name: 'LampLinc BiPhy', modelNumber: 'B2457D2' }; break; case String.fromCharCode(30): retVal = { name: 'Icon Dimmer', modelNumber: '2876DB' }; break; case String.fromCharCode(29): retVal = { name: 'SwitchLinc Dimmer 1000W', modelNumber: '2476DH', class: Insteon.DimmerLampSwitch.Node }; break; case '"': retVal = { name: 'LampLinc 2-Pin Dimmer', modelNumber: '2457D2X' }; break; case 'U': retVal = { name: 'Dual Band Switchlinc Dimmer', modelNumber: '2432-622', class: Insteon.DimmerLampSwitch.Node }; break; case ' ': retVal = { name: 'Dual Band SwitchLinc Dimmer', modelNumber: '2477D', class: Insteon.DimmerLampSwitch.Node }; break; case '1': retVal = { name: 'Dual Band SwitchLinc Dimmer (240V)', modelNumber: '2478D', class: Insteon.DimmerLampSwitch.Node }; break; case '-': retVal = { name: 'Dual Band SwitchLinc Dimmer', modelNumber: '2477DH', class: Insteon.DimmerLampSwitch.Node }; break; case "'": retVal = { name: 'Dual Band SwitchLinc Dimmer', modelNumber: '2477D-SP', class: Insteon.DimmerLampSwitch.Node }; break; case '+': retVal = { name: 'Dual Band SwitchLinc Dimmer', modelNumber: '2477DH-SP', class: Insteon.DimmerLampSwitch.Node }; break; case ')': retVal = { name: 'KeypadLinc Dimmer 8 Buttons', modelNumber: '2486D-SP', class: Insteon.DimmerLampSwitch.Node }; break; case '*': retVal = { name: 'LampLinc 2-Pin Dimmer', modelNumber: '2457D2X-SP' }; break; case ',': retVal = { name: 'InlineLinc Dimmer', modelNumber: '2475D-SP' }; break; case '%': retVal = { name: 'Ballast Dimmer', modelNumber: '2475DA2' }; break; case '=': retVal = { name: 'Ballast Dimmer', modelNumber: '2446-422' }; break; case '>': retVal = { name: 'Ballast Dimmer', modelNumber: '2446-522' }; break; case '.': retVal = { name: 'FanLinc', modelNumber: '2475F', class: Insteon.Fan as any }; break; case '!': retVal = { name: 'Dual Band OutletLinc Dimmer', modelNumber: '2472D', class: Insteon.DimmerOutlet }; break; case '0': retVal = { name: 'SwitchLinc Dimmer', modelNumber: '2476D', class: Insteon.DimmerLampSwitch.Node }; break; case '$': retVal = { name: 'SwitchLinc Dimmer 2-Wire', modelNumber: '2474DWH', class: Insteon.DimmerLampSwitch.Node }; break; case '2': retVal = { name: 'InLineLinc Dimmer', modelNumber: '2475DA1' }; break; case ':': retVal = { name: 'Insteon LED Bulb 8 Watt (60W)', modelNumber: '2672-222' }; break; case 'I': retVal = { name: 'Insteon LED Bulb PAR38 12 Watt', modelNumber: '2674-222' }; break; case '5': retVal = { name: 'Micro Module Dimmer', modelNumber: '2442-222' }; break; case '8': retVal = { name: 'Micro Module Dimmer', modelNumber: '2442-422' }; break; case '9': retVal = { name: 'Micro Module Dimmer', modelNumber: '2442-522' }; break; case 'S': retVal = { name: 'Micro Module Dimmer', modelNumber: '2442-522' }; break; case '4': retVal = { name: 'Din Rail Dimmer', modelNumber: '2452-222' }; break; case '6': retVal = { name: 'Din Rail Dimmer', modelNumber: '2452-422' }; break; case '7': retVal = { name: 'Din Rail Dimmer', modelNumber: '2452-522' }; break; case 'T': retVal = { name: 'Din Rail Dimmer', modelNumber: '2452-522' }; break; case 'B': retVal = { name: 'KeypadLinc Dimmer 5 Buttons', modelNumber: '2334-2', class: Insteon.KeypadDimmer.Node }; break; case 'A': retVal = { name: 'KeypadLinc Dimmer 8 Buttons', modelNumber: '2334-2', class: Insteon.KeypadDimmer.Node }; break; case 'V': retVal = { name: 'KeypadLinc Dimmer 6 Buttons', modelNumber: '2334-632', class: Insteon.KeypadDimmer.Node }; break; case String.fromCharCode(11): retVal = { name: 'Plugin Dimmer', modelNumber: '2632-422' }; break; case String.fromCharCode(15): retVal = { name: 'Plugin Dimmer', modelNumber: '2632-432' }; break; case String.fromCharCode(17): retVal = { name: 'Plugin Dimmer', modelNumber: '2632-442' }; break; case 'P': retVal = { name: 'Plugin Dimmer', modelNumber: '2632-452' }; break; case String.fromCharCode(18): retVal = { name: 'Plugin Dimmer', modelNumber: '2632-522' }; } if (subAddress !== '1' && retVal.class === Insteon.KeypadDimmer.Node) { retVal.class = Insteon.KeypadButton.Node; } if (node.nodeDefId === 'FanLincMotor') { retVal.class = Insteon.FanLincMotor.Node; } if (retVal?.class === undefined) { retVal.class = Insteon.DimmerLamp.Node; } return retVal; } private static getControllerInfo(deviceCode: number): { name: string; modelNumber?: string; version?: string; class: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = null; switch (c) { case String.fromCharCode(0): retVal = { name: 'ControLinc', modelNumber: '2430' }; break; case String.fromCharCode(5): retVal = { name: 'RemoteLinc', modelNumber: '2440' }; break; case String.fromCharCode(14): retVal = { name: 'RemoteLinc EZ', modelNumber: '2440EZ' }; break; case String.fromCharCode(6): retVal = { name: 'Icon Tabletop', modelNumber: '2830' }; break; case '\t': retVal = { name: 'SignaLinc', modelNumber: '2442' }; break; case String.fromCharCode(17): retVal = { name: 'RemoteLinc 2 Switch', modelNumber: '2342-242' }; break; case String.fromCharCode(16): retVal = { name: 'RemoteLinc 2 Keypad, 4 Scene', modelNumber: '2342-232' }; break; case String.fromCharCode(18): retVal = { name: 'RemoteLinc 2 Keypad, 8 Scene', modelNumber: '2342-222' }; break; case String.fromCharCode(20): retVal = { name: 'Mini Remote Keypad, 4 Scene', modelNumber: '2342-432' }; break; case String.fromCharCode(21): retVal = { name: 'Mini Remote Switch', modelNumber: '2342-442' }; break; case String.fromCharCode(22): retVal = { name: 'Mini Remote Keypad, 8 Scene', modelNumber: '2342-422' }; break; case String.fromCharCode(23): retVal = { name: 'Mini Remote Keypad, 4 Scene', modelNumber: '2342-532' }; break; case String.fromCharCode(24): retVal = { name: 'Mini Remote Keypad, 8 Scene', modelNumber: '2342-522' }; break; case String.fromCharCode(25): retVal = { name: 'Mini Remote Switch', modelNumber: '2342-542' }; break; case String.fromCharCode(26): retVal = { name: 'Mini Remote Keypad, 8 Scene', modelNumber: '2342-222' }; break; case String.fromCharCode(27): retVal = { name: 'Mini Remote Keypad, 4 Scene', modelNumber: '2342-232' }; break; case String.fromCharCode(28): retVal = { name: 'Mini Remote Switch', modelNumber: '2342-242' }; } return retVal; } private static getIOControlInfo(deviceCode: number): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = null; switch (c) { case String.fromCharCode(0): retVal = { name: 'IOLinc', modelNumber: '2450' }; break; case String.fromCharCode(3): retVal = { name: 'Compacta EZIO 2x4: INSTEON I/O Controller' }; break; case String.fromCharCode(4): retVal = { name: 'Compacta EZIO8SA: INSTEON I/O Controller' }; break; case String.fromCharCode(2): retVal = { name: 'Compacta EZIO8T: INSTEON I/O Controller' }; break; case String.fromCharCode(5): retVal = { name: 'Compacta EZSnSRF' }; break; case String.fromCharCode(6): retVal = { name: 'Compacta EZSnSRF Interface' }; break; case String.fromCharCode(7): retVal = { name: 'Compacta EZIO6I' }; break; case '\b': retVal = { name: 'Compacta EZIO4O' }; break; case '\t': retVal = { name: 'SynchroLinc', modelNumber: '2423A5' }; break; case '\r': retVal = { name: 'IOLinc (Refurbished)', modelNumber: '2450' }; break; case String.fromCharCode(14): retVal = { name: 'I/O Module', modelNumber: '2248-222' }; break; case String.fromCharCode(15): retVal = { name: 'I/O Module', modelNumber: '2248-422' }; break; case String.fromCharCode(16): retVal = { name: 'I/O Module', modelNumber: '2248-442' }; break; case String.fromCharCode(17): retVal = { name: 'I/O Module', modelNumber: '2248-522' }; break; case String.fromCharCode(18): retVal = { name: 'IOLinc', modelNumber: '2822-222' }; break; case String.fromCharCode(19): retVal = { name: 'IOLinc', modelNumber: '2822-422' }; break; case String.fromCharCode(20): retVal = { name: 'IOLinc', modelNumber: '2822-442' }; break; case String.fromCharCode(21): retVal = { name: 'IOLinc', modelNumber: '2822-522' }; break; case String.fromCharCode(22): retVal = { name: 'Contact Closure', modelNumber: '2822-222' }; break; case String.fromCharCode(23): retVal = { name: 'Contact Closure', modelNumber: '2822-422' }; break; case String.fromCharCode(24): retVal = { name: 'Contact Closure', modelNumber: '2822-442' }; break; case String.fromCharCode(25): retVal = { name: 'Contact Closure', modelNumber: '2822-522' }; break; case String.fromCharCode(26): retVal = { name: 'Alert Module', modelNumber: '2867-222' }; break; case String.fromCharCode(30): retVal = { name: 'Siren', modelNumber: '2868-222' }; break; case ' ': retVal = { name: 'Siren', modelNumber: '2868-622' }; } return retVal; } private static getSHS(deviceCode: number, subAddress: string, node): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = null; switch (c) { case String.fromCharCode(1): retVal = { name: 'INSTEON Motion Sensor', modelNumber: '2842-222', class: Insteon.MotionSensor }; break; case String.fromCharCode(4): retVal = { name: 'INSTEON Motion Sensor', modelNumber: '2842-422', class: Insteon.MotionSensor }; break; case String.fromCharCode(5): retVal = { name: 'INSTEON Motion Sensor', modelNumber: '2842-522', class: Insteon.MotionSensor }; break; case String.fromCharCode(3): retVal = { name: 'INSTEON Motion Sensor', modelNumber: '2420M-SP', class: Insteon.MotionSensor }; break; case String.fromCharCode(2): retVal = { name: 'TriggerLinc', modelNumber: '2421', class: Insteon.MotionSensor }; break; case '\t': retVal = { name: 'Open/Close Sensor', modelNumber: '2843-222', class: Insteon.DoorWindowSensor }; break; case String.fromCharCode(6): retVal = { name: 'Open/Close Sensor', modelNumber: '2843-422', class: Insteon.DoorWindowSensor }; break; case String.fromCharCode(7): break; case String.fromCharCode(25): retVal = { name: 'Open/Close Sensor', modelNumber: '2843-522', class: Insteon.DoorWindowSensor }; break; case '\b': retVal = { name: 'Leak Sensor', modelNumber: '2852-222', class: Insteon.LeakSensor }; break; case '\r': retVal = { name: 'Leak Sensor', modelNumber: '2852-422', class: Insteon.LeakSensor }; break; case String.fromCharCode(14): retVal = { name: 'Leak Sensor', modelNumber: '2852-522', class: Insteon.LeakSensor }; break; case String.fromCharCode(26): retVal = { name: 'Leak Sensor', modelNumber: '2852-522', class: Insteon.LeakSensor }; break; case '\n': retVal = { name: 'INSTEON Smoke Sensor', modelNumber: '', class: Insteon.SmokeSensor }; break; case String.fromCharCode(17): retVal = { name: 'INSTEON Hidden Door Sensor', modelNumber: '2845-222', class: Insteon.DoorWindowSensor }; break; case String.fromCharCode(20): retVal = { name: 'INSTEON Hidden Door Sensor', modelNumber: '2845-422', class: Insteon.DoorWindowSensor }; break; case String.fromCharCode(21): break; case String.fromCharCode(27): retVal = { name: 'INSTEON Hidden Door Sensor', modelNumber: '2845-522', class: Insteon.DoorWindowSensor }; break; case String.fromCharCode(22): retVal = { name: 'Insteon Motion Sensor II', modelNumber: '2844-222', class: Insteon.MotionSensor }; break; case String.fromCharCode(24): retVal = { name: 'Insteon Motion Sensor II', modelNumber: '2844-522', class: Insteon.MotionSensor }; } if ((node.nodeDefId === 'BinaryAlarm' || node.nodeDefId === 'BinaryAlarm_ADV') && subAddress !== '1') { if (retVal) { retVal.class = Insteon.Base; } } return retVal; } private static getClimateControlInfo(deviceCode: number): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = null; switch (c) { case String.fromCharCode(0): retVal = { name: 'BROAN SMSC080 Exhaust Fan' }; break; case String.fromCharCode(2): retVal = { name: 'BROAN SMSC110 Exhaust Fan' }; break; case String.fromCharCode(5): retVal = { name: 'BROAN, Venmar, Best Rangehoods' }; break; case String.fromCharCode(1): retVal = { name: 'Compacta EZTherm' }; break; case String.fromCharCode(4): retVal = { name: 'Compacta EZTherm' }; break; case String.fromCharCode(3): retVal = { name: 'INSTEON Thermostat Adapter', modelNumber: '2441V' }; break; case '\t': retVal = { name: 'INSTEON Thermostat Adapter', modelNumber: '2441V-SP' }; break; case String.fromCharCode(11): retVal = { name: 'INSTEON Thermostat', modelNumber: '2441TH' }; break; case String.fromCharCode(15): retVal = { name: 'INSTEON Thermostat', modelNumber: '2732-422' }; break; case String.fromCharCode(16): retVal = { name: 'INSTEON Thermostat', modelNumber: '2732-522' }; break; case String.fromCharCode(17): retVal = { name: 'INSTEON Thermostat', modelNumber: '2732-432' }; break; case String.fromCharCode(18): retVal = { name: 'INSTEON Thermostat', modelNumber: '2732-532' }; break; case String.fromCharCode(19): retVal = { name: 'INSTEON Thermostat Heat Pump', modelNumber: '2732-242' }; break; case String.fromCharCode(20): retVal = { name: 'INSTEON Thermostat Heat Pump for Europe', modelNumber: '2732-442' }; break; case String.fromCharCode(21): retVal = { name: 'INSTEON Thermostat Heat Pump for Aus/NZ', modelNumber: '2732-542' }; break; case String.fromCharCode(22): retVal = { name: 'INSTEON Thermostat 2.0 (HVAC/HP)', modelNumber: '2732-222' }; break; case String.fromCharCode(23): retVal = { name: 'INSTEON Thermostat 2.0 (HVAC/HP) for Europe', modelNumber: '2732-422' }; break; case String.fromCharCode(24): retVal = { name: 'INSTEON Thermostat 2.0 (HVAC/HP) for Aus/NZ', modelNumber: '(2732-522)' }; break; case '\n': retVal = { name: 'INSTEON Wireless Thermostat', modelNumber: '2441ZTH' }; break; case String.fromCharCode(14): retVal = { name: 'All-In-One INSTEON Thermostat Adapter', modelNumber: '2491T' }; } if (retVal?.class === undefined) { retVal.class = Insteon.Thermostat.Node; } return retVal; } private static getAccessControlInfo(deviceCode: number): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<any, any, any, any>> } { const c = String.fromCharCode(deviceCode); const retVal = { name: '', modelNumber: '', class: Insteon.DoorLock.Node }; switch (c) { case String.fromCharCode(6): retVal.name = 'MorningLinc'; break; case '\n': retVal.name = 'Lock Controller'; } return retVal; } private static getEnergyManagement(deviceCode: number): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = null; switch (c) { case String.fromCharCode(0): retVal = { name: 'ZBPCM (iMeter Solo compat.)' }; break; case String.fromCharCode(7): retVal = { name: 'iMeter Solo', modelNumber: '2423A1' }; break; case String.fromCharCode(11): retVal = { name: 'Dual Band Normally Closed 240V Load Controller', modelNumber: '2477SA2' }; break; case '\n': retVal = { name: 'Dual Band Normally Open 240V Load Controller', modelNumber: '2477SA1' }; break; case '\r': retVal = { name: 'Energy Display', modelNumber: '(2448A2)' }; } return retVal; } private static getWindowsCovering(deviceCode: number): { name: string; modelNumber?: string; version?: string; class?: Constructor<ISYNode<Family.Insteon, any, any>> } { const c = String.fromCharCode(deviceCode); let retVal = null; switch (c) { case String.fromCharCode(1): retVal = { name: 'Micro Module Open/Close', modelNumber: '2444-222' }; break; case String.fromCharCode(2): retVal = { name: 'Micro Module Open/Close', modelNumber: '2444-422' }; break; case String.fromCharCode(3): retVal = { name: 'Micro Module Open/Close', modelNumber: '2444-522' }; break; case String.fromCharCode(7): retVal = { name: 'Micro Module Open/Close', modelNumber: '2444-522' }; } return retVal; } }