UNPKG

@pmouli/isy-matter-server

Version:

Service to expose an ISY device as a Matter Border router

202 lines (194 loc) 8.67 kB
import { BridgedDeviceBasicInformationBehavior, DescriptorServer, FixedLabelServer, UserLabelServer } from '@matter/node/behaviors'; //import type { FanFanDevice } from 'isy-nodejs/Devices/Insteon/InsteonFanDevice'; import { Descriptor } from '@matter/main/clusters'; import { Devices as DevicesNS, Family } from 'isy-nodejs/ISY'; import { ISYDevice } from 'isy-nodejs/ISYDevice'; import { ISYNode } from 'isy-nodejs/ISYNode'; import { ISYBridgedDeviceBehavior } from '../Behaviors/ISYBridgedDeviceBehavior.js'; export function add(This, mapping) { let m = { ...This, ...mapping }; //@ts-ignore let s = { ...m, add(mapping2) { return add(m, mapping2); } }; return s; } export function hasPath(mapping) { if (typeof mapping == 'object' && 'driver' in mapping) { const driver = mapping.driver; if (typeof driver === 'string') { return true; } } return false; } // #endregion Type aliases (16) // #region Classes (1) //@ts-ignore const BaseDescriptorServer = DescriptorServer.withFeatures(Descriptor.Feature.TagList); export class MappingRegistry { // #region Properties (1) static map = new Map(); static cache = {}; // #endregion Properties (1) // #region Public Static Methods (3) static getMapping(device) { let m = this.cache[device.address]; if (!m) { if (device) { if (MappingRegistry.map.has(Family[device.family])) { let g = MappingRegistry.map.get(Family[device.family]); //let m: DeviceToClusterMap<T,MutableEndpoint>; if (g.has(device.constructor.name)) { m = g.get(device.constructor.name); } else if (g.has(device.type)) { m = g.get(device.type); } else if (ISYDevice.isNode(device)) { if (g.has(device.nodeDefId)) { m = g.get(device.nodeDefId); } if (!m) { for (var nodeDefId of ISYNode.getImplements(device)) { if (g.has(nodeDefId)) { device.logger(`Mapping found to ${Family[device.family]}.${nodeDefId}`, 'info'); m = g.get(nodeDefId); g.set(device.nodeDefId, m); break; } } } } if (m !== null) this.cache[device.address] = m; } } } return m; } static getMappingForBehavior(device, behavior) { //var m = MappingRegistry.getMapping(device); //return m[behavior.cluster.name]; for (var m in MappingRegistry.getMapping(device).mapping) { if (behavior.cluster.name === m) return MappingRegistry.getMapping(device).mapping[m]; } } static add(mapping) { MappingRegistry.register(mapping); return MappingRegistry; } //@ts-ignore static register(map, family) { if ('Family' in map) { let regMap; let Devices = DevicesNS[map.Family]; if (!MappingRegistry.map.has(map.Family)) { MappingRegistry.map.set(map.Family, new Map()); } regMap = MappingRegistry.map.get(map.Family); for (var key in map) { if (key !== 'Family' && key !== 'add') { let m = map[key]; m = { deviceType: m.deviceType.with(BridgedDeviceBasicInformationBehavior, ISYBridgedDeviceBehavior, UserLabelServer, FixedLabelServer), mapping: m.mapping, toJSON() { return { deviceType: this.deviceType.name, mapping: this.mapping }; } }; if (m.mapping != undefined) { for (var key1 in m.mapping) { for (var key2 in m.mapping[key1].attributes) { let attribute = m.mapping[key1].attributes[key2]; { let d = attribute; try { if (typeof d === 'string') { let [d1, d2] = d.split('.'); if (d2) { m.mapping[key1].attributes[key2] = { driver: `${Devices[key]?.Nodes[d1].Drivers[d2]}`, node: d1 }; } else { m.mapping[key1].attributes[key2] = { driver: Devices[key]?.Drivers[d1] }; } } else if (hasPath(d)) { let [d1, d2] = d.driver.split('.'); if (d2) { //@ts-ignore m.mapping[key1].attributes[key2].driver = `${Devices[key]?.Nodes[d1].Drivers[d2]}`; //@ts-ignore m.mapping[key1].attributes[key2].node = d1; } else { //@ts-ignore m.mapping[key1].attributes[key2].driver = Devices[key]?.Drivers[d1]; } } } catch { console.log('Error', key, key1, key2, d); } } } } } console.log('Registering', JSON.stringify({ keys: [key, Devices[key]?.Class?.name, Devices[key]?.Class?.nodeDefId], mapping: m }, null, 2)); regMap.set(key, m); regMap.set(Devices[key]?.Class?.name, m); if (ISYDevice.isNode(Devices[key])) { regMap.set(Devices[key]?.Class?.nodeDefId, m); } } } } /*else { let regMap: Map<string, DeviceToClusterMap<any, any>>; for (var key in map) { const keys = key.split('.'); let x = DevicesNS[keys[0]][keys[1]] as typeof ISYNode<any, any, any, any>; if (!MappingRegistry.map.has(Family[x.family] as keyof typeof Family)) { MappingRegistry.map.set(Family[x.family] as keyof typeof Family, new Map()); } //{family, key} = key.split(".")[0] regMap = MappingRegistry.map.get(Family[x.family] as keyof typeof Family); let m = map[key] as DeviceToClusterMap<ISYDevice.Any, MutableEndpoint>; let deviceType = m.deviceType; deviceType = deviceType.with(BridgedDeviceBasicInformationBehavior, ISYBridgedDeviceBehavior); m = { deviceType: deviceType, mapping: m.mapping }; regMap.set(keys[1], m); regMap.set(x.name, m); } } }*/ // #endregion Public Static Methods (3) } } // #endregion Classes (1) // #region Variables (3) /*interface SimplyEndpointMapping<T extends ISYNode<Family, any, any, any>, K extends MutableEndpoint> extends SimplifyDeep<ISYtoMatterMapping<T, K>> {}*/ /* const map = { deviceType: DimmableLightDevice, mapping: { onOff: { attributes: { onOff: { driver: 'ST', converter: 'Percent.Boolean' }, }, commands: { onWithTimedOff: { command: 'DON' }, } }, levelControl: { attributes: { } } } } as Mapping<Insteon.RelayLampNode, DimmableLightDevice>; */ // #endregion Variables (3) //# sourceMappingURL=MappingRegistry.js.map