@pmouli/isy-matter-server
Version:
Service to expose an ISY device as a Matter Border router
99 lines (87 loc) • 2.98 kB
text/typescript
import type { Constructor } from 'type-fest';
import { Family } from '../Definitions/Global/Families.js';
import type { ISY } from '../ISY.js';
import { ISYDevice } from '../ISYDevice.js';
//@ts-ignore
import { ISYDeviceNode } from '../ISYDeviceNode.js';
import { ISYNode } from '../ISYNode.js';
import { NodeInfo, cleanNodeInfo } from '../Model/NodeInfo.js';
import type { Factory, StringKeys } from '../Utils.js';
import { GenericNode } from './GenericNode.js';
import { InsteonDeviceFactory } from './Insteon/InsteonDeviceFactory.js';
import { NodeFactory } from './NodeFactory.js';
import { ZigBeeDeviceFactory } from './ZigBee/ZigBeeDeviceFactory.js';
export class DeviceFactory {
static async createAll(isy: ISY, ...nodeInfos: NodeInfo[]) {
const devices = await Promise.all(
nodeInfos.map(async (node) => {
return await this.create(isy, node);
})
);
for (const device of devices) {
if (ISYDevice.isComposite(device)) {
for (const child of this.nodeMap.get(device.node.address) ?? []) {
device.addNode(child, isy);
}
}
}
return devices;
}
static nodeMap = new Map<string, NodeInfo<Family>[]>();
static async addChildNodes(isy: ISY) {
isy.logger.debug('Adding child nodes. Composite Device Count: ' + DeviceFactory.nodeMap.size);
for (const [address, nodeInfos] of DeviceFactory.nodeMap) {
isy.logger.debug('Adding child nodes for: ' + address + '. Child Count: ' + nodeInfos.length);
const parent = isy.getDevice(address);
if (parent && ISYDevice.isComposite(parent)) {
for (const nodeInfo of nodeInfos) {
await parent.addNode(nodeInfo, isy);
}
await parent.applyNodeDefs();
} else {
isy.logger.debug('Parent not found for: ' + address);
for (const nodeInfo of nodeInfos) {
try {
await NodeFactory.create(nodeInfo, isy);
} catch {}
}
}
}
}
static async create<T extends Family>(isy: ISY, nodeInfo: NodeInfo<T>): Promise<ISYDevice<T, any, any, any>> {
const cinfo = cleanNodeInfo(nodeInfo);
if (cinfo.pnode != cinfo.address) {
let nodeInfos = DeviceFactory.nodeMap.get(cinfo.pnode) ?? [];
nodeInfos.push(cinfo);
DeviceFactory.nodeMap.set(nodeInfo.pnode, nodeInfos);
return null;
}
let device = null as ISYDevice<T, any, any, any>;
switch (cinfo.family) {
case Family.Insteon:
//@ts-ignore
device = await InsteonDeviceFactory.create(isy, cinfo);
break;
case Family.ZigBee:
device = (await ZigBeeDeviceFactory.create(isy, cinfo)) as any;
break;
default:
device = null;
break;
}
if (!device) {
device = (await NodeFactory.create(cinfo, isy)) as any;
}
/*if (!device) {
return new GenericNode(isy, nodeInfo) as any;
}*/
return device;
}
}
export namespace DeviceFactory {
export const Insteon = InsteonDeviceFactory;
export type ZWave = {};
export type ZigBee = ZigBeeDeviceFactory;
export const ZigBee = ZigBeeDeviceFactory;
export type Insteon = typeof InsteonDeviceFactory;
}