UNPKG

@citrineos/configuration

Version:

The configuration module for OCPP v2.0.1. This module is not intended to be used directly, but rather as a dependency for other modules.

701 lines 42.6 kB
"use strict"; // Copyright (c) 2023 S44, LLC // Copyright Contributors to the CitrineOS Project // // SPDX-License-Identifier: Apache 2.0 var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigurationModule = void 0; const base_1 = require("@citrineos/base"); const data_1 = require("@citrineos/data"); const util_1 = require("@citrineos/util"); const uuid_1 = require("uuid"); const DeviceModelService_1 = require("./DeviceModelService"); const BootNotificationService_1 = require("./BootNotificationService"); /** * Component that handles Configuration related messages. */ class ConfigurationModule extends base_1.AbstractModule { /** * Constructor */ /** * This is the constructor function that initializes the {@link ConfigurationModule}. * * @param {SystemConfig} config - The `config` contains configuration settings for the module. * * @param {ICache} [cache] - The cache instance which is shared among the modules & Central System to pass information such as blacklisted actions or boot status. * * @param {IMessageSender} [sender] - The `sender` parameter is an optional parameter that represents an instance of the {@link IMessageSender} interface. * It is used to send messages from the central system to external systems or devices. If no `sender` is provided, a default {@link RabbitMqSender} instance is created and used. * * @param {IMessageHandler} [handler] - The `handler` parameter is an optional parameter that represents an instance of the {@link IMessageHandler} interface. * It is used to handle incoming messages and dispatch them to the appropriate methods or functions. If no `handler` is provided, a default {@link RabbitMqReceiver} instance is created and used. * * @param {Logger<ILogObj>} [logger] - The `logger` parameter is an optional parameter that represents an instance of {@link Logger<ILogObj>}. * It is used to propagate system-wide logger settings and will serve as the parent logger for any subcomponent logging. If no `logger` is provided, a default {@link Logger<ILogObj>} instance is created and used. * * @param {IBootRepository} [bootRepository] - An optional parameter of type {@link IBootRepository} which represents a repository for accessing and manipulating authorization data. * If no `bootRepository` is provided, a default {@link SequelizeBootRepository} instance is created and used. * * @param {IDeviceModelRepository} [deviceModelRepository] - An optional parameter of type {@link IDeviceModelRepository} which represents a repository for accessing and manipulating variable data. * If no `deviceModelRepository` is provided, a default {@link sequelize:deviceModelRepository} instance is created and used. * * @param {IMessageInfoRepository} [messageInfoRepository] - An optional parameter of type {@link messageInfoRepository} which * represents a repository for accessing and manipulating message info data. If no `messageInfoRepository` is provided, a default * {@link SequelizeMessageInfoRepository} instance is created and used. * * @param {ILocationRepository} [locationRepository] - An optional parameter of type {@link locationRepository} which * represents a repository for accessing and manipulating location data. If no `locationRepository` is provided, a default * {@link SequelizeLocationRepository} instance is created and used. * * @param {IChangeConfigurationRepository} [changeConfigurationRepository] - An optional parameter of type {@link IChangeConfigurationRepository} which * represents a repository for accessing and manipulating change configuration data. If no `changeConfigurationRepository` is provided, a default * {@link SequelizeChangeConfigurationRepository} instance is created and used. * * @param {IOCPPMessageRepository} [ocppMessageRepository] - An optional parameter of type {@link IOCPPMessageRepository} which * represents a repository for accessing and manipulating call message data. If no `ocppMessageRepository` is provided, a default * {@link SequelizeOCPPMessageRepository} instance is created and used. * * @param {IdGenerator} [idGenerator] - An optional parameter of type {@link IdGenerator} which * represents a generator for ids. * *If no `deviceModelRepository` is provided, a default {@link sequelize:messageInfoRepository} instance is created and used. */ constructor(config, cache, sender, handler, logger, bootRepository, deviceModelRepository, messageInfoRepository, locationRepository, changeConfigurationRepository, ocppMessageRepository, idGenerator) { super(config, cache, handler || new util_1.RabbitMqReceiver(config, logger), sender || new util_1.RabbitMqSender(config, logger), base_1.EventGroup.Configuration, logger); this._requests = [ base_1.OCPP2_0_1_CallAction.BootNotification, base_1.OCPP2_0_1_CallAction.DataTransfer, base_1.OCPP2_0_1_CallAction.FirmwareStatusNotification, base_1.OCPP2_0_1_CallAction.Heartbeat, base_1.OCPP2_0_1_CallAction.NotifyDisplayMessages, base_1.OCPP2_0_1_CallAction.PublishFirmwareStatusNotification, base_1.OCPP1_6_CallAction.Heartbeat, base_1.OCPP1_6_CallAction.BootNotification, ]; this._responses = [ base_1.OCPP2_0_1_CallAction.ChangeAvailability, base_1.OCPP2_0_1_CallAction.ClearDisplayMessage, base_1.OCPP2_0_1_CallAction.GetDisplayMessages, base_1.OCPP2_0_1_CallAction.PublishFirmware, base_1.OCPP2_0_1_CallAction.Reset, base_1.OCPP2_0_1_CallAction.SetDisplayMessage, base_1.OCPP2_0_1_CallAction.SetNetworkProfile, base_1.OCPP2_0_1_CallAction.TriggerMessage, base_1.OCPP2_0_1_CallAction.UnpublishFirmware, base_1.OCPP2_0_1_CallAction.UpdateFirmware, base_1.OCPP1_6_CallAction.ChangeAvailability, base_1.OCPP1_6_CallAction.ChangeConfiguration, base_1.OCPP1_6_CallAction.GetConfiguration, base_1.OCPP1_6_CallAction.Reset, base_1.OCPP1_6_CallAction.TriggerMessage, ]; this._bootRepository = bootRepository || new data_1.sequelize.SequelizeBootRepository(config, this._logger); this._deviceModelRepository = deviceModelRepository || new data_1.sequelize.SequelizeDeviceModelRepository(config, this._logger); this._messageInfoRepository = messageInfoRepository || new data_1.sequelize.SequelizeMessageInfoRepository(config, this._logger); this._locationRepository = locationRepository || new data_1.sequelize.SequelizeLocationRepository(config, this._logger); this._changeConfigurationRepository = changeConfigurationRepository || new data_1.SequelizeChangeConfigurationRepository(config, this._logger); this._ocppMessageRepository = ocppMessageRepository || new data_1.SequelizeOCPPMessageRepository(config, this._logger); this._deviceModelService = new DeviceModelService_1.DeviceModelService(this._deviceModelRepository); this._bootService = new BootNotificationService_1.BootNotificationService(this._bootRepository, this._cache, this._config.modules.configuration, this._logger); this._idGenerator = idGenerator || new util_1.IdGenerator(new data_1.SequelizeChargingStationSequenceRepository(config, this._logger)); } get bootRepository() { return this._bootRepository; } get deviceModelRepository() { return this._deviceModelRepository; } get messageInfoRepository() { return this._messageInfoRepository; } get locationRepository() { return this._locationRepository; } get changeConfigurationRepository() { return this._changeConfigurationRepository; } get ocppMessageRepository() { return this._ocppMessageRepository; } /** * Handle OCPP 2.0.1 requests */ _handleBootNotification(message, props) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f; this._logger.debug('BootNotification received:', message, props); const stationId = message.context.stationId; const tenantId = message.context.tenantId; const timestamp = message.context.timestamp; const chargingStation = message.payload.chargingStation; const bootNotificationResponse = yield this._bootService.createBootNotificationResponse(stationId); // Check cached boot status for charger. Only Pending and Rejected statuses are cached. const cachedBootStatus = yield this._cache.get(base_1.BOOT_STATUS, stationId); // Blacklist or whitelist charger actions in cache yield this._bootService.cacheChargerActionsPermissions(stationId, cachedBootStatus, bootNotificationResponse.status); const bootNotificationResponseMessageConfirmation = yield this.sendCallResultWithMessage(message, bootNotificationResponse); // Update or create charging station yield this._deviceModelService.updateDeviceModel(chargingStation, stationId, timestamp); if (!bootNotificationResponseMessageConfirmation.success) { throw new Error('BootNotification failed: ' + bootNotificationResponseMessageConfirmation); } if (bootNotificationResponse.status !== base_1.OCPP2_0_1.RegistrationStatusEnumType.Accepted && (!cachedBootStatus || bootNotificationResponse.status !== cachedBootStatus)) { // Cache boot status for charger if (not accepted) and ((not already cached) or (different status from cached status)). yield this._cache.set(base_1.BOOT_STATUS, bootNotificationResponse.status, stationId); } // Update charger-specific boot config with details of most recently sent BootNotificationResponse const bootConfigDbEntity = yield this._bootService.updateBootConfig(bootNotificationResponse, stationId); // If boot notification is not pending, do not start configuration. // If cached boot status is not null and pending, configuration is already in progress - do not start configuration again. if (bootNotificationResponse.status !== base_1.OCPP2_0_1.RegistrationStatusEnumType.Pending || (cachedBootStatus && cachedBootStatus === base_1.OCPP2_0_1.RegistrationStatusEnumType.Pending)) { return; } // GetBaseReport // TODO Consider refactoring GetBaseReport and SetVariables sections as methods to be used by their respective message api endpoints as well if ((_a = bootConfigDbEntity.getBaseReportOnPending) !== null && _a !== void 0 ? _a : (_b = this._config.modules.configuration.ocpp2_0_1) === null || _b === void 0 ? void 0 : _b.getBaseReportOnPending) { // Remove Notify Report from blacklist yield this._cache.remove(base_1.OCPP2_0_1_CallAction.NotifyReport, stationId); const getBaseReportRequest = yield this._bootService.createGetBaseReportRequest(stationId, this._config.maxCachingSeconds); const getBaseReportConfirmation = yield this.sendCall(stationId, tenantId, base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.GetBaseReport, getBaseReportRequest); yield this._bootService.confirmGetBaseReportSuccess(stationId, getBaseReportRequest.requestId.toString(), getBaseReportConfirmation, this._config.maxCachingSeconds); // Make sure GetBaseReport doesn't re-trigger on next boot attempt bootConfigDbEntity.getBaseReportOnPending = false; yield bootConfigDbEntity.save(); } // SetVariables let rejectedSetVariable = false; let rebootSetVariable = false; if (bootConfigDbEntity.pendingBootSetVariables && bootConfigDbEntity.pendingBootSetVariables.length > 0) { bootConfigDbEntity.variablesRejectedOnLastBoot = []; let setVariableData = yield this._deviceModelRepository.readAllSetVariableByStationId(stationId); // If ItemsPerMessageSetVariables not set, send all variables at once const itemsPerMessageSetVariables = (_c = (yield this._deviceModelService.getItemsPerMessageSetVariablesByStationId(stationId))) !== null && _c !== void 0 ? _c : setVariableData.length; while (setVariableData.length > 0) { const correlationId = (0, uuid_1.v4)(); const cacheCallbackPromise = this._cache.onChange(correlationId, this._config.maxCachingSeconds, stationId); // x2 fudge factor for any network lag yield this.sendCall(stationId, tenantId, base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.SetVariables, { setVariableData: setVariableData.slice(0, itemsPerMessageSetVariables), }, undefined, correlationId); setVariableData = setVariableData.slice(itemsPerMessageSetVariables); const setVariablesResponseJsonString = yield cacheCallbackPromise; if (setVariablesResponseJsonString) { if (rejectedSetVariable && rebootSetVariable) { continue; } const setVariablesResponse = JSON.parse(setVariablesResponseJsonString); setVariablesResponse.setVariableResult.forEach((result) => { if (result.attributeStatus === base_1.OCPP2_0_1.SetVariableStatusEnumType.Rejected) { rejectedSetVariable = true; } else if (result.attributeStatus === base_1.OCPP2_0_1.SetVariableStatusEnumType.RebootRequired) { rebootSetVariable = true; } }); } else { throw new Error('SetVariables response not found'); } } const doNotBootWithRejectedVariables = !((_d = bootConfigDbEntity.bootWithRejectedVariables) !== null && _d !== void 0 ? _d : (_e = this._config.modules.configuration.ocpp2_0_1) === null || _e === void 0 ? void 0 : _e.bootWithRejectedVariables); if (rejectedSetVariable && doNotBootWithRejectedVariables) { bootConfigDbEntity.status = base_1.OCPP2_0_1.RegistrationStatusEnumType.Rejected; yield bootConfigDbEntity.save(); // No more to do. return; } } if ((_f = this._config.modules.configuration.ocpp2_0_1) === null || _f === void 0 ? void 0 : _f.autoAccept) { // Update boot config with status accepted // TODO: Determine how/if StatusInfo should be generated bootConfigDbEntity.status = base_1.OCPP2_0_1.RegistrationStatusEnumType.Accepted; yield bootConfigDbEntity.save(); } if (rebootSetVariable) { // Charger SHALL not be in a transaction as it has not yet successfully booted, therefore it is appropriate to send an Immediate Reset yield this.sendCall(stationId, tenantId, base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.Reset, { type: base_1.OCPP2_0_1.ResetEnumType.Immediate, }); } else { // We could trigger the new boot immediately rather than wait for the retry, as nothing more now needs to be done. // However, B02.FR.02 - Spec allows for TriggerMessageRequest - OCTT fails over trigger // Commenting out until OCTT behavior changes. // this.sendCall(stationId, tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.TriggerMessage, // { requestedMessage: MessageTriggerEnumType.BootNotification } as TriggerMessageRequest); } }); } _handleHeartbeat(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('Heartbeat received:', message, props); // Create response const response = { currentTime: new Date().toISOString(), }; const messageConfirmation = yield this.sendCallResultWithMessage(message, response); this._logger.debug('Heartbeat response sent: ', messageConfirmation); }); } _handleNotifyDisplayMessages(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('NotifyDisplayMessages received: ', message, props); const messageInfoTypes = message.payload.messageInfo; for (const messageInfoType of messageInfoTypes) { let componentId; if (messageInfoType.display) { const component = yield this._deviceModelRepository.findOrCreateEvseAndComponent(messageInfoType.display, message.context.tenantId); componentId = component.id; } yield this._messageInfoRepository.createOrUpdateByMessageInfoTypeAndStationId(messageInfoType, message.context.stationId, componentId); } // Create response const response = {}; const messageConfirmation = yield this.sendCallResultWithMessage(message, response); this._logger.debug('NotifyDisplayMessages response sent: ', messageConfirmation); }); } _handleFirmwareStatusNotification(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('FirmwareStatusNotification received:', message, props); // TODO: FirmwareStatusNotification is usually triggered. Ideally, it should be sent to the callbackUrl from the message api that sent the trigger message // Create response const response = {}; const messageConfirmation = yield this.sendCallResultWithMessage(message, response); this._logger.debug('FirmwareStatusNotification response sent: ', messageConfirmation); }); } _handleDataTransfer(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('DataTransfer received:', message, props); // Create response const response = { status: base_1.OCPP2_0_1.DataTransferStatusEnumType.Rejected, statusInfo: { reasonCode: base_1.ErrorCode.NotImplemented }, }; const messageConfirmation = yield this.sendCallResultWithMessage(message, response); this._logger.debug('DataTransfer response sent: ', messageConfirmation); }); } /** * Handle OCPP 2.0.1 responses */ _handleChangeAvailability(message, props) { this._logger.debug('ChangeAvailability response received:', message, props); } _handleSetNetworkProfile(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('SetNetworkProfile response received:', message, props); if (message.payload.status == base_1.OCPP2_0_1.SetNetworkProfileStatusEnumType.Accepted) { const setNetworkProfile = yield data_1.SetNetworkProfile.findOne({ where: { correlationId: message.context.correlationId }, }); if (setNetworkProfile) { const serverNetworkProfile = yield data_1.ServerNetworkProfile.findByPk(setNetworkProfile.websocketServerConfigId); if (serverNetworkProfile) { const chargingStation = yield data_1.ChargingStation.findByPk(message.context.stationId); if (chargingStation) { const [chargingStationNetworkProfile] = yield data_1.ChargingStationNetworkProfile.findOrBuild({ where: { stationId: chargingStation.id, configurationSlot: setNetworkProfile.configurationSlot, }, }); chargingStationNetworkProfile.websocketServerConfigId = setNetworkProfile.websocketServerConfigId; chargingStationNetworkProfile.setNetworkProfileId = setNetworkProfile.id; yield chargingStationNetworkProfile.save(); } } } } }); } _handleGetDisplayMessages(message, props) { this._logger.debug('GetDisplayMessages response received:', message, props); } _handleSetDisplayMessage(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('SetDisplayMessage response received:', message, props); const status = message.payload.status; // when charger station accepts the set message info request // we trigger a get all display messages request to update stored message info in db if (status === base_1.OCPP2_0_1.DisplayMessageStatusEnumType.Accepted) { yield this._messageInfoRepository.deactivateAllByStationId(message.context.stationId); yield this.sendCall(message.context.stationId, message.context.tenantId, base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.GetDisplayMessages, { requestId: yield this._idGenerator.generateRequestId(message.context.stationId, base_1.ChargingStationSequenceType.getDisplayMessages), }); } }); } _handlePublishFirmware(message, props) { this._logger.debug('PublishFirmware response received:', message, props); } _handleUnpublishFirmware(message, props) { this._logger.debug('UnpublishFirmware response received:', message, props); } _handleUpdateFirmware(message, props) { this._logger.debug('UpdateFirmware response received:', message, props); } _handleReset(message, props) { this._logger.debug('Reset response received:', message, props); } _handleTriggerMessage(message, props) { this._logger.debug('TriggerMessage response received:', message, props); } _handleClearDisplayMessage(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('ClearDisplayMessage response received:', message, props); const status = message.payload.status; // when charger station accepts the clear message info request // we trigger a get all display messages request to update stored message info in db if (status === base_1.OCPP2_0_1.ClearMessageStatusEnumType.Accepted) { yield this._messageInfoRepository.deactivateAllByStationId(message.context.stationId); yield this.sendCall(message.context.stationId, message.context.tenantId, base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.GetDisplayMessages, { requestId: yield this._idGenerator.generateRequestId(message.context.stationId, base_1.ChargingStationSequenceType.getDisplayMessages), }); } }); } /** * Handle OCPP 1.6 requests */ _handle16Heartbeat(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('Heartbeat received:', message, props); const response = { currentTime: new Date().toISOString(), }; const messageConfirmation = yield this.sendCallResultWithMessage(message, response); this._logger.debug('Heartbeat response sent: ', messageConfirmation); }); } _handleOcpp16BootNotification(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('OCPP 1.6 BootNotification request received:', message, props); const stationId = message.context.stationId; const tenantId = message.context.tenantId; const request = message.payload; // 1. Send BootNotification response // Create BootNotification response const bootNotificationResponse = yield this._bootService.createOcpp16BootNotificationResponse(stationId); // Check cached boot status for charger. Only Pending and Rejected statuses are cached. const cachedBootStatus = yield this._cache.get(base_1.BOOT_STATUS, stationId); // Blacklist or whitelist charger actions yield this._bootService.cacheOcpp16ChargerActionsPermissions(stationId, cachedBootStatus, bootNotificationResponse.status); // Send BootNotification response const bootNotificationResponseMessageConfirmation = yield this.sendCallResultWithMessage(message, bootNotificationResponse); // Create or update charging station this._logger.debug(`Creating or updating charging station: ${stationId}`); yield this._locationRepository.createOrUpdateChargingStation(data_1.ChargingStation.build({ id: stationId, chargePointVendor: request.chargePointVendor, chargePointModel: request.chargePointModel, chargePointSerialNumber: request.chargePointSerialNumber, chargeBoxSerialNumber: request.chargeBoxSerialNumber, firmwareVersion: request.firmwareVersion, iccid: request.iccid, imsi: request.imsi, meterType: request.meterType, meterSerialNumber: request.meterSerialNumber, })); // Check if response was successful if (!bootNotificationResponseMessageConfirmation.success) { throw new Error('Send BootNotification response failed: ' + bootNotificationResponseMessageConfirmation); } // 2. Update boot status in cache and db entity // Cache boot status for charger if (not accepted) and ((not already cached) or (different status from cached status)). if (bootNotificationResponse.status !== base_1.OCPP1_6.BootNotificationResponseStatus.Accepted && (!cachedBootStatus || bootNotificationResponse.status !== cachedBootStatus)) { yield this._cache.set(base_1.BOOT_STATUS, bootNotificationResponse.status, stationId); } // Update boot with details of most recently sent BootNotificationResponse const bootEntity = yield this._bootService.updateOcpp16BootConfig(bootNotificationResponse, stationId); // 3. Sync configurations // If boot notification is not pending, do not start configuration. // If cached boot status is not null and pending, configuration is already in progress - do not start configuration again. if (bootNotificationResponse.status !== base_1.OCPP1_6.BootNotificationResponseStatus.Pending || (cachedBootStatus && cachedBootStatus === base_1.OCPP1_6.BootNotificationResponseStatus.Pending)) { return; } let changeConfigurationsOnPending = false; let getConfigurationsOnPending = true; // Change Configurations on charging station const configurations = yield this._changeConfigurationRepository.readAllByQuery({ where: { stationId, }, }); // Remove ChangeConfiguration call action from blacklist yield this._cache.remove(base_1.OCPP1_6_CallAction.ChangeConfiguration, stationId); // Set each configuration on Charging Station for (const config of configurations) { const correlationId = (0, uuid_1.v4)(); const cacheCallbackPromise = this._cache.onChange(correlationId, this._config.maxCachingSeconds, stationId); const changeConfigurationResponseMessageConfirmation = yield this.sendCall(stationId, tenantId, base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.ChangeConfiguration, { key: config.key, value: config.value, }, undefined, correlationId); if (!changeConfigurationResponseMessageConfirmation.success) { changeConfigurationsOnPending = true; } // wait before sending next call yield cacheCallbackPromise; } // Get Configurations from charging station // Remove GetConfiguration call action from blacklist yield this._cache.remove(base_1.OCPP1_6_CallAction.GetConfiguration, stationId); // Send GetConfiguration request to charger const getConfigurationResponseMessageConfirmation = yield this.sendCall(stationId, tenantId, base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.GetConfiguration, {}); if (getConfigurationResponseMessageConfirmation.success) { getConfigurationsOnPending = false; } // Update configuration related fields on boot entity yield this._bootRepository.updateByKey({ changeConfigurationsOnPending, getConfigurationsOnPending, }, bootEntity.id); // 4. Trigger another boot when pending yield this._cache.remove(base_1.OCPP1_6_CallAction.TriggerMessage, stationId); yield this.sendCall(stationId, tenantId, base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.TriggerMessage, { requestedMessage: base_1.OCPP1_6.TriggerMessageRequestRequestedMessage.BootNotification, }); }); } /** * Handle OCPP 1.6 response */ _handleOcpp16GetConfiguration(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('OCPP 1.6 GetConfiguration response received:', message, props); const stationId = message.context.stationId; const configurations = message.payload.configurationKey; if (configurations && configurations.length > 0) { for (const config of configurations) { if (config.key) { yield this._changeConfigurationRepository.createOrUpdateChangeConfiguration({ stationId, key: config.key, value: config.value, readonly: config.readonly, }); } } } }); } _handleOcpp16ChangeConfiguration(message, props) { return __awaiter(this, void 0, void 0, function* () { this._logger.debug('OCPP 1.6 ChangeConfiguration response received:', message, props); const stationId = message.context.stationId; const correlationId = message.context.correlationId; const request = yield this._ocppMessageRepository.readOnlyOneByQuery({ where: { stationId, correlationId, origin: base_1.MessageOrigin.ChargingStationManagementSystem, }, }); if (!request) { this._logger.error(`No valid ChangeConfigurationRequest found for correlationId ${correlationId}`); } const status = message.payload.status; const key = request === null || request === void 0 ? void 0 : request.message[3].key; const value = request === null || request === void 0 ? void 0 : request.message[3].value; if (status == base_1.OCPP1_6.ChangeConfigurationResponseStatus.Rejected || status == base_1.OCPP1_6.ChangeConfigurationResponseStatus.NotSupported) { this._logger.warn(`Attempted ChangeConfiguration ${correlationId} for ${key}:${value} unsuccessful with status ${status}`); return; } else { const config = yield this._changeConfigurationRepository.createOrUpdateChangeConfiguration({ stationId, key, value, }); if (!config) { this._logger.error(`Failed to create or update configuration ${key}:${value} on ${stationId}`); } else { this._logger.debug(`Updated changeConfiguration ${key}:${value}`); } } }); } _handleOcpp16TriggerMessage(message, props) { this._logger.debug('TriggerMessage response received:', message, props); if (message.payload.status !== base_1.OCPP1_6.TriggerMessageResponseStatus.Accepted) { this._logger.error('TriggerMessage failed with status:', message); } } _handle16Reset(message, props) { this._logger.debug('Reset response received:', message, props); } _handleOcpp16ChangeAvailability(message, props) { this._logger.debug('ChangeAvailability response received:', message, props); } } exports.ConfigurationModule = ConfigurationModule; __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.BootNotification), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleBootNotification", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.Heartbeat), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleHeartbeat", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.NotifyDisplayMessages), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleNotifyDisplayMessages", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.FirmwareStatusNotification), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleFirmwareStatusNotification", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.DataTransfer), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleDataTransfer", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.ChangeAvailability), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleChangeAvailability", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.SetNetworkProfile), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleSetNetworkProfile", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.GetDisplayMessages), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleGetDisplayMessages", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.SetDisplayMessage), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleSetDisplayMessage", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.PublishFirmware), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handlePublishFirmware", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.UnpublishFirmware), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleUnpublishFirmware", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.UpdateFirmware), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleUpdateFirmware", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.Reset), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleReset", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.TriggerMessage), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleTriggerMessage", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP2_0_1, base_1.OCPP2_0_1_CallAction.ClearDisplayMessage), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleClearDisplayMessage", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.Heartbeat), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handle16Heartbeat", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.BootNotification), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleOcpp16BootNotification", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.GetConfiguration), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleOcpp16GetConfiguration", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.ChangeConfiguration), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], ConfigurationModule.prototype, "_handleOcpp16ChangeConfiguration", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.TriggerMessage), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleOcpp16TriggerMessage", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.Reset), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handle16Reset", null); __decorate([ (0, base_1.AsHandler)(base_1.OCPPVersion.OCPP1_6, base_1.OCPP1_6_CallAction.ChangeAvailability), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", void 0) ], ConfigurationModule.prototype, "_handleOcpp16ChangeAvailability", null); //# sourceMappingURL=module.js.map