UNPKG

matterbridge

Version:
462 lines • 32 kB
/** * This file contains the behavior classes of Matterbridge. * * @file matterbridgeBehaviors.ts * @author Luca Liguori * @date 2024-11-07 * @version 1.3.0 * * Copyright 2024, 2025, 2026 Luca Liguori. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable @typescript-eslint/no-unused-vars */ // @matter import { Behavior } from '@matter/main'; // @matter clusters import { BooleanStateConfiguration } from '@matter/main/clusters/boolean-state-configuration'; import { ColorControl } from '@matter/main/clusters/color-control'; import { FanControl } from '@matter/main/clusters/fan-control'; import { WindowCovering } from '@matter/main/clusters/window-covering'; import { Thermostat } from '@matter/main/clusters/thermostat'; import { ValveConfigurationAndControl } from '@matter/main/clusters/valve-configuration-and-control'; import { SmokeCoAlarm } from '@matter/main/clusters/smoke-co-alarm'; import { BooleanStateConfigurationServer } from '@matter/main/behaviors/boolean-state-configuration'; import { OperationalState } from '@matter/main/clusters/operational-state'; import { ModeBase } from '@matter/main/clusters/mode-base'; import { ServiceArea } from '@matter/main/clusters/service-area'; // @matter behaviors import { IdentifyServer } from '@matter/main/behaviors/identify'; import { OnOffServer } from '@matter/main/behaviors/on-off'; import { LevelControlServer } from '@matter/main/behaviors/level-control'; import { ColorControlServer } from '@matter/main/behaviors/color-control'; import { WindowCoveringServer } from '@matter/main/behaviors/window-covering'; import { DoorLockServer } from '@matter/main/behaviors/door-lock'; import { FanControlServer } from '@matter/main/behaviors/fan-control'; import { ThermostatServer } from '@matter/main/behaviors/thermostat'; import { ValveConfigurationAndControlServer } from '@matter/main/behaviors/valve-configuration-and-control'; import { ModeSelectServer } from '@matter/main/behaviors/mode-select'; import { SmokeCoAlarmServer } from '@matter/main/behaviors/smoke-co-alarm'; import { SwitchServer } from '@matter/main/behaviors/switch'; import { OperationalStateServer } from '@matter/main/behaviors/operational-state'; import { ServiceAreaServer } from '@matter/main/behaviors/service-area'; import { DeviceEnergyManagementModeServer } from '@matter/main/behaviors/device-energy-management-mode'; export class MatterbridgeServer extends Behavior { static id = 'matterbridge'; initialize() { this.state.log.debug(`MatterbridgeServer initialized (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); super.initialize(); } } (function (MatterbridgeServer) { class State { log; commandHandler; } MatterbridgeServer.State = State; })(MatterbridgeServer || (MatterbridgeServer = {})); export class MatterbridgeIdentifyServer extends IdentifyServer { identify(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Identifying device for ${request.identifyTime} seconds (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('identify', { request, cluster: IdentifyServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeIdentifyServer: identify called`); super.identify(request); } triggerEffect(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Triggering effect ${request.effectIdentifier} variant ${request.effectVariant} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('triggerEffect', { request, cluster: IdentifyServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeIdentifyServer: triggerEffect called`); super.triggerEffect(request); } } export class MatterbridgeOnOffServer extends OnOffServer { on() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Switching device on (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('on', { request: {}, cluster: OnOffServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeOnOffServer: on called`); super.on(); } off() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Switching device off (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('off', { request: {}, cluster: OnOffServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeOnOffServer: off called`); super.off(); } toggle() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Toggle device on/off (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('toggle', { request: {}, cluster: OnOffServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeOnOffServer: toggle called`); super.toggle(); } } export class MatterbridgeLevelControlServer extends LevelControlServer { moveToLevel(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting level to ${request.level} with transitionTime ${request.transitionTime} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('moveToLevel', { request, cluster: LevelControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeLevelControlServer: moveToLevel called`); super.moveToLevel(request); } moveToLevelWithOnOff(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting level to ${request.level} with transitionTime ${request.transitionTime} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('moveToLevelWithOnOff', { request, cluster: LevelControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeLevelControlServer: moveToLevelWithOnOff called`); super.moveToLevelWithOnOff(request); } } export class MatterbridgeColorControlServer extends ColorControlServer.with(ColorControl.Feature.HueSaturation, ColorControl.Feature.Xy, ColorControl.Feature.ColorTemperature) { moveToHue(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting hue to ${request.hue} with transitionTime ${request.transitionTime} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('moveToHue', { request, cluster: ColorControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeColorControlServer: moveToHue called`); super.moveToHue(request); } moveToSaturation(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting saturation to ${request.saturation} with transitionTime ${request.transitionTime} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('moveToSaturation', { request, cluster: ColorControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeColorControlServer: moveToSaturation called`); super.moveToSaturation(request); } moveToHueAndSaturation(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting hue to ${request.hue} and saturation to ${request.saturation} with transitionTime ${request.transitionTime} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('moveToHueAndSaturation', { request, cluster: ColorControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeColorControlServer: moveToHueAndSaturation called`); super.moveToHueAndSaturation(request); } moveToColor(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting color to ${request.colorX}, ${request.colorY} with transitionTime ${request.transitionTime} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('moveToColor', { request, cluster: ColorControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeColorControlServer: moveToColor called`); super.moveToColor(request); } moveToColorTemperature(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting color temperature to ${request.colorTemperatureMireds} with transitionTime ${request.transitionTime} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('moveToColorTemperature', { request, cluster: ColorControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeColorControlServer: moveToColorTemperature called`); super.moveToColorTemperature(request); } } export class MatterbridgeLiftWindowCoveringServer extends WindowCoveringServer.with(WindowCovering.Feature.Lift, WindowCovering.Feature.PositionAwareLift) { upOrOpen() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Opening cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler(`upOrOpen`, { request: {}, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeWindowCoveringServer: upOrOpen called`); super.upOrOpen(); } downOrClose() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Closing cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler(`downOrClose`, { request: {}, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeWindowCoveringServer: downOrClose called`); super.downOrClose(); } stopMotion() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Stopping cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('stopMotion', { request: {}, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeWindowCoveringServer: stopMotion called`); super.stopMotion(); } goToLiftPercentage(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting cover lift percentage to ${request.liftPercent100thsValue} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('goToLiftPercentage', { request, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeWindowCoveringServer: goToLiftPercentage with ${request.liftPercent100thsValue}`); super.goToLiftPercentage(request); } async handleMovement(type, reversed, direction, targetPercent100ths) { // Do nothing here, as the device will handle the movement } } export class MatterbridgeLiftTiltWindowCoveringServer extends WindowCoveringServer.with(WindowCovering.Feature.Lift, WindowCovering.Feature.PositionAwareLift, WindowCovering.Feature.Tilt, WindowCovering.Feature.PositionAwareTilt) { upOrOpen() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Opening cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler(`upOrOpen`, { request: {}, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeLiftTiltWindowCoveringServer: upOrOpen called`); super.upOrOpen(); } downOrClose() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Closing cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler(`downOrClose`, { request: {}, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeLiftTiltWindowCoveringServer: downOrClose called`); super.downOrClose(); } stopMotion() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Stopping cover (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('stopMotion', { request: {}, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeLiftTiltWindowCoveringServer: stopMotion called`); super.stopMotion(); } goToLiftPercentage(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting cover lift percentage to ${request.liftPercent100thsValue} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('goToLiftPercentage', { request, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeLiftTiltWindowCoveringServer: goToLiftPercentage with ${request.liftPercent100thsValue}`); super.goToLiftPercentage(request); } goToTiltPercentage(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting cover tilt percentage to ${request.tiltPercent100thsValue} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('goToTiltPercentage', { request, cluster: WindowCoveringServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeLiftTiltWindowCoveringServer: goToTiltPercentage with ${request.tiltPercent100thsValue}`); super.goToTiltPercentage(request); } async handleMovement(type, reversed, direction, targetPercent100ths) { // Do nothing here, as the device will handle the movement } } export class MatterbridgeDoorLockServer extends DoorLockServer { lockDoor() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Locking door (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('lockDoor', { request: {}, cluster: DoorLockServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeDoorLockServer: lockDoor called`); super.lockDoor(); } unlockDoor() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Unlocking door (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('unlockDoor', { request: {}, cluster: DoorLockServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeDoorLockServer: unlockDoor called`); super.unlockDoor(); } } export class MatterbridgeFanControlServer extends FanControlServer.with(FanControl.Feature.Auto, FanControl.Feature.Step) { step(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Stepping fan with direction ${request.direction} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('step', { request, cluster: FanControlServer.id, attributes: this.state, endpoint: this.endpoint }); const lookupStepDirection = ['Increase', 'Decrease']; device.log.debug(`MatterbridgeFanControlServer: step called with direction: ${lookupStepDirection[request.direction]} wrap: ${request.wrap} lowestOff: ${request.lowestOff}`); device.log.debug(`- current percentCurrent: ${this.state.percentCurrent}`); if (request.direction === FanControl.StepDirection.Increase) { if (request.wrap && this.state.percentCurrent === 100) { this.state.percentCurrent = request.lowestOff ? 0 : 10; } else this.state.percentCurrent = Math.min(this.state.percentCurrent + 10, 100); } else if (request.direction === FanControl.StepDirection.Decrease) { if (request.wrap && this.state.percentCurrent === (request.lowestOff ? 0 : 10)) { this.state.percentCurrent = 100; } else this.state.percentCurrent = Math.max(this.state.percentCurrent - 10, request.lowestOff ? 0 : 10); } device.log.debug('Set percentCurrent to:', this.state.percentCurrent); // step is not implemented in matter.js // super.step(request); } } export class MatterbridgeThermostatServer extends ThermostatServer.with(Thermostat.Feature.Cooling, Thermostat.Feature.Heating, Thermostat.Feature.AutoMode) { setpointRaiseLower(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Setting setpoint by ${request.amount} in mode ${request.mode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('setpointRaiseLower', { request, cluster: ThermostatServer.id, attributes: this.state, endpoint: this.endpoint }); const lookupSetpointAdjustMode = ['Heat', 'Cool', 'Both']; device.log.debug(`MatterbridgeThermostatServer: setpointRaiseLower called with mode: ${lookupSetpointAdjustMode[request.mode]} amount: ${request.amount / 10}`); if (this.state.occupiedHeatingSetpoint !== undefined) device.log.debug(`- current occupiedHeatingSetpoint: ${this.state.occupiedHeatingSetpoint / 100}`); if (this.state.occupiedCoolingSetpoint !== undefined) device.log.debug(`- current occupiedCoolingSetpoint: ${this.state.occupiedCoolingSetpoint / 100}`); if ((request.mode === Thermostat.SetpointRaiseLowerMode.Heat || request.mode === Thermostat.SetpointRaiseLowerMode.Both) && this.state.occupiedHeatingSetpoint !== undefined) { const setpoint = this.state.occupiedHeatingSetpoint / 100 + request.amount / 10; this.state.occupiedHeatingSetpoint = setpoint * 100; device.log.debug(`Set occupiedHeatingSetpoint to ${setpoint}`); } if ((request.mode === Thermostat.SetpointRaiseLowerMode.Cool || request.mode === Thermostat.SetpointRaiseLowerMode.Both) && this.state.occupiedCoolingSetpoint !== undefined) { const setpoint = this.state.occupiedCoolingSetpoint / 100 + request.amount / 10; this.state.occupiedCoolingSetpoint = setpoint * 100; device.log.debug(`Set occupiedCoolingSetpoint to ${setpoint}`); } // setpointRaiseLower is not implemented in matter.js // super.setpointRaiseLower(request); } } export class MatterbridgeValveConfigurationAndControlServer extends ValveConfigurationAndControlServer.with(ValveConfigurationAndControl.Feature.Level) { open(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Opening valve to ${request.targetLevel ? request.targetLevel + '%' : 'fully opened'} ${request.openDuration ? 'for ' + request.openDuration + 's' : 'until closed'} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('open', { request, cluster: ValveConfigurationAndControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeValveConfigurationAndControlServer: open called with openDuration: ${request.openDuration} targetLevel: ${request.targetLevel}`); this.state.targetState = ValveConfigurationAndControl.ValveState.Open; this.state.currentState = ValveConfigurationAndControl.ValveState.Open; this.state.targetLevel = request.targetLevel ?? 100; this.state.currentLevel = request.targetLevel ?? 100; this.state.openDuration = request.openDuration ?? this.state.defaultOpenDuration; if (this.state.openDuration === null) this.state.remainingDuration = null; // open is not implemented in matter.js // super.open(request); } close() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Closing valve (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('close', { request: {}, cluster: ValveConfigurationAndControlServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeValveConfigurationAndControlServer: close called`); this.state.targetState = ValveConfigurationAndControl.ValveState.Closed; this.state.currentState = ValveConfigurationAndControl.ValveState.Closed; this.state.targetLevel = 0; this.state.currentLevel = 0; this.state.openDuration = null; this.state.remainingDuration = null; // close is not implemented in matter.js // super.close(); } } export class MatterbridgeSmokeCoAlarmServer extends SmokeCoAlarmServer.with(SmokeCoAlarm.Feature.SmokeAlarm, SmokeCoAlarm.Feature.CoAlarm) { selfTestRequest() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Testing SmokeCOAlarm (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('selfTestRequest', { request: {}, cluster: SmokeCoAlarmServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeSmokeCoAlarmServer: selfTestRequest called`); // selfTestRequest is not implemented in matter.js // super.selfTestRequest(); } } export class MatterbridgeBooleanStateConfigurationServer extends BooleanStateConfigurationServer.with(BooleanStateConfiguration.Feature.Visual, BooleanStateConfiguration.Feature.Audible, BooleanStateConfiguration.Feature.SensitivityLevel) { enableDisableAlarm(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Enabling/disabling alarm ${request.alarmsToEnableDisable} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('enableDisableAlarm', { request, cluster: BooleanStateConfigurationServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeBooleanStateConfigurationServer: enableDisableAlarm called`); // enableDisableAlarm is not implemented in matter.js // super.enableDisableAlarm(request); } } export class MatterbridgeSwitchServer extends SwitchServer { initialize() { // Do nothing here, as the device will handle the switch logic: we need to convert something like "single" into the appropriate sequence of state changes and events } } export class MatterbridgeOperationalStateServer extends OperationalStateServer { initialize() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.debug('MatterbridgeOperationalStateServer initialized: setting operational state to Stopped'); this.state.operationalState = OperationalState.OperationalStateEnum.Stopped; this.state.operationalError = { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }; super.initialize(); // Error handling logic is handled in matter.js } pause() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Pause (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('pause', { request: {}, cluster: OperationalStateServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug('MatterbridgeOperationalStateServer: pause called setting operational state to Paused'); this.state.operationalState = OperationalState.OperationalStateEnum.Paused; this.state.operationalError = { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }; // pause is not implemented in matter.js // return super.pause(); return { commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }, }; } stop() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Stop (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('stop', { request: {}, cluster: OperationalStateServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug('MatterbridgeOperationalStateServer: stop called setting operational state to Stopped'); this.state.operationalState = OperationalState.OperationalStateEnum.Stopped; this.state.operationalError = { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }; // stop is not implemented in matter.js // return super.stop(); return { commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }, }; } start() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Start (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('start', { request: {}, cluster: OperationalStateServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug('MatterbridgeOperationalStateServer: start called setting operational state to Running'); this.state.operationalState = OperationalState.OperationalStateEnum.Running; this.state.operationalError = { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }; // start is not implemented in matter.js // return super.start(); return { commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }, }; } resume() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Resume (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('resume', { request: {}, cluster: OperationalStateServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug('MatterbridgeOperationalStateServer: resume called setting operational state to Running'); this.state.operationalState = OperationalState.OperationalStateEnum.Running; this.state.operationalError = { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }; // resume is not implemented in matter.js // return super.resume(); return { commandResponseState: { errorStateId: OperationalState.ErrorState.NoError, errorStateLabel: 'No error', errorStateDetails: 'Fully operational' }, }; } } export class MatterbridgeServiceAreaServer extends ServiceAreaServer { selectAreas(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Selecting areas ${request.newAreas} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('selectAreas', { request, cluster: ServiceAreaServer.id, attributes: this.state, endpoint: this.endpoint }); for (const area of request.newAreas) { const supportedArea = this.state.supportedAreas.find((supportedArea) => supportedArea.areaId === area); if (!supportedArea) { device.log.error(`MatterbridgeServiceAreaServer selectAreas called with unsupported area: ${area}`); return { status: ServiceArea.SelectAreasStatus.UnsupportedArea, statusText: 'Unsupported areas' }; } } this.state.selectedAreas = request.newAreas; device.log.debug(`MatterbridgeServiceAreaServer selectAreas called with: ${request.newAreas.map((area) => area.toString()).join(', ')}`); return super.selectAreas(request); // return { status: ServiceArea.SelectAreasStatus.Success, statusText: 'Succesfully selected new areas' }; } } export class MatterbridgeModeSelectServer extends ModeSelectServer { changeToMode(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Changing mode to ${request.newMode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('changeToMode', { request, cluster: ModeSelectServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeModeSelectServer: changeToMode called with mode: ${request.newMode}`); super.changeToMode(request); } } export class MatterbridgeDeviceEnergyManagementModeServer extends DeviceEnergyManagementModeServer { changeToMode(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Changing mode to ${request.newMode} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('changeToMode', { request, cluster: DeviceEnergyManagementModeServer.id, attributes: this.state, endpoint: this.endpoint }); const supported = this.state.supportedModes.find((mode) => mode.mode === request.newMode); if (!supported) { device.log.error(`MatterbridgeDeviceEnergyManagementModeServer changeToMode called with unsupported newMode: ${request.newMode}`); return { status: ModeBase.ModeChangeStatus.UnsupportedMode, statusText: 'Unsupported mode' }; } this.state.currentMode = request.newMode; device.log.debug(`MatterbridgeDeviceEnergyManagementModeServer changeToMode called with newMode ${request.newMode} => ${supported.label}`); return super.changeToMode(request); // return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Success' }; } } //# sourceMappingURL=matterbridgeBehaviors.js.map