@pmouli/isy-matter-server
Version:
Service to expose an ISY device as a Matter Border router
202 lines (194 loc) • 8.67 kB
JavaScript
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