UNPKG

matterbridge

Version:
146 lines 9.01 kB
/** * This file contains the Evse class. * * @file energy-evse.ts * @author Luca Liguori * @contributor Ludovic BOUÉ * @date 2025-05-27 * @version 1.1.0 * * Copyright 2025, 2026, 2027 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. * */ import { EnergyEvseServer } from '@matter/main/behaviors/energy-evse'; import { EnergyEvseModeServer } from '@matter/main/behaviors/energy-evse-mode'; import { EnergyEvse, EnergyEvseMode } from '@matter/main/clusters'; import { DeviceEnergyManagement } from '@matter/main/clusters/device-energy-management'; import { ModeBase } from '@matter/main/clusters/mode-base'; // Matterbridge import { MatterbridgeEndpoint } from './matterbridgeEndpoint.js'; import { MatterbridgeServer } from './matterbridgeBehaviors.js'; import { deviceEnergyManagement, electricalSensor, evse, powerSource } from './matterbridgeDeviceTypes.js'; export class Evse extends MatterbridgeEndpoint { /** * Creates an instance of the EVSE class. * * @param {string} name - The name of the EVSE. * @param {string} serial - The serial number of the EVSE. * @param {number} [currentMode] - The current mode of the EnergyEvseMode cluster. Defaults to mode 1 (EnergyEvseMode.ModeTag.Manual). * @param {EnergyEvseMode.ModeOption[]} [supportedModes] - The supported modes for the EnergyEvseMode cluster. This is a fixed attribute that defaults to a predefined set of EnergyEvseMode cluster modes. * @param {EnergyEvse.State} [state] - The current state of the EVSE. Defaults to NotPluggedIn. * @param {EnergyEvse.SupplyState} [supplyState] - The supply state of the EVSE. Defaults to Disabled. * @param {EnergyEvse.FaultState} [faultState] - The fault state of the EVSE. Defaults to NoError. * @param {number} [absMinPower=0] - Indicate the minimum electrical power that the ESA can consume when switched on. Defaults to `0` if not provided. * @param {number} [absMaxPower=0] - Indicate the maximum electrical power that the ESA can consume when switched on. Defaults to `0` if not provided. */ constructor(name, serial, currentMode, supportedModes, state, supplyState, faultState, absMinPower, absMaxPower) { super([evse, powerSource, electricalSensor, deviceEnergyManagement], { uniqueStorageKey: `${name.replaceAll(' ', '')}-${serial.replaceAll(' ', '')}` }, true); this.createDefaultIdentifyClusterServer() .createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge EVSE') .createDefaultPowerSourceWiredClusterServer() .createDefaultPowerTopologyClusterServer() .createDefaultElectricalPowerMeasurementClusterServer() .createDefaultElectricalEnergyMeasurementClusterServer() .createDefaultDeviceEnergyManagementClusterServer(DeviceEnergyManagement.EsaType.Evse, false, DeviceEnergyManagement.EsaState.Online, absMinPower, absMaxPower) .createDefaultEnergyEvseClusterServer(state, supplyState, faultState) .createDefaultEnergyEvseModeClusterServer(currentMode, supportedModes) .addRequiredClusterServers(); } /** * Creates a default EnergyEvseServer Cluster Server. * */ createDefaultEnergyEvseClusterServer(state, supplyState, faultState) { this.behaviors.require(MatterbridgeEnergyEvseServer, { state: state ?? EnergyEvse.State.NotPluggedIn, supplyState: supplyState ?? EnergyEvse.SupplyState.ChargingEnabled, faultState: faultState ?? EnergyEvse.FaultState.NoError, chargingEnabledUntil: 0, // Persistent attribute circuitCapacity: 0, // Persistent attribute in mA minimumChargeCurrent: 6000, // Persistent attribute in mA maximumChargeCurrent: 0, // Persistent attribute in mA sessionId: null, // Persistent attribute sessionDuration: 0, // Persistent attribute sessionEnergyCharged: 0, // Persistent attribute }); return this; } /** * Creates a default EnergyEvseMode Cluster Server. * * @param {number} [currentMode] - The current mode of the EnergyEvseMode cluster. Defaults to mode 1 (EnergyEvseMode.ModeTag.Manual). * @param {EnergyEvseMode.ModeOption[]} [supportedModes] - The supported modes for the EnergyEvseMode cluster. Defaults all EnergyEvseMode cluster modes. * * @returns {this} The current MatterbridgeEndpoint instance for chaining. */ createDefaultEnergyEvseModeClusterServer(currentMode, supportedModes) { this.behaviors.require(MatterbridgeEnergyEvseModeServer, { supportedModes: supportedModes ?? [ { label: 'On demand', mode: 1, modeTags: [{ value: EnergyEvseMode.ModeTag.Manual }] }, { label: 'Scheduled', mode: 2, modeTags: [{ value: EnergyEvseMode.ModeTag.TimeOfUse }] }, { label: 'Solar charging', mode: 3, modeTags: [{ value: EnergyEvseMode.ModeTag.SolarCharging }] }, // { label: 'Home to vehicle and Vehicle to home', mode: 4, modeTags: [{ value: EnergyEvseMode.ModeTag.V2X }] }, // This mode is not valid in charging only EVSEs ], // FixedAttribute currentMode: currentMode ?? 1, // Persistent attribute }); return this; } } export class MatterbridgeEnergyEvseServer extends EnergyEvseServer { disable() { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`Disable charging (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('disable', { request: {}, cluster: EnergyEvseServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeEnergyEvseServer disable called`); this.state.supplyState = EnergyEvse.SupplyState.Disabled; if (this.state.state === EnergyEvse.State.PluggedInCharging) { this.state.state = EnergyEvse.State.PluggedInDemand; } this.state.chargingEnabledUntil = 0; // super.disable(); // disable is not implemented in matter.js } enableCharging(request) { const device = this.endpoint.stateOf(MatterbridgeServer); device.log.info(`EnableCharging (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`); device.commandHandler.executeHandler('enableCharging', { request, cluster: EnergyEvseServer.id, attributes: this.state, endpoint: this.endpoint }); device.log.debug(`MatterbridgeEnergyEvseServer enableCharging called`); this.state.supplyState = EnergyEvse.SupplyState.ChargingEnabled; if (this.state.state === EnergyEvse.State.PluggedInDemand) { this.state.state = EnergyEvse.State.PluggedInCharging; } this.state.chargingEnabledUntil = request.chargingEnabledUntil; this.state.minimumChargeCurrent = request.minimumChargeCurrent; this.state.maximumChargeCurrent = request.maximumChargeCurrent; // The implementation should also stop the charging session at the required time and update the sessionId, sessionDuration, and sessionEnergyCharged attributes if needed. // super.enableCharging(); // enableCharging is not implemented in matter.js } } export class MatterbridgeEnergyEvseModeServer extends EnergyEvseModeServer { 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: EnergyEvseModeServer.id, attributes: this.state, endpoint: this.endpoint }); const supported = this.state.supportedModes.find((mode) => mode.mode === request.newMode); if (!supported) { device.log.error(`MatterbridgeEnergyEvseModeServer changeToMode called with unsupported newMode: ${request.newMode}`); return { status: ModeBase.ModeChangeStatus.UnsupportedMode, statusText: 'Unsupported mode' }; } this.state.currentMode = request.newMode; device.log.debug(`MatterbridgeEnergyEvseModeServer changeToMode called with newMode ${request.newMode} => ${supported.label}`); return { status: ModeBase.ModeChangeStatus.Success, statusText: 'Success' }; } } //# sourceMappingURL=evse.js.map