UNPKG

@pmouli/isy-matter-server

Version:

Service to expose an ISY device as a Matter Border router

245 lines 12.9 kB
import { Converter } from 'isy-nodejs/ISY'; import { ISYDevice } from 'isy-nodejs/ISYDevice'; import { hasPath } from '../Mappings/MappingRegistry.js'; import { ISYBridgedDeviceBehavior } from './ISYBridgedDeviceBehavior.js'; // #endregion Type aliases (6) // #region Functions (1) function clusterBehaviorForNode(base, p) { //@ts-ignore let s = class ISYClusterBehavior extends base { _device; static factory = p; handlers = {}; _bridgedDeviceBehavior; get bridgedDeviceBehavior() { return this._bridgedDeviceBehavior ?? this.agent.get((ISYBridgedDeviceBehavior)); } ///public map: ClusterMapping<ToClusterTypeByName<ClusterForBehavior<ConstructedType<typeof base>>["name"]>,ISYDeviceNode<any, any, any>>; map; setStateSafe(key, value) { if (this.state[key] != value) { try { this.state[key] = value; } catch (e) { this.logger.error(`Error setting state ${key} to ${value}: ${e}`); } } } async initialize(_options) { await super.initialize(_options); var behavior = (await this.agent.load((ISYBridgedDeviceBehavior))); this._bridgedDeviceBehavior = behavior; //var behavior = this.agent.get(ISYBridgedDeviceBehavior); this._device = behavior.device; this.logger.debug(`Initializing cluster behavior: ${this.constructor.name}`); //@ts-ignore this.map = behavior.mapForBehavior(this); for (const key2 in this.map?.attributes) { let val = this.map.attributes[key2]; let that = this; let driverObj = null; if (typeof val === 'string' || typeof val === 'number') { driverObj = this._device.drivers[val]; if (driverObj) { let evt = `${driverObj.name}Changed`; //this.state[key2 as string] = driverObj.value; //this.state[key2 as string] = driverObj.value; this.setStateSafe(key2, driverObj.value); this[`handle_${evt}`] = function ({ driver, newValue, oldValue, formattedValue }) { this.logger.debug(`${that.constructor.name}: handling property change for ${String(driver)} from ${oldValue} to ${newValue}`); this.setStateSafe(key2, newValue); }; this.reactTo(behavior.events[evt], this[`handle_${evt}`]); } } else if (hasPath(val)) { driverObj = this._device.drivers[val.driver]; if (driverObj) { let evt = `${driverObj.name}Changed`; let { driver, converter } = val; const convFunc = typeof val.converter === 'function' ? val.converter : Converter.get(val.converter)?.to; if (!convFunc) throw new Error(`Converter ${converter} not found`); /*this.state[key2 as string] = convFunc(this._device.drivers[driver as string].value);*/ this.setStateSafe(key2, convFunc(this._device.drivers[driver].value)); this[`handle_${evt}`] = function ({ driver, newValue, oldValue, formattedValue }) { let v = convFunc(newValue); let oldV = this.state[key2]; this.logger.debug(`${that.constructor.name}: handling property change for ${String(driver)} from ${oldValue} (${oldV}) to ${newValue} (${v})`); this.setStateSafe(key2, v); }; this.reactTo(behavior.events[evt], this[`handle_${evt}`]); } } /*this.handlers[driverObj.id] = function (parent = that, newValue, oldValue, formattedValue) { //this.device.logger(`Handling property change for ${driver} (${key2}) with value ${newValue}`); //if (convFunc) this.state[key2 as string] = convFunc(newValue); parent.state[key2 as string] = convFunc(newValue); };*/ //(this as any).evt = this.handlers[driverObj.name]; } this.logger.debug(`Cluster behavior initialized: ${this.constructor.name}`); //this.reactTo(behavior.events.propertyChanged, this.handlePropertyChange, { lock: false }); //this._device.on("PropertyChanged", this.handlePropertyChange.bind(this)); } get device() { return (this._device = this._device ?? this.agent.get((ISYBridgedDeviceBehavior)).device); } get logger() { return this.bridgedDeviceBehavior.logger; } async handlePropertyChange({ driver, newValue, oldValue, formattedValue }) { // for (const key2 in this.map.attributes) { //await this.initialize(); this.device.logger(`${this.constructor.name}: handling property change for ${String(driver)} with value ${newValue}`); if (this.handlers[driver]) { this.handlers[driver](newValue, oldValue, formattedValue); } // if (typeof this.map.attributes[key2] === "string") { // if(this.map.attributes[key2] == driver) // { // this.state[key2 as string] = newValue; // return; // } }else if (this.map.attributes[key2].driver == driver) { // if (this.map.attributes[key2]?.driver == driver) { // this.state[key2 as string] = this.map.attributes[key2].converter(newValue); // } // } // } } }; s.factory = p; return s; } function clusterBehaviorForComposite(base, p) { let s = class ISYClusterBehavior extends base { _device; static factory = p; handlers = {}; setStateSafe(key, value) { if (this.state[key] != value) { try { this.state[key] = value; } catch (e) { this.logger.error(`Error setting state ${key} to ${value}: ${e}`); } } } _bridgedDeviceBehavior; get bridgedDeviceBehavior() { return this._bridgedDeviceBehavior ?? this.agent.get((ISYBridgedDeviceBehavior)); } ///public map: ClusterMapping<ToClusterTypeByName<ClusterForBehavior<ConstructedType<typeof base>>["name"]>,ISYDeviceNode<any, any, any>>; map; async initialize(_options) { await super.initialize(_options); var behavior = (await this.agent.load((ISYBridgedDeviceBehavior))); this._bridgedDeviceBehavior = behavior; //var behavior = this.agent.get(ISYBridgedDeviceBehavior); this._device = behavior.device; this.logger.debug(`Initializing cluster behavior: ${this.constructor.name}`); //@ts-ignore this.map = behavior.mapForBehavior(this); for (const key in this.map?.attributes) { let val = this.map.attributes[key]; let driverObj = null; let nodeObj = null; if (typeof val === 'string') { let [node, id] = val.split('.'); nodeObj = this._device.nodes[node]; driverObj = nodeObj.drivers[id]; this.setStateSafe(key, nodeObj.drivers[id].value); //this.state[key as string] = nodeObj.drivers[id].value; let evt = `${node}.${driverObj.name}Changed`; this[`handle_${evt}`] = function ({ node, driver, newValue, oldValue, formattedValue }) { this.logger.debug(`${this.constructor.name}: handling property change for ${node}.${driver} (${key}) with value ${newValue}`); this.setStateSafe(key, newValue); }; this.reactTo(behavior.events[evt], this[`handle_${evt}`]); } else if (hasPath(val)) { let driverObj = this._device?.nodes[val.node]?.drivers[val.driver]; if (driverObj) { let evt = `${val.node}.${driverObj.name}Changed`; if (val.converter) { const convFunc = typeof val.converter === 'function' ? val.converter : Converter.get(val.converter)?.to; if (!convFunc) throw new Error(`Converter ${val.converter} not found`); this.setStateSafe(key, convFunc(driverObj.value)); //this.state[key as string] = convFunc(driverObj.value); this[`handle_${evt}`] = function ({ node, driver, newValue, oldValue, formattedValue }) { let v = convFunc(newValue); let oldV = this.state[key]; this.logger.debug(`${this.constructor.name}: handling property change for ${node}.${String(driver)} from ${oldValue} (${oldV}) to ${newValue} (${v})`); this.setStateSafe(key, v); }; } else { this.setStateSafe(key, driverObj.value); //this.state[key as string] = driverObj.value; this[`handle_${evt}`] = function ({ node, driver, newValue, oldValue, formattedValue }) { this.logger.debug(`${this.constructor.name}: handling property change for ${node}.${driver} (${key}) from ${oldValue} to ${newValue}`); this.setStateSafe(key, newValue); }; } this.reactTo(behavior.events[evt], this[`handle_${evt}`]); } } /*if (driverObj && nodeObj) { let evt = `${nodeObj}.${driverObj.name}Changed`; (this as any).evt = this.handlers[driverObj.name]; //this.reactTo(behavior.events[evt], this.handlePropertyChange, { lock: false }); }*/ this.logger.debug(`Cluster behavior initialized: ${this.constructor.name}`); } //this.reactTo(behavior.events.propertyChanged, this.handlePropertyChange, { lock: false }); //this._device.on("PropertyChanged", this.handlePropertyChange.bind(this)); } get device() { return (this._device = this._device ?? this.agent.get((ISYBridgedDeviceBehavior)).device); } get logger() { return this.bridgedDeviceBehavior.logger; } async handlePropertyChange({ node, driver, newValue, oldValue, formattedValue }) { // for (const key2 in this.map.attributes) { //await this.initialize(); this.logger.debug(`${this.constructor.name}: handling property change for ${node}.${String(driver)} with value ${newValue}`); if (this.handlers[node][driver]) { this.handlers[node][driver](newValue, oldValue, formattedValue); } // if (typeof this.map.attributes[key2] === "string") { // if(this.map.attributes[key2] == driver) // { // this.state[key2 as string] = newValue; // return; // } }else if (this.map.attributes[key2].driver == driver) { // if (this.map.attributes[key2]?.driver == driver) { // this.state[key2 as string] = this.map.attributes[key2].converter(newValue); // } // } // } } }; s.factory = p; return s; } export function ISYClusterBehavior(base, p) { let alterations = { attributes: {} }; for (const l in base.cluster.attributes) { alterations.attributes[l] = { persistent: false }; } base = base.alter(alterations); if (ISYDevice.isNode(p)) { //@ts-ignore return clusterBehaviorForNode(base, p); } else if (ISYDevice.isComposite(p)) { //@ts-ignore return clusterBehaviorForComposite(base, p); } } // #endregion Functions (1) //# sourceMappingURL=ISYClusterBehavior.js.map