UNPKG

@pmouli/isy-matter-server

Version:

Service to expose an ISY device as a Matter Border router

131 lines (110 loc) 4.08 kB
import { Family } from './Definitions/index.js'; import { NodeFactory } from './Devices/NodeFactory.js'; import type { CompositeDevice } from './ISY.js'; import { ISYDevice, ISYDeviceInfo } from './ISYDevice.js'; import { ISYNode } from './ISYNode.js'; import type { Factory, StringKeys } from './Utils.js'; export class Registry<K extends keyof any, T> { Global: { [x in K]?: T } = {}; FamilyLevel: { [x in StringKeys<typeof Family>]?: { [y in K]?: T } } = {}; DeviceLevel: { [x: string]: { [y in K]?: T } } = {}; NodeDefLevel: { [x: string]: { [y in K]?: T } } = {}; ClassLevel: {[x: string]: { [y in K]?: T } } = {}; registerGlobal(key: K, value: T): void { this.Global[key] = value; } registerFamilyLevel<F extends Family>(family: F & number, key: K, value: T): void { this.FamilyLevel[Family[family] as string] = this.FamilyLevel[Family[family] as string] ?? {}; this.FamilyLevel[Family[family] as string]![key] = value; } registerDeviceLevel(device: string, key: K, value: T): void { this.DeviceLevel[device] = this.DeviceLevel[device] ?? {}; this.DeviceLevel[device]![key] = value; } registerNodeDefLevel(nodeDefId: string, key: K, value: T): void { this.NodeDefLevel[nodeDefId] = this.NodeDefLevel[nodeDefId] ?? {}; this.NodeDefLevel[nodeDefId]![key] = value; } registerClassLevel(className: string, key: K, value: T): void { this.ClassLevel[className] = this.ClassLevel[className] ?? {}; this.ClassLevel[className]![key] = value; } register(key: K, value: T): void; register(key: K, value: T, deviceType: string): void; register(key: K, value: T, factory: ISYDevice.Factory<any, any, any, any,any>): void; register(key: K, value: T, discriminant?: string | Family | ISYDevice.Factory<any,any, any,any,any>): void { if (discriminant === undefined) { this.registerGlobal(key, value); return; } else if (typeof discriminant === 'string') { this.registerDeviceLevel(discriminant, key, value); return; } else if (typeof discriminant === 'number') { if (discriminant in Family) { this.registerFamilyLevel(discriminant as Family, key, value); return; } } else if (ISYDevice.isNode(discriminant)) { this.registerNodeDefLevel(discriminant.Class.prototype.nodeDefId, key, value); for (const nodeDefId in NodeFactory.getImplements(discriminant)) { this.registerNodeDefLevel(nodeDefId, key, value); } this.registerClassLevel(discriminant.Class.name, key, value) this.registerFamilyLevel((discriminant.Class as unknown as typeof ISYNode).family, key, value); return; } else if(ISYDevice.isComposite(discriminant)) { this.registerClassLevel(discriminant.Class.name, key, value); return; } /*else if(ISYDevice.isComposite(discriminant)) { this.registerFamilyLevel(discriminant.types, key, value); return; }*/ //TODO: Implement Composite Device } getGlobal(key: K): T | undefined { return this.Global[key]; } getFamilyLevel<F extends Family>(family: F & number, key: K): T | undefined { return this.FamilyLevel[Family[family] as string]?.[key]; } getDeviceLevel(device: string, key: K): T | undefined { return this.DeviceLevel[device]?.[key]; } getNodeLevel(nodeDefId: string, key: K): T | undefined { return this.NodeDefLevel[nodeDefId]?.[key]; } getClassLevel(className: string, key: K): T | undefined { return this.ClassLevel[className]?.[key]; } get(device: ISYDevice.Any, key: K): T | undefined { if (device.type) { let d = this.getDeviceLevel(device.type, key); if (d) return d; } if (ISYDevice.isNode(device)) { let d = this.getNodeLevel(device.nodeDefId, key); if (d) { return d; } else { for (const nodeDefId in NodeFactory.getImplements(device)) { let d = this.getNodeLevel(nodeDefId, key); if (d) return d; } } } if(ISYDevice.isComposite(device)) { let d = this.getClassLevel(device.constructor.name, key); if(d) return d; } let f = this.getFamilyLevel(device.family, key); if (f) return f; return this.getGlobal(key); } }