@pmouli/isy-matter-server
Version:
Service to expose an ISY device as a Matter Border router
82 lines • 3.4 kB
JavaScript
import { ColorControl } from '@matter/main/clusters';
import { ClusterId } from '@matter/types';
import { writeDebugFile } from '../../ISY.js';
import { ColorTemperatureLight, DimmableLight, ExtendedColorLight } from './index.js';
import { OnOffLight } from './OnOffLight.js';
import { hasBitFlag } from './ZigbeeClusterData.js';
export function parseZigbeeClusterData(input) {
const clusters = {};
const clusterRegex = /Cluster (\d+) 0x([0-9A-Fa-f]+) ([\w_]+)/g;
const dataRegex = /(\w+)\s+DATA\s+devices\.\d+\.endpoints\.(\d+)\.clusters\.\d+\.data\.?([\w\.]*)\s*=\s*(.+)/gm;
let currentCluster = null;
input?.split('\n').forEach((line) => {
clusterRegex.lastIndex = 0; // Reset lastIndex for clusterRegex
const clusterMatch = clusterRegex.exec(line);
if (clusterMatch) {
if (currentCluster)
clusters[currentCluster.clusterName] = currentCluster;
currentCluster = {
clusterId: ClusterId(parseInt(clusterMatch[1], 10)),
clusterName: clusterMatch[3],
endpoint: 0, // Placeholder, will be updated later
data: {}
};
return;
}
dataRegex.lastIndex = 0; // Reset lastIndex for dataRegex
const dataMatch = dataRegex.exec(line);
if (dataMatch && currentCluster) {
const [, type, endpoint, key, value] = dataMatch;
currentCluster.endpoint = parseInt(endpoint, 10);
currentCluster.data[key] = parseValue(type, value);
}
});
if (currentCluster) {
clusters[currentCluster?.clusterName] = currentCluster;
}
return clusters;
}
function parseValue(type, value) {
switch (type) {
case 'Boolean':
return value.trim() === 'True';
case 'Integer':
return parseInt(value, 10);
case 'Binary':
return value.match(/\[([0-9A-Fa-f]+)\]/)?.[1] || value;
case 'Empty':
return null;
default:
return value.trim();
}
}
export class ZigBeeDeviceFactory {
static async create(isy, nodeInfo) {
let clusterInfo = await isy.sendRequest(`zmatter/zigbee/dh/node/${nodeInfo.address}/cluster/0`, { trailingSlash: false });
if (clusterInfo) {
if (isy.isDebugEnabled) {
await writeDebugFile(clusterInfo, `${nodeInfo.address}_ClusterData.txt`, isy.logger, isy.storagePath);
}
let cd = parseZigbeeClusterData(clusterInfo);
//@ts-expect-error
let cc = cd['COLOR_CONTROL'];
//@ts-expect-error
let lc = cd['LEVEL_CONTROL'];
//@ts-expect-error
let os = cd['ON_OFF_SWITCH'];
if (cc) {
if (hasBitFlag(cc.data.colorCapabilities, ColorControl.ColorCapabilities.xy)) {
return new ExtendedColorLight(isy, nodeInfo, cd);
}
else if (hasBitFlag(cc.data.colorCapabilities, ColorControl.ColorCapabilities.colorTemperature)) {
return new ColorTemperatureLight(isy, nodeInfo);
}
}
else if (lc && os)
return new DimmableLight(isy, nodeInfo);
else if (os)
return new OnOffLight(isy, nodeInfo);
}
}
}
//# sourceMappingURL=ZigBeeDeviceFactory.js.map