@zetra/citrineos-configuration 1.8.3-fork.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/module/1.6/MessageApi.d.ts +34 -0
- package/dist/module/1.6/MessageApi.js +190 -0
- package/dist/module/1.6/MessageApi.js.map +1 -0
- package/dist/module/2.0.1/MessageApi.d.ts +38 -0
- package/dist/module/2.0.1/MessageApi.js +183 -0
- package/dist/module/2.0.1/MessageApi.js.map +1 -0
- package/dist/module/BootNotificationService.d.ts +57 -0
- package/dist/module/BootNotificationService.js +248 -0
- package/dist/module/BootNotificationService.js.map +1 -0
- package/dist/module/DataApi.d.ts +52 -0
- package/dist/module/DataApi.js +206 -0
- package/dist/module/DataApi.js.map +1 -0
- package/dist/module/DeviceModelService.d.ts +30 -0
- package/dist/module/DeviceModelService.js +122 -0
- package/dist/module/DeviceModelService.js.map +1 -0
- package/dist/module/interface.d.ts +5 -0
- package/dist/module/interface.js +5 -0
- package/dist/module/interface.js.map +1 -0
- package/dist/module/module.d.ts +110 -0
- package/dist/module/module.js +733 -0
- package/dist/module/module.js.map +1 -0
- package/package.json +25 -0
|
@@ -0,0 +1,733 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { AbstractModule, AsHandler, BOOT_STATUS, ChargingStationSequenceTypeEnum, ErrorCode, EventGroup, MessageOrigin, Namespace, OCPP1_6, OCPP1_6_CallAction, OCPP2_0_1, OCPP2_0_1_CallAction, OcppError, OCPPValidator, OCPPVersion, } from '@citrineos/base';
|
|
11
|
+
import { Boot, ChangeConfiguration, ChargingStation, ChargingStationNetworkProfile, Component, sequelize, SequelizeChangeConfigurationRepository, SequelizeChargingStationSequenceRepository, SequelizeOCPPMessageRepository, ServerNetworkProfile, SetNetworkProfile, } from '@citrineos/data';
|
|
12
|
+
import { IdGenerator, RabbitMqReceiver, RabbitMqSender, validateMessageContentType, } from '@citrineos/util';
|
|
13
|
+
import { Logger } from 'tslog';
|
|
14
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
15
|
+
import { BootNotificationService } from './BootNotificationService.js';
|
|
16
|
+
import { DeviceModelService } from './DeviceModelService.js';
|
|
17
|
+
/**
|
|
18
|
+
* Component that handles Configuration related messages.
|
|
19
|
+
*/
|
|
20
|
+
export class ConfigurationModule extends AbstractModule {
|
|
21
|
+
_deviceModelService;
|
|
22
|
+
_requests = [];
|
|
23
|
+
_responses = [];
|
|
24
|
+
_bootService;
|
|
25
|
+
_idGenerator;
|
|
26
|
+
/**
|
|
27
|
+
* This is the constructor function that initializes the {@link ConfigurationModule}.
|
|
28
|
+
*
|
|
29
|
+
* @param {BootstrapConfig & SystemConfig} config - The `config` contains configuration settings for the module.
|
|
30
|
+
*
|
|
31
|
+
* @param {ICache} [cache] - The cache instance which is shared among the modules & Central System to pass information such as blacklisted actions or boot status.
|
|
32
|
+
*
|
|
33
|
+
* @param {IMessageSender} [sender] - The `sender` parameter is an optional parameter that represents an instance of the {@link IMessageSender} interface.
|
|
34
|
+
* 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.
|
|
35
|
+
*
|
|
36
|
+
* @param {IMessageHandler} [handler] - The `handler` parameter is an optional parameter that represents an instance of the {@link IMessageHandler} interface.
|
|
37
|
+
* 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.
|
|
38
|
+
*
|
|
39
|
+
* @param {Logger<ILogObj>} [logger] - The `logger` parameter is an optional parameter that represents an instance of {@link Logger<ILogObj>}.
|
|
40
|
+
* 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.
|
|
41
|
+
*
|
|
42
|
+
* @param {IBootRepository} [bootRepository] - An optional parameter of type {@link IBootRepository} which represents a repository for accessing and manipulating authorization data.
|
|
43
|
+
* If no `bootRepository` is provided, a default {@link SequelizeBootRepository} instance is created and used.
|
|
44
|
+
*
|
|
45
|
+
* @param {IDeviceModelRepository} [deviceModelRepository] - An optional parameter of type {@link IDeviceModelRepository} which represents a repository for accessing and manipulating variable data.
|
|
46
|
+
* If no `deviceModelRepository` is provided, a default {@link sequelize:deviceModelRepository} instance is created and used.
|
|
47
|
+
*
|
|
48
|
+
* @param {IMessageInfoRepository} [messageInfoRepository] - An optional parameter of type {@link messageInfoRepository} which
|
|
49
|
+
* represents a repository for accessing and manipulating message info data. If no `messageInfoRepository` is provided, a default
|
|
50
|
+
* {@link SequelizeMessageInfoRepository} instance is created and used.
|
|
51
|
+
*
|
|
52
|
+
* @param {ILocationRepository} [locationRepository] - An optional parameter of type {@link locationRepository} which
|
|
53
|
+
* represents a repository for accessing and manipulating location data. If no `locationRepository` is provided, a default
|
|
54
|
+
* {@link SequelizeLocationRepository} instance is created and used.
|
|
55
|
+
*
|
|
56
|
+
* @param {IChangeConfigurationRepository} [changeConfigurationRepository] - An optional parameter of type {@link IChangeConfigurationRepository} which
|
|
57
|
+
* represents a repository for accessing and manipulating change configuration data. If no `changeConfigurationRepository` is provided, a default
|
|
58
|
+
* {@link SequelizeChangeConfigurationRepository} instance is created and used.
|
|
59
|
+
*
|
|
60
|
+
* @param {IOCPPMessageRepository} [ocppMessageRepository] - An optional parameter of type {@link IOCPPMessageRepository} which
|
|
61
|
+
* represents a repository for accessing and manipulating call message data. If no `ocppMessageRepository` is provided, a default
|
|
62
|
+
* {@link SequelizeOCPPMessageRepository} instance is created and used.
|
|
63
|
+
*
|
|
64
|
+
* @param {IdGenerator} [idGenerator] - An optional parameter of type {@link IdGenerator} which
|
|
65
|
+
* represents a generator for ids.
|
|
66
|
+
*
|
|
67
|
+
*If no `deviceModelRepository` is provided, a default {@link sequelize:messageInfoRepository} instance is created and used.
|
|
68
|
+
*/
|
|
69
|
+
constructor(config, cache, sender, handler, logger, ocppValidator, bootRepository, deviceModelRepository, messageInfoRepository, locationRepository, changeConfigurationRepository, ocppMessageRepository, idGenerator, tenantRepository) {
|
|
70
|
+
super(config, cache, handler || new RabbitMqReceiver(config, logger), sender || new RabbitMqSender(config, logger), EventGroup.Configuration, logger, ocppValidator);
|
|
71
|
+
this._requests = config.modules.configuration.requests;
|
|
72
|
+
this._responses = config.modules.configuration.responses;
|
|
73
|
+
this._bootRepository =
|
|
74
|
+
bootRepository || new sequelize.SequelizeBootRepository(config, this._logger);
|
|
75
|
+
this._deviceModelRepository =
|
|
76
|
+
deviceModelRepository || new sequelize.SequelizeDeviceModelRepository(config, this._logger);
|
|
77
|
+
this._messageInfoRepository =
|
|
78
|
+
messageInfoRepository || new sequelize.SequelizeMessageInfoRepository(config, this._logger);
|
|
79
|
+
this._locationRepository =
|
|
80
|
+
locationRepository || new sequelize.SequelizeLocationRepository(config, this._logger);
|
|
81
|
+
this._changeConfigurationRepository =
|
|
82
|
+
changeConfigurationRepository ||
|
|
83
|
+
new SequelizeChangeConfigurationRepository(config, this._logger);
|
|
84
|
+
this._ocppMessageRepository =
|
|
85
|
+
ocppMessageRepository || new SequelizeOCPPMessageRepository(config, this._logger);
|
|
86
|
+
this._tenantRepository =
|
|
87
|
+
tenantRepository || new sequelize.SequelizeTenantRepository(config, this._logger);
|
|
88
|
+
this._deviceModelService = new DeviceModelService(this._deviceModelRepository);
|
|
89
|
+
this._bootService = new BootNotificationService(this._bootRepository, this._cache, this._config.modules.configuration, this._logger);
|
|
90
|
+
this._idGenerator =
|
|
91
|
+
idGenerator ||
|
|
92
|
+
new IdGenerator(new SequelizeChargingStationSequenceRepository(config, this._logger));
|
|
93
|
+
}
|
|
94
|
+
_tenantRepository;
|
|
95
|
+
get tenantRepository() {
|
|
96
|
+
return this._tenantRepository;
|
|
97
|
+
}
|
|
98
|
+
_bootRepository;
|
|
99
|
+
get bootRepository() {
|
|
100
|
+
return this._bootRepository;
|
|
101
|
+
}
|
|
102
|
+
_deviceModelRepository;
|
|
103
|
+
get deviceModelRepository() {
|
|
104
|
+
return this._deviceModelRepository;
|
|
105
|
+
}
|
|
106
|
+
_messageInfoRepository;
|
|
107
|
+
get messageInfoRepository() {
|
|
108
|
+
return this._messageInfoRepository;
|
|
109
|
+
}
|
|
110
|
+
_locationRepository;
|
|
111
|
+
get locationRepository() {
|
|
112
|
+
return this._locationRepository;
|
|
113
|
+
}
|
|
114
|
+
_changeConfigurationRepository;
|
|
115
|
+
get changeConfigurationRepository() {
|
|
116
|
+
return this._changeConfigurationRepository;
|
|
117
|
+
}
|
|
118
|
+
_ocppMessageRepository;
|
|
119
|
+
get ocppMessageRepository() {
|
|
120
|
+
return this._ocppMessageRepository;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Handle OCPP 2.0.1 requests
|
|
124
|
+
*/
|
|
125
|
+
async _handleBootNotification(message, props) {
|
|
126
|
+
this._logger.debug('BootNotification received:', message, props);
|
|
127
|
+
const stationId = message.context.stationId;
|
|
128
|
+
const tenantId = message.context.tenantId;
|
|
129
|
+
const timestamp = message.context.timestamp;
|
|
130
|
+
const chargingStation = message.payload.chargingStation;
|
|
131
|
+
// Quick guard: validate tenant exists before proceeding.
|
|
132
|
+
try {
|
|
133
|
+
const tenantRecord = await this._tenantRepository.readByKey(tenantId, tenantId);
|
|
134
|
+
if (!tenantRecord) {
|
|
135
|
+
await this.sendCallErrorWithMessage(message, new OcppError(message.context.correlationId, ErrorCode.SecurityError, `Unknown tenant ${tenantId}`, {}));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
this._logger.warn('Tenant validation failed', err);
|
|
141
|
+
await this.sendCallErrorWithMessage(message, new OcppError(message.context.correlationId, ErrorCode.SecurityError, `Tenant validation error for ${tenantId}`, {}));
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const bootNotificationResponse = await this._bootService.createBootNotificationResponse(tenantId, stationId);
|
|
145
|
+
// Check cached boot status for charger. Only Pending and Rejected statuses are cached.
|
|
146
|
+
const cachedBootStatus = await this._cache.get(BOOT_STATUS, stationId);
|
|
147
|
+
// Blacklist or whitelist charger actions in cache
|
|
148
|
+
await this._bootService.cacheChargerActionsPermissions(stationId, cachedBootStatus, bootNotificationResponse.status);
|
|
149
|
+
const bootNotificationResponseMessageConfirmation = await this.sendCallResultWithMessage(message, bootNotificationResponse);
|
|
150
|
+
// Update device model and charging station
|
|
151
|
+
this._deviceModelService
|
|
152
|
+
.updateDeviceModel(chargingStation, tenantId, stationId, timestamp)
|
|
153
|
+
.then()
|
|
154
|
+
.catch((error) => {
|
|
155
|
+
this._logger.error(`Error updating device model for station ${stationId} with boot info:`, error);
|
|
156
|
+
});
|
|
157
|
+
this._locationRepository
|
|
158
|
+
.createOrUpdateChargingStation(tenantId, ChargingStation.build({
|
|
159
|
+
tenantId,
|
|
160
|
+
id: stationId,
|
|
161
|
+
chargePointVendor: chargingStation.vendorName,
|
|
162
|
+
chargePointModel: chargingStation.model,
|
|
163
|
+
chargePointSerialNumber: chargingStation.serialNumber,
|
|
164
|
+
firmwareVersion: chargingStation.firmwareVersion,
|
|
165
|
+
iccid: chargingStation.modem?.iccid,
|
|
166
|
+
imsi: chargingStation.modem?.imsi,
|
|
167
|
+
}))
|
|
168
|
+
.then()
|
|
169
|
+
.catch((error) => {
|
|
170
|
+
this._logger.error(`Error updating station ${stationId} with boot info:`, error);
|
|
171
|
+
});
|
|
172
|
+
if (!bootNotificationResponseMessageConfirmation.success) {
|
|
173
|
+
throw new Error('BootNotification failed: ' + bootNotificationResponseMessageConfirmation);
|
|
174
|
+
}
|
|
175
|
+
if (bootNotificationResponse.status !== OCPP2_0_1.RegistrationStatusEnumType.Accepted &&
|
|
176
|
+
(!cachedBootStatus || bootNotificationResponse.status !== cachedBootStatus)) {
|
|
177
|
+
// Cache boot status for charger if (not accepted) and ((not already cached) or (different status from cached status)).
|
|
178
|
+
await this._cache.set(BOOT_STATUS, bootNotificationResponse.status, stationId);
|
|
179
|
+
}
|
|
180
|
+
// Update charger-specific boot config with details of most recently sent BootNotificationResponse
|
|
181
|
+
const bootConfigDbEntity = await this._bootService.updateBootConfig(bootNotificationResponse, tenantId, stationId);
|
|
182
|
+
// If boot notification is not pending, do not start configuration.
|
|
183
|
+
// If cached boot status is not null and pending, configuration is already in progress - do not start configuration again.
|
|
184
|
+
if (bootNotificationResponse.status !== OCPP2_0_1.RegistrationStatusEnumType.Pending ||
|
|
185
|
+
(cachedBootStatus && cachedBootStatus === OCPP2_0_1.RegistrationStatusEnumType.Pending)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// GetBaseReport
|
|
189
|
+
// TODO Consider refactoring GetBaseReport and SetVariables sections as methods to be used by their respective message api endpoints as well
|
|
190
|
+
if (bootConfigDbEntity.getBaseReportOnPending ??
|
|
191
|
+
this._config.modules.configuration.ocpp2_0_1?.getBaseReportOnPending) {
|
|
192
|
+
// Remove Notify Report from blacklist
|
|
193
|
+
await this._cache.remove(OCPP2_0_1_CallAction.NotifyReport, stationId);
|
|
194
|
+
const getBaseReportRequest = await this._bootService.createGetBaseReportRequest(stationId, this._config.maxCachingSeconds);
|
|
195
|
+
const getBaseReportConfirmation = await this.sendCall(stationId, tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetBaseReport, getBaseReportRequest);
|
|
196
|
+
await this._bootService.confirmGetBaseReportSuccess(stationId, getBaseReportRequest.requestId.toString(), getBaseReportConfirmation, this._config.maxCachingSeconds);
|
|
197
|
+
// Make sure GetBaseReport doesn't re-trigger on next boot attempt
|
|
198
|
+
bootConfigDbEntity.getBaseReportOnPending = false;
|
|
199
|
+
await bootConfigDbEntity.save();
|
|
200
|
+
}
|
|
201
|
+
// SetVariables
|
|
202
|
+
let rejectedSetVariable = false;
|
|
203
|
+
let rebootSetVariable = false;
|
|
204
|
+
if (bootConfigDbEntity.pendingBootSetVariables &&
|
|
205
|
+
bootConfigDbEntity.pendingBootSetVariables.length > 0) {
|
|
206
|
+
bootConfigDbEntity.variablesRejectedOnLastBoot = [];
|
|
207
|
+
let setVariableData = await this._deviceModelRepository.readAllSetVariableByStationId(tenantId, stationId);
|
|
208
|
+
// If ItemsPerMessageSetVariables not set, send all variables at once
|
|
209
|
+
const itemsPerMessageSetVariables = (await this._deviceModelService.getItemsPerMessageSetVariablesByStationId(tenantId, stationId)) ?? setVariableData.length;
|
|
210
|
+
while (setVariableData.length > 0) {
|
|
211
|
+
const correlationId = uuidv4();
|
|
212
|
+
const cacheCallbackPromise = this._cache.onChange(correlationId, this._config.maxCachingSeconds, stationId); // x2 fudge factor for any network lag
|
|
213
|
+
await this.sendCall(stationId, tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.SetVariables, {
|
|
214
|
+
setVariableData: setVariableData.slice(0, itemsPerMessageSetVariables),
|
|
215
|
+
}, undefined, correlationId);
|
|
216
|
+
setVariableData = setVariableData.slice(itemsPerMessageSetVariables);
|
|
217
|
+
const setVariablesResponseJsonString = await cacheCallbackPromise;
|
|
218
|
+
if (setVariablesResponseJsonString) {
|
|
219
|
+
if (rejectedSetVariable && rebootSetVariable) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const setVariablesResponse = JSON.parse(setVariablesResponseJsonString);
|
|
223
|
+
setVariablesResponse.setVariableResult.forEach((result) => {
|
|
224
|
+
if (result.attributeStatus === OCPP2_0_1.SetVariableStatusEnumType.Rejected) {
|
|
225
|
+
rejectedSetVariable = true;
|
|
226
|
+
}
|
|
227
|
+
else if (result.attributeStatus === OCPP2_0_1.SetVariableStatusEnumType.RebootRequired) {
|
|
228
|
+
rebootSetVariable = true;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
throw new Error('SetVariables response not found');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const doNotBootWithRejectedVariables = !(bootConfigDbEntity.bootWithRejectedVariables ??
|
|
237
|
+
this._config.modules.configuration.ocpp2_0_1?.bootWithRejectedVariables);
|
|
238
|
+
if (rejectedSetVariable && doNotBootWithRejectedVariables) {
|
|
239
|
+
bootConfigDbEntity.status = OCPP2_0_1.RegistrationStatusEnumType.Rejected;
|
|
240
|
+
await bootConfigDbEntity.save();
|
|
241
|
+
// No more to do.
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (this._config.modules.configuration.ocpp2_0_1?.autoAccept) {
|
|
246
|
+
// Update boot config with status accepted
|
|
247
|
+
// TODO: Determine how/if StatusInfo should be generated
|
|
248
|
+
bootConfigDbEntity.status = OCPP2_0_1.RegistrationStatusEnumType.Accepted;
|
|
249
|
+
await bootConfigDbEntity.save();
|
|
250
|
+
}
|
|
251
|
+
if (rebootSetVariable) {
|
|
252
|
+
// Charger SHALL not be in a transaction as it has not yet successfully booted, therefore it is appropriate to send an Immediate Reset
|
|
253
|
+
await this.sendCall(stationId, tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.Reset, {
|
|
254
|
+
type: OCPP2_0_1.ResetEnumType.Immediate,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
// We could trigger the new boot immediately rather than wait for the retry, as nothing more now needs to be done.
|
|
259
|
+
// However, B02.FR.02 - Spec allows for TriggerMessageRequest - OCTT fails over trigger
|
|
260
|
+
// Commenting out until OCTT behavior changes.
|
|
261
|
+
// this.sendCall(stationId, tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.TriggerMessage,
|
|
262
|
+
// { requestedMessage: MessageTriggerEnumType.BootNotification } as TriggerMessageRequest);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async _handleHeartbeat(message, props) {
|
|
266
|
+
this._logger.debug('Heartbeat received:', message, props);
|
|
267
|
+
// Create response
|
|
268
|
+
const response = {
|
|
269
|
+
currentTime: new Date().toISOString(),
|
|
270
|
+
};
|
|
271
|
+
const messageConfirmation = await this.sendCallResultWithMessage(message, response);
|
|
272
|
+
this._logger.debug('Heartbeat response sent: ', messageConfirmation);
|
|
273
|
+
}
|
|
274
|
+
async _handleNotifyDisplayMessages(message, props) {
|
|
275
|
+
// Validate requestId was provided in a previous GetDisplayMessagesRequest
|
|
276
|
+
const requestId = message.payload.requestId;
|
|
277
|
+
const previousRequest = await this._ocppMessageRepository.readAllByQuery(message.context.tenantId, {
|
|
278
|
+
where: {
|
|
279
|
+
tenantId: message.context.tenantId,
|
|
280
|
+
stationId: message.context.stationId,
|
|
281
|
+
action: OCPP2_0_1_CallAction.GetDisplayMessages,
|
|
282
|
+
message: {
|
|
283
|
+
requestId: requestId,
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
limit: 1,
|
|
287
|
+
}, Namespace.OCPPMessage);
|
|
288
|
+
if (!previousRequest || previousRequest.length === 0) {
|
|
289
|
+
await this.sendCallErrorWithMessage(message, new OcppError(message.context.correlationId, ErrorCode.PropertyConstraintViolation, 'RequestId was not provided in a GetDisplayMessagesRequest.'));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const messageInfoTypes = message.payload.messageInfo;
|
|
293
|
+
// Validate message content for each messageInfo item
|
|
294
|
+
if (messageInfoTypes && messageInfoTypes.length > 0) {
|
|
295
|
+
const validationErrors = [];
|
|
296
|
+
for (const messageInfoType of messageInfoTypes) {
|
|
297
|
+
const validationResult = validateMessageContentType(messageInfoType.message);
|
|
298
|
+
if (!validationResult.isValid) {
|
|
299
|
+
validationErrors.push(`Message ID ${messageInfoType.id}: ${validationResult.errorMessage}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (validationErrors.length > 0) {
|
|
303
|
+
const errorMessage = `Message content validation failed: ${validationErrors.join('; ')}`;
|
|
304
|
+
const error = new OcppError(message.context.correlationId, ErrorCode.PropertyConstraintViolation, errorMessage);
|
|
305
|
+
await this.sendCallErrorWithMessage(message, error);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
this._logger.debug('NotifyDisplayMessages received: ', message, props);
|
|
310
|
+
const tenantId = message.context.tenantId;
|
|
311
|
+
for (const messageInfoType of messageInfoTypes) {
|
|
312
|
+
let componentId;
|
|
313
|
+
if (messageInfoType.display) {
|
|
314
|
+
const component = await this._deviceModelRepository.findOrCreateEvseAndComponent(tenantId, messageInfoType.display, message.context.stationId);
|
|
315
|
+
componentId = component.id;
|
|
316
|
+
}
|
|
317
|
+
await this._messageInfoRepository.createOrUpdateByMessageInfoTypeAndStationId(tenantId, messageInfoType, message.context.stationId, componentId);
|
|
318
|
+
}
|
|
319
|
+
// Create response
|
|
320
|
+
const response = {};
|
|
321
|
+
const messageConfirmation = await this.sendCallResultWithMessage(message, response);
|
|
322
|
+
this._logger.debug('NotifyDisplayMessages response sent: ', messageConfirmation);
|
|
323
|
+
}
|
|
324
|
+
async _handleFirmwareStatusNotification(message, props) {
|
|
325
|
+
this._logger.debug('FirmwareStatusNotification received:', message, props);
|
|
326
|
+
// TODO: FirmwareStatusNotification is usually triggered. Ideally, it should be sent to the callbackUrl from the message api that sent the trigger message
|
|
327
|
+
// Validate requestId requirement
|
|
328
|
+
// requestId is mandatory unless message was triggered by TriggerMessageRequest AND no firmware update is ongoing
|
|
329
|
+
if (!message.payload.requestId) {
|
|
330
|
+
await this.sendCallErrorWithMessage(message, new OcppError(message.context.correlationId, ErrorCode.OccurrenceConstraintViolation, 'RequestId is required.'));
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
// Create response
|
|
334
|
+
const response = {};
|
|
335
|
+
const messageConfirmation = await this.sendCallResultWithMessage(message, response);
|
|
336
|
+
this._logger.debug('FirmwareStatusNotification response sent: ', messageConfirmation);
|
|
337
|
+
}
|
|
338
|
+
async _handleDataTransfer(message, props) {
|
|
339
|
+
this._logger.debug('DataTransfer received:', message, props);
|
|
340
|
+
// Create response
|
|
341
|
+
const response = {
|
|
342
|
+
status: OCPP2_0_1.DataTransferStatusEnumType.Rejected,
|
|
343
|
+
statusInfo: { reasonCode: ErrorCode.NotImplemented },
|
|
344
|
+
};
|
|
345
|
+
const messageConfirmation = await this.sendCallResultWithMessage(message, response);
|
|
346
|
+
this._logger.debug('DataTransfer response sent: ', messageConfirmation);
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Handle OCPP 2.0.1 responses
|
|
350
|
+
*/
|
|
351
|
+
_handleChangeAvailability(message, props) {
|
|
352
|
+
this._logger.debug('ChangeAvailability response received:', message, props);
|
|
353
|
+
}
|
|
354
|
+
async _handleSetNetworkProfile(message, props) {
|
|
355
|
+
this._logger.debug('SetNetworkProfile response received:', message, props);
|
|
356
|
+
if (message.payload.status == OCPP2_0_1.SetNetworkProfileStatusEnumType.Accepted) {
|
|
357
|
+
const setNetworkProfile = await SetNetworkProfile.findOne({
|
|
358
|
+
where: { correlationId: message.context.correlationId },
|
|
359
|
+
});
|
|
360
|
+
if (setNetworkProfile) {
|
|
361
|
+
const serverNetworkProfile = await ServerNetworkProfile.findByPk(setNetworkProfile.websocketServerConfigId);
|
|
362
|
+
if (serverNetworkProfile) {
|
|
363
|
+
const chargingStation = await ChargingStation.findByPk(message.context.stationId);
|
|
364
|
+
if (chargingStation) {
|
|
365
|
+
const [chargingStationNetworkProfile] = await ChargingStationNetworkProfile.findOrBuild({
|
|
366
|
+
where: {
|
|
367
|
+
stationId: chargingStation.id,
|
|
368
|
+
configurationSlot: setNetworkProfile.configurationSlot,
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
chargingStationNetworkProfile.websocketServerConfigId =
|
|
372
|
+
setNetworkProfile.websocketServerConfigId;
|
|
373
|
+
chargingStationNetworkProfile.setNetworkProfileId = setNetworkProfile.id;
|
|
374
|
+
await chargingStationNetworkProfile.save();
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
_handleGetDisplayMessages(message, props) {
|
|
381
|
+
this._logger.debug('GetDisplayMessages response received:', message, props);
|
|
382
|
+
}
|
|
383
|
+
async _handleSetDisplayMessage(message, props) {
|
|
384
|
+
this._logger.debug('SetDisplayMessage response received:', message, props);
|
|
385
|
+
const status = message.payload.status;
|
|
386
|
+
// when charger station accepts the set message info request
|
|
387
|
+
// we trigger a get all display messages request to update stored message info in db
|
|
388
|
+
if (status === OCPP2_0_1.DisplayMessageStatusEnumType.Accepted) {
|
|
389
|
+
await this._messageInfoRepository.deactivateAllByStationId(message.context.tenantId, message.context.stationId);
|
|
390
|
+
await this.sendCall(message.context.stationId, message.context.tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetDisplayMessages, {
|
|
391
|
+
requestId: await this._idGenerator.generateRequestId(message.context.tenantId, message.context.stationId, ChargingStationSequenceTypeEnum.getDisplayMessages),
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
_handlePublishFirmware(message, props) {
|
|
396
|
+
this._logger.debug('PublishFirmware response received:', message, props);
|
|
397
|
+
}
|
|
398
|
+
_handleUnpublishFirmware(message, props) {
|
|
399
|
+
this._logger.debug('UnpublishFirmware response received:', message, props);
|
|
400
|
+
}
|
|
401
|
+
_handleUpdateFirmware(message, props) {
|
|
402
|
+
this._logger.debug('UpdateFirmware response received:', message, props);
|
|
403
|
+
}
|
|
404
|
+
_handleReset(message, props) {
|
|
405
|
+
this._logger.debug('Reset response received:', message, props);
|
|
406
|
+
}
|
|
407
|
+
_handleTriggerMessage(message, props) {
|
|
408
|
+
this._logger.debug('TriggerMessage response received:', message, props);
|
|
409
|
+
}
|
|
410
|
+
async _handleClearDisplayMessage(message, props) {
|
|
411
|
+
this._logger.debug('ClearDisplayMessage response received:', message, props);
|
|
412
|
+
const status = message.payload.status;
|
|
413
|
+
// when charger station accepts the clear message info request
|
|
414
|
+
// we trigger a get all display messages request to update stored message info in db
|
|
415
|
+
if (status === OCPP2_0_1.ClearMessageStatusEnumType.Accepted) {
|
|
416
|
+
await this._messageInfoRepository.deactivateAllByStationId(message.context.tenantId, message.context.stationId);
|
|
417
|
+
await this.sendCall(message.context.stationId, message.context.tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetDisplayMessages, {
|
|
418
|
+
requestId: await this._idGenerator.generateRequestId(message.context.tenantId, message.context.stationId, ChargingStationSequenceTypeEnum.getDisplayMessages),
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Handle OCPP 1.6 requests
|
|
424
|
+
*/
|
|
425
|
+
async _handle16Heartbeat(message, props) {
|
|
426
|
+
this._logger.debug('Heartbeat received:', message, props);
|
|
427
|
+
const response = {
|
|
428
|
+
currentTime: new Date().toISOString(),
|
|
429
|
+
};
|
|
430
|
+
const messageConfirmation = await this.sendCallResultWithMessage(message, response);
|
|
431
|
+
this._logger.debug('Heartbeat response sent: ', messageConfirmation);
|
|
432
|
+
}
|
|
433
|
+
async _handleOcpp16BootNotification(message, props) {
|
|
434
|
+
this._logger.debug('OCPP 1.6 BootNotification request received:', message, props);
|
|
435
|
+
const stationId = message.context.stationId;
|
|
436
|
+
const tenantId = message.context.tenantId;
|
|
437
|
+
const request = message.payload;
|
|
438
|
+
// 1. Send BootNotification response
|
|
439
|
+
// Create BootNotification response
|
|
440
|
+
const bootNotificationResponse = await this._bootService.createOcpp16BootNotificationResponse(tenantId, stationId);
|
|
441
|
+
// Check cached boot status for charger. Only Pending and Rejected statuses are cached.
|
|
442
|
+
const cachedBootStatus = await this._cache.get(BOOT_STATUS, stationId);
|
|
443
|
+
// Blacklist or whitelist charger actions
|
|
444
|
+
await this._bootService.cacheOcpp16ChargerActionsPermissions(stationId, cachedBootStatus, bootNotificationResponse.status);
|
|
445
|
+
// Send BootNotification response
|
|
446
|
+
const bootNotificationResponseMessageConfirmation = await this.sendCallResultWithMessage(message, bootNotificationResponse);
|
|
447
|
+
// Create or update charging station
|
|
448
|
+
this._logger.debug(`Creating or updating charging station: ${stationId}`);
|
|
449
|
+
this._locationRepository
|
|
450
|
+
.createOrUpdateChargingStation(tenantId, ChargingStation.build({
|
|
451
|
+
tenantId,
|
|
452
|
+
id: stationId,
|
|
453
|
+
chargePointVendor: request.chargePointVendor,
|
|
454
|
+
chargePointModel: request.chargePointModel,
|
|
455
|
+
chargePointSerialNumber: request.chargePointSerialNumber,
|
|
456
|
+
chargeBoxSerialNumber: request.chargeBoxSerialNumber,
|
|
457
|
+
firmwareVersion: request.firmwareVersion,
|
|
458
|
+
iccid: request.iccid,
|
|
459
|
+
imsi: request.imsi,
|
|
460
|
+
meterType: request.meterType,
|
|
461
|
+
meterSerialNumber: request.meterSerialNumber,
|
|
462
|
+
}))
|
|
463
|
+
.then()
|
|
464
|
+
.catch((error) => {
|
|
465
|
+
this._logger.error(`Error updating station ${stationId} with boot info:`, error);
|
|
466
|
+
});
|
|
467
|
+
// Check if response was successful
|
|
468
|
+
if (!bootNotificationResponseMessageConfirmation.success) {
|
|
469
|
+
throw new Error('Send BootNotification response failed: ' + bootNotificationResponseMessageConfirmation);
|
|
470
|
+
}
|
|
471
|
+
// 2. Update boot status in cache and db entity
|
|
472
|
+
// Cache boot status for charger if (not accepted) and ((not already cached) or (different status from cached status)).
|
|
473
|
+
if (bootNotificationResponse.status !== OCPP1_6.BootNotificationResponseStatus.Accepted &&
|
|
474
|
+
(!cachedBootStatus || bootNotificationResponse.status !== cachedBootStatus)) {
|
|
475
|
+
await this._cache.set(BOOT_STATUS, bootNotificationResponse.status, stationId);
|
|
476
|
+
}
|
|
477
|
+
// Update boot with details of most recently sent BootNotificationResponse
|
|
478
|
+
const bootEntity = await this._bootService.updateOcpp16BootConfig(bootNotificationResponse, tenantId, stationId);
|
|
479
|
+
// 3. Sync configurations
|
|
480
|
+
// If boot notification is not pending, do not start configuration.
|
|
481
|
+
// If cached boot status is not null and pending, configuration is already in progress - do not start configuration again.
|
|
482
|
+
if (bootNotificationResponse.status !== OCPP1_6.BootNotificationResponseStatus.Pending ||
|
|
483
|
+
(cachedBootStatus && cachedBootStatus === OCPP1_6.BootNotificationResponseStatus.Pending)) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
let changeConfigurationsOnPending = false;
|
|
487
|
+
let getConfigurationsOnPending = true;
|
|
488
|
+
// Change Configurations on charging station
|
|
489
|
+
const configurations = await this._changeConfigurationRepository.readAllByQuery(tenantId, {
|
|
490
|
+
where: {
|
|
491
|
+
stationId,
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
// Remove ChangeConfiguration call action from blacklist
|
|
495
|
+
await this._cache.remove(OCPP1_6_CallAction.ChangeConfiguration, stationId);
|
|
496
|
+
// Set each configuration on Charging Station
|
|
497
|
+
for (const config of configurations) {
|
|
498
|
+
const correlationId = uuidv4();
|
|
499
|
+
const cacheCallbackPromise = this._cache.onChange(correlationId, this._config.maxCachingSeconds, stationId);
|
|
500
|
+
const changeConfigurationResponseMessageConfirmation = await this.sendCall(stationId, tenantId, OCPPVersion.OCPP1_6, OCPP1_6_CallAction.ChangeConfiguration, {
|
|
501
|
+
key: config.key,
|
|
502
|
+
value: config.value,
|
|
503
|
+
}, undefined, correlationId);
|
|
504
|
+
if (!changeConfigurationResponseMessageConfirmation.success) {
|
|
505
|
+
changeConfigurationsOnPending = true;
|
|
506
|
+
}
|
|
507
|
+
// wait before sending next call
|
|
508
|
+
await cacheCallbackPromise;
|
|
509
|
+
}
|
|
510
|
+
// Get Configurations from charging station
|
|
511
|
+
// Remove GetConfiguration call action from blacklist
|
|
512
|
+
await this._cache.remove(OCPP1_6_CallAction.GetConfiguration, stationId);
|
|
513
|
+
// Send GetConfiguration request to charger
|
|
514
|
+
const getConfigurationResponseMessageConfirmation = await this.sendCall(stationId, tenantId, OCPPVersion.OCPP1_6, OCPP1_6_CallAction.GetConfiguration, {});
|
|
515
|
+
if (getConfigurationResponseMessageConfirmation.success) {
|
|
516
|
+
getConfigurationsOnPending = false;
|
|
517
|
+
}
|
|
518
|
+
// Update configuration related fields on boot entity
|
|
519
|
+
await this._bootRepository.updateByKey(tenantId, {
|
|
520
|
+
changeConfigurationsOnPending,
|
|
521
|
+
getConfigurationsOnPending,
|
|
522
|
+
}, bootEntity.id);
|
|
523
|
+
// 4. Trigger another boot when pending
|
|
524
|
+
await this._cache.remove(OCPP1_6_CallAction.TriggerMessage, stationId);
|
|
525
|
+
await this.sendCall(stationId, tenantId, OCPPVersion.OCPP1_6, OCPP1_6_CallAction.TriggerMessage, {
|
|
526
|
+
requestedMessage: OCPP1_6.TriggerMessageRequestRequestedMessage.BootNotification,
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Handle OCPP 1.6 response
|
|
531
|
+
*/
|
|
532
|
+
async _handleOcpp16GetConfiguration(message, props) {
|
|
533
|
+
this._logger.debug('OCPP 1.6 GetConfiguration response received:', message, props);
|
|
534
|
+
const tenantId = message.context.tenantId;
|
|
535
|
+
const stationId = message.context.stationId;
|
|
536
|
+
const configurations = message.payload.configurationKey;
|
|
537
|
+
if (configurations && configurations.length > 0) {
|
|
538
|
+
for (const config of configurations) {
|
|
539
|
+
if (config.key) {
|
|
540
|
+
await this._changeConfigurationRepository.createOrUpdateChangeConfiguration(tenantId, {
|
|
541
|
+
stationId,
|
|
542
|
+
key: config.key,
|
|
543
|
+
value: config.value,
|
|
544
|
+
readonly: config.readonly,
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
async _handleOcpp16ChangeConfiguration(message, props) {
|
|
551
|
+
this._logger.debug('OCPP 1.6 ChangeConfiguration response received:', message, props);
|
|
552
|
+
const tenantId = message.context.tenantId;
|
|
553
|
+
const stationId = message.context.stationId;
|
|
554
|
+
const correlationId = message.context.correlationId;
|
|
555
|
+
const request = await this._ocppMessageRepository.readOnlyOneByQuery(tenantId, {
|
|
556
|
+
where: {
|
|
557
|
+
stationId,
|
|
558
|
+
correlationId,
|
|
559
|
+
origin: MessageOrigin.ChargingStationManagementSystem,
|
|
560
|
+
},
|
|
561
|
+
});
|
|
562
|
+
if (!request) {
|
|
563
|
+
this._logger.error(`No valid ChangeConfigurationRequest found for correlationId ${correlationId}`);
|
|
564
|
+
}
|
|
565
|
+
const status = message.payload.status;
|
|
566
|
+
const key = request?.message[3].key;
|
|
567
|
+
const value = request?.message[3].value;
|
|
568
|
+
if (status == OCPP1_6.ChangeConfigurationResponseStatus.Rejected ||
|
|
569
|
+
status == OCPP1_6.ChangeConfigurationResponseStatus.NotSupported) {
|
|
570
|
+
this._logger.warn(`Attempted ChangeConfiguration ${correlationId} for ${key}:${value} unsuccessful with status ${status}`);
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
const config = await this._changeConfigurationRepository.createOrUpdateChangeConfiguration(tenantId, {
|
|
575
|
+
tenantId,
|
|
576
|
+
stationId,
|
|
577
|
+
key,
|
|
578
|
+
value,
|
|
579
|
+
});
|
|
580
|
+
if (!config) {
|
|
581
|
+
this._logger.error(`Failed to create or update configuration ${key}:${value} on ${stationId}`);
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
this._logger.debug(`Updated changeConfiguration ${key}:${value}`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
_handleOcpp16TriggerMessage(message, props) {
|
|
589
|
+
this._logger.debug('TriggerMessage response received:', message, props);
|
|
590
|
+
if (message.payload.status !== OCPP1_6.TriggerMessageResponseStatus.Accepted) {
|
|
591
|
+
this._logger.error('TriggerMessage failed with status:', message);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
_handle16Reset(message, props) {
|
|
595
|
+
this._logger.debug('Reset response received:', message, props);
|
|
596
|
+
}
|
|
597
|
+
_handleOcpp16ChangeAvailability(message, props) {
|
|
598
|
+
this._logger.debug('ChangeAvailability response received:', message, props);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
__decorate([
|
|
602
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.BootNotification),
|
|
603
|
+
__metadata("design:type", Function),
|
|
604
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
605
|
+
__metadata("design:returntype", Promise)
|
|
606
|
+
], ConfigurationModule.prototype, "_handleBootNotification", null);
|
|
607
|
+
__decorate([
|
|
608
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.Heartbeat),
|
|
609
|
+
__metadata("design:type", Function),
|
|
610
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
611
|
+
__metadata("design:returntype", Promise)
|
|
612
|
+
], ConfigurationModule.prototype, "_handleHeartbeat", null);
|
|
613
|
+
__decorate([
|
|
614
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.NotifyDisplayMessages),
|
|
615
|
+
__metadata("design:type", Function),
|
|
616
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
617
|
+
__metadata("design:returntype", Promise)
|
|
618
|
+
], ConfigurationModule.prototype, "_handleNotifyDisplayMessages", null);
|
|
619
|
+
__decorate([
|
|
620
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.FirmwareStatusNotification),
|
|
621
|
+
__metadata("design:type", Function),
|
|
622
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
623
|
+
__metadata("design:returntype", Promise)
|
|
624
|
+
], ConfigurationModule.prototype, "_handleFirmwareStatusNotification", null);
|
|
625
|
+
__decorate([
|
|
626
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.DataTransfer),
|
|
627
|
+
__metadata("design:type", Function),
|
|
628
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
629
|
+
__metadata("design:returntype", Promise)
|
|
630
|
+
], ConfigurationModule.prototype, "_handleDataTransfer", null);
|
|
631
|
+
__decorate([
|
|
632
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.ChangeAvailability),
|
|
633
|
+
__metadata("design:type", Function),
|
|
634
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
635
|
+
__metadata("design:returntype", void 0)
|
|
636
|
+
], ConfigurationModule.prototype, "_handleChangeAvailability", null);
|
|
637
|
+
__decorate([
|
|
638
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.SetNetworkProfile),
|
|
639
|
+
__metadata("design:type", Function),
|
|
640
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
641
|
+
__metadata("design:returntype", Promise)
|
|
642
|
+
], ConfigurationModule.prototype, "_handleSetNetworkProfile", null);
|
|
643
|
+
__decorate([
|
|
644
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.GetDisplayMessages),
|
|
645
|
+
__metadata("design:type", Function),
|
|
646
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
647
|
+
__metadata("design:returntype", void 0)
|
|
648
|
+
], ConfigurationModule.prototype, "_handleGetDisplayMessages", null);
|
|
649
|
+
__decorate([
|
|
650
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.SetDisplayMessage),
|
|
651
|
+
__metadata("design:type", Function),
|
|
652
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
653
|
+
__metadata("design:returntype", Promise)
|
|
654
|
+
], ConfigurationModule.prototype, "_handleSetDisplayMessage", null);
|
|
655
|
+
__decorate([
|
|
656
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.PublishFirmware),
|
|
657
|
+
__metadata("design:type", Function),
|
|
658
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
659
|
+
__metadata("design:returntype", void 0)
|
|
660
|
+
], ConfigurationModule.prototype, "_handlePublishFirmware", null);
|
|
661
|
+
__decorate([
|
|
662
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.UnpublishFirmware),
|
|
663
|
+
__metadata("design:type", Function),
|
|
664
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
665
|
+
__metadata("design:returntype", void 0)
|
|
666
|
+
], ConfigurationModule.prototype, "_handleUnpublishFirmware", null);
|
|
667
|
+
__decorate([
|
|
668
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.UpdateFirmware),
|
|
669
|
+
__metadata("design:type", Function),
|
|
670
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
671
|
+
__metadata("design:returntype", void 0)
|
|
672
|
+
], ConfigurationModule.prototype, "_handleUpdateFirmware", null);
|
|
673
|
+
__decorate([
|
|
674
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.Reset),
|
|
675
|
+
__metadata("design:type", Function),
|
|
676
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
677
|
+
__metadata("design:returntype", void 0)
|
|
678
|
+
], ConfigurationModule.prototype, "_handleReset", null);
|
|
679
|
+
__decorate([
|
|
680
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.TriggerMessage),
|
|
681
|
+
__metadata("design:type", Function),
|
|
682
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
683
|
+
__metadata("design:returntype", void 0)
|
|
684
|
+
], ConfigurationModule.prototype, "_handleTriggerMessage", null);
|
|
685
|
+
__decorate([
|
|
686
|
+
AsHandler(OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.ClearDisplayMessage),
|
|
687
|
+
__metadata("design:type", Function),
|
|
688
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
689
|
+
__metadata("design:returntype", Promise)
|
|
690
|
+
], ConfigurationModule.prototype, "_handleClearDisplayMessage", null);
|
|
691
|
+
__decorate([
|
|
692
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.Heartbeat),
|
|
693
|
+
__metadata("design:type", Function),
|
|
694
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
695
|
+
__metadata("design:returntype", Promise)
|
|
696
|
+
], ConfigurationModule.prototype, "_handle16Heartbeat", null);
|
|
697
|
+
__decorate([
|
|
698
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.BootNotification),
|
|
699
|
+
__metadata("design:type", Function),
|
|
700
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
701
|
+
__metadata("design:returntype", Promise)
|
|
702
|
+
], ConfigurationModule.prototype, "_handleOcpp16BootNotification", null);
|
|
703
|
+
__decorate([
|
|
704
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.GetConfiguration),
|
|
705
|
+
__metadata("design:type", Function),
|
|
706
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
707
|
+
__metadata("design:returntype", Promise)
|
|
708
|
+
], ConfigurationModule.prototype, "_handleOcpp16GetConfiguration", null);
|
|
709
|
+
__decorate([
|
|
710
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.ChangeConfiguration),
|
|
711
|
+
__metadata("design:type", Function),
|
|
712
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
713
|
+
__metadata("design:returntype", Promise)
|
|
714
|
+
], ConfigurationModule.prototype, "_handleOcpp16ChangeConfiguration", null);
|
|
715
|
+
__decorate([
|
|
716
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.TriggerMessage),
|
|
717
|
+
__metadata("design:type", Function),
|
|
718
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
719
|
+
__metadata("design:returntype", void 0)
|
|
720
|
+
], ConfigurationModule.prototype, "_handleOcpp16TriggerMessage", null);
|
|
721
|
+
__decorate([
|
|
722
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.Reset),
|
|
723
|
+
__metadata("design:type", Function),
|
|
724
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
725
|
+
__metadata("design:returntype", void 0)
|
|
726
|
+
], ConfigurationModule.prototype, "_handle16Reset", null);
|
|
727
|
+
__decorate([
|
|
728
|
+
AsHandler(OCPPVersion.OCPP1_6, OCPP1_6_CallAction.ChangeAvailability),
|
|
729
|
+
__metadata("design:type", Function),
|
|
730
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
731
|
+
__metadata("design:returntype", void 0)
|
|
732
|
+
], ConfigurationModule.prototype, "_handleOcpp16ChangeAvailability", null);
|
|
733
|
+
//# sourceMappingURL=module.js.map
|