@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.
@@ -0,0 +1,248 @@
1
+ import { Boot, OCPP1_6_Mapper, OCPP2_0_1_Mapper } from '@citrineos/data';
2
+ import { BOOT_STATUS, OCPP1_6, OCPP1_6_CALL_SCHEMA_MAP, OCPP1_6_CallAction, OCPP2_0_1, OCPP2_0_1_CALL_SCHEMA_MAP, OCPP2_0_1_CallAction, } from '@citrineos/base';
3
+ import { Logger } from 'tslog';
4
+ export class BootNotificationService {
5
+ _bootRepository;
6
+ _cache;
7
+ _logger;
8
+ _config;
9
+ constructor(bootRepository, cache, config, logger) {
10
+ this._bootRepository = bootRepository;
11
+ this._cache = cache;
12
+ this._config = config;
13
+ this._logger = logger
14
+ ? logger.getSubLogger({ name: this.constructor.name })
15
+ : new Logger({ name: this.constructor.name });
16
+ }
17
+ determineBootStatus(bootConfig) {
18
+ let bootStatus = bootConfig
19
+ ? OCPP2_0_1_Mapper.BootMapper.toRegistrationStatusEnumType(bootConfig.status)
20
+ : this._config.ocpp2_0_1.unknownChargerStatus;
21
+ if (bootStatus === OCPP2_0_1.RegistrationStatusEnumType.Pending) {
22
+ let needToGetBaseReport = this._config.ocpp2_0_1.getBaseReportOnPending;
23
+ let needToSetVariables = false;
24
+ if (bootConfig) {
25
+ if (bootConfig.getBaseReportOnPending !== undefined &&
26
+ bootConfig.getBaseReportOnPending !== null) {
27
+ needToGetBaseReport = bootConfig.getBaseReportOnPending;
28
+ }
29
+ if (bootConfig.pendingBootSetVariables && bootConfig.pendingBootSetVariables.length > 0) {
30
+ needToSetVariables = true;
31
+ }
32
+ }
33
+ if (!needToGetBaseReport && !needToSetVariables && this._config.ocpp2_0_1.autoAccept) {
34
+ bootStatus = OCPP2_0_1.RegistrationStatusEnumType.Accepted;
35
+ }
36
+ }
37
+ return bootStatus;
38
+ }
39
+ async createBootNotificationResponse(tenantId, stationId) {
40
+ // Unknown chargers, chargers without a BootConfig, will use SystemConfig.unknownChargerStatus for status.
41
+ const bootConfig = await this._bootRepository.readByKey(tenantId, stationId);
42
+ const bootStatus = this.determineBootStatus(bootConfig);
43
+ // When any BootConfig field is not set, the corresponding field on the SystemConfig will be used.
44
+ return {
45
+ currentTime: new Date().toISOString(),
46
+ status: bootStatus,
47
+ statusInfo: OCPP2_0_1_Mapper.BootMapper.toStatusInfo(bootConfig?.statusInfo),
48
+ interval: bootStatus === OCPP2_0_1.RegistrationStatusEnumType.Accepted
49
+ ? bootConfig?.heartbeatInterval || this._config.heartbeatInterval
50
+ : bootConfig?.bootRetryInterval || this._config.bootRetryInterval,
51
+ };
52
+ }
53
+ async updateBootConfig(bootNotificationResponse, tenantId, stationId) {
54
+ let bootConfigDbEntity = await this._bootRepository.readByKey(tenantId, stationId);
55
+ if (!bootConfigDbEntity) {
56
+ const unknownChargerBootConfig = {
57
+ status: bootNotificationResponse.status,
58
+ statusInfo: bootNotificationResponse.statusInfo,
59
+ };
60
+ bootConfigDbEntity = await this._bootRepository.createOrUpdateByKey(tenantId, unknownChargerBootConfig, stationId);
61
+ }
62
+ if (!bootConfigDbEntity) {
63
+ throw new Error('Unable to create/update BootConfig...');
64
+ }
65
+ else {
66
+ bootConfigDbEntity.lastBootTime = bootNotificationResponse.currentTime;
67
+ await bootConfigDbEntity.save();
68
+ }
69
+ return bootConfigDbEntity;
70
+ }
71
+ /**
72
+ * Determines whether to blacklist or whitelist charger actions based on its boot status.
73
+ *
74
+ * If the new boot is accepted and the charger actions were previously blacklisted, then whitelist the charger actions.
75
+ * If the new boot is not accepted and charger actions were previously whitelisted, then blacklist the charger actions.
76
+ *
77
+ * @param stationId
78
+ * @param cachedBootStatus
79
+ * @param bootNotificationResponseStatus
80
+ */
81
+ async cacheChargerActionsPermissions(stationId, cachedBootStatus, bootNotificationResponseStatus) {
82
+ // New boot status is Accepted and cachedBootStatus exists (meaning there was a previous Rejected or Pending boot)
83
+ if (bootNotificationResponseStatus === OCPP2_0_1.RegistrationStatusEnumType.Accepted) {
84
+ if (cachedBootStatus) {
85
+ // Undo blacklisting of charger-originated actions
86
+ const promises = Array.from(OCPP2_0_1_CALL_SCHEMA_MAP).map(async ([action]) => {
87
+ if (action !== OCPP2_0_1_CallAction.BootNotification) {
88
+ return this._cache.remove(action, stationId);
89
+ }
90
+ });
91
+ await Promise.all(promises);
92
+ // Remove cached boot status
93
+ await this._cache.remove(BOOT_STATUS, stationId);
94
+ this._logger.debug('Cached boot status removed: ', cachedBootStatus);
95
+ }
96
+ }
97
+ else if (!cachedBootStatus) {
98
+ // Status is not Accepted; i.e. Status is Rejected or Pending.
99
+ // Cached boot status for charger did not exist; i.e. this is the first BootNotificationResponse to be Rejected or Pending.
100
+ // Blacklist all charger-originated actions except BootNotification
101
+ // GetReport messages will need to un-blacklist NotifyReport
102
+ // TriggerMessage will need to un-blacklist the message it triggers
103
+ const promises = Array.from(OCPP2_0_1_CALL_SCHEMA_MAP).map(async ([action]) => {
104
+ if (action !== OCPP2_0_1_CallAction.BootNotification) {
105
+ return this._cache.set(action, 'blacklisted', stationId);
106
+ }
107
+ });
108
+ await Promise.all(promises);
109
+ }
110
+ }
111
+ async createGetBaseReportRequest(stationId, maxCachingSeconds) {
112
+ // OCTT tool does not meet B07.FR.04; instead always sends requestId === 0
113
+ // Commenting out this line, using requestId === 0 until fixed (10/26/2023)
114
+ // const requestId = Math.floor(Math.random() * ConfigurationModule.GET_BASE_REPORT_REQUEST_ID_MAX);
115
+ const requestId = 0;
116
+ await this._cache.set(requestId.toString(), 'ongoing', stationId, maxCachingSeconds);
117
+ return {
118
+ requestId: requestId,
119
+ reportBase: OCPP2_0_1.ReportBaseEnumType.FullInventory,
120
+ };
121
+ }
122
+ /**
123
+ * Based on the GetBaseReportMessageConfirmation, checks the cache to ensure GetBaseReport truly succeeded.
124
+ * If GetBaseReport did not succeed, this method will throw. Otherwise, it will finish without throwing.
125
+ *
126
+ * @param stationId
127
+ * @param requestId
128
+ * @param getBaseReportMessageConfirmation
129
+ * @param maxCachingSeconds
130
+ */
131
+ async confirmGetBaseReportSuccess(stationId, requestId, getBaseReportMessageConfirmation, maxCachingSeconds) {
132
+ if (getBaseReportMessageConfirmation.success) {
133
+ this._logger.debug(`GetBaseReport successfully sent to charger: ${getBaseReportMessageConfirmation}`);
134
+ // Wait for GetBaseReport to complete
135
+ let getBaseReportCacheValue = await this._cache.onChange(requestId, maxCachingSeconds, stationId);
136
+ while (getBaseReportCacheValue === 'ongoing') {
137
+ getBaseReportCacheValue = await this._cache.onChange(requestId, maxCachingSeconds, stationId);
138
+ }
139
+ if (getBaseReportCacheValue === 'complete') {
140
+ this._logger.debug('GetBaseReport process successful.'); // All NotifyReports have been processed
141
+ }
142
+ else {
143
+ throw new Error('GetBaseReport process failed--message timed out without a response.');
144
+ }
145
+ }
146
+ else {
147
+ throw new Error(`GetBaseReport failed: ${JSON.stringify(getBaseReportMessageConfirmation)}`);
148
+ }
149
+ }
150
+ /**
151
+ * Methods for OCPP 1.6
152
+ */
153
+ determineOcpp16BootStatus(bootConfig) {
154
+ let bootStatus = bootConfig
155
+ ? OCPP1_6_Mapper.BootMapper.toRegistrationStatusEnumType(bootConfig.status)
156
+ : this._config.ocpp1_6.unknownChargerStatus;
157
+ if (bootStatus === OCPP1_6.BootNotificationResponseStatus.Pending) {
158
+ let needToGetConfigurations = true;
159
+ let needToChangeConfigurations = true;
160
+ if (bootConfig) {
161
+ if (bootConfig.getConfigurationsOnPending !== undefined &&
162
+ bootConfig.getConfigurationsOnPending !== null) {
163
+ needToGetConfigurations = bootConfig.getConfigurationsOnPending;
164
+ }
165
+ if (bootConfig.changeConfigurationsOnPending !== undefined &&
166
+ bootConfig.changeConfigurationsOnPending !== null) {
167
+ needToChangeConfigurations = bootConfig.changeConfigurationsOnPending;
168
+ }
169
+ }
170
+ if (!needToGetConfigurations && !needToChangeConfigurations) {
171
+ bootStatus = OCPP1_6.BootNotificationResponseStatus.Accepted;
172
+ }
173
+ }
174
+ return bootStatus;
175
+ }
176
+ async createOcpp16BootNotificationResponse(tenantId, stationId) {
177
+ const boot = await this._bootRepository.readByKey(tenantId, stationId);
178
+ const status = this.determineOcpp16BootStatus(boot);
179
+ return {
180
+ currentTime: new Date().toISOString(),
181
+ status,
182
+ interval: status === OCPP1_6.BootNotificationResponseStatus.Accepted
183
+ ? boot?.heartbeatInterval || this._config.heartbeatInterval
184
+ : boot?.bootRetryInterval || this._config.bootRetryInterval,
185
+ };
186
+ }
187
+ /**
188
+ * Determines whether to blacklist or whitelist charger actions based on its boot status.
189
+ *
190
+ * If the new boot is accepted and the charger actions were previously blacklisted, then whitelist the charger actions.
191
+ * If the new boot is not accepted and charger actions were previously whitelisted, then blacklist the charger actions.
192
+ *
193
+ * @param stationId
194
+ * @param cachedBootStatus
195
+ * @param bootNotificationResponseStatus
196
+ */
197
+ async cacheOcpp16ChargerActionsPermissions(stationId, cachedBootStatus, bootNotificationResponseStatus) {
198
+ // New boot status is Accepted and cachedBootStatus exists (meaning there was a previous Rejected or Pending boot)
199
+ if (bootNotificationResponseStatus === OCPP1_6.BootNotificationResponseStatus.Accepted) {
200
+ if (cachedBootStatus) {
201
+ // Undo blacklisting of charger-originated actions
202
+ const promises = Array.from(OCPP1_6_CALL_SCHEMA_MAP).map(async ([action]) => {
203
+ if (action !== OCPP1_6_CallAction.BootNotification) {
204
+ return this._cache.remove(action, stationId);
205
+ }
206
+ });
207
+ await Promise.all(promises);
208
+ // Remove cached boot status
209
+ await this._cache.remove(BOOT_STATUS, stationId);
210
+ this._logger.debug(`Cached boot status ${cachedBootStatus} removed for station ${stationId}.`);
211
+ }
212
+ }
213
+ else if (!cachedBootStatus) {
214
+ // Status is not Accepted; i.e. Status is Rejected or Pending.
215
+ // Cached boot status for charger did not exist; i.e. this is the first BootNotificationResponse to be Rejected or Pending.
216
+ // Blacklist all charger-originated actions except BootNotification
217
+ // ChangeConfiguration, GetConfiguration and TriggerMessage will need to un-blacklist the message it triggers
218
+ const promises = Array.from(OCPP1_6_CALL_SCHEMA_MAP).map(async ([action]) => {
219
+ if (action !== OCPP1_6_CallAction.BootNotification) {
220
+ return this._cache.set(action, 'blacklisted', stationId);
221
+ }
222
+ });
223
+ await Promise.all(promises);
224
+ }
225
+ }
226
+ async updateOcpp16BootConfig(response, tenantId, stationId) {
227
+ const heartbeatInterval = response.status === OCPP1_6.BootNotificationResponseStatus.Accepted
228
+ ? response.interval
229
+ : undefined;
230
+ const bootRetryInterval = response.status !== OCPP1_6.BootNotificationResponseStatus.Accepted
231
+ ? response.interval
232
+ : undefined;
233
+ const unknownChargerBootConfig = {
234
+ status: response.status,
235
+ heartbeatInterval,
236
+ bootRetryInterval,
237
+ };
238
+ let bootConfigDbEntity = await this._bootRepository.createOrUpdateByKey(tenantId, unknownChargerBootConfig, stationId);
239
+ if (bootConfigDbEntity) {
240
+ bootConfigDbEntity = await this._bootRepository.updateLastBootTimeByKey(tenantId, response.currentTime, stationId);
241
+ }
242
+ if (!bootConfigDbEntity) {
243
+ throw new Error('Unable to create/update BootConfig...');
244
+ }
245
+ return bootConfigDbEntity;
246
+ }
247
+ }
248
+ //# sourceMappingURL=BootNotificationService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BootNotificationService.js","sourceRoot":"","sources":["../../src/module/BootNotificationService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { FastifyInstance, FastifyRequest } from 'fastify';
2
+ import type { ILogObj } from 'tslog';
3
+ import { Logger } from 'tslog';
4
+ import type { IConfigurationModuleApi } from './interface.js';
5
+ import { ConfigurationModule } from './module.js';
6
+ import type { BootConfig, IMessageConfirmation, UpdateChargingStationPasswordRequest } from '@citrineos/base';
7
+ import { AbstractModuleApi, Namespace, OCPP1_6_Namespace, OCPP2_0_1, OCPP2_0_1_Namespace } from '@citrineos/base';
8
+ import type { ChargingStationKeyQuerystring, NetworkProfileDeleteQuerystring, NetworkProfileQuerystring, UpdateChargingStationPasswordQueryString } from '@citrineos/data';
9
+ import { Boot, ChargingStationNetworkProfile } from '@citrineos/data';
10
+ /**
11
+ * Server API for the Configuration component.
12
+ */
13
+ export declare class ConfigurationDataApi extends AbstractModuleApi<ConfigurationModule> implements IConfigurationModuleApi {
14
+ /**
15
+ * Constructor for the class.
16
+ *
17
+ * @param {ConfigurationModule} ConfigurationComponent - The Configuration component.
18
+ * @param {FastifyInstance} server - The server instance.
19
+ * @param {Logger<ILogObj>} [logger] - Optional logger instance.
20
+ */
21
+ constructor(ConfigurationComponent: ConfigurationModule, server: FastifyInstance, logger?: Logger<ILogObj>);
22
+ putBootConfig(request: FastifyRequest<{
23
+ Body: OCPP2_0_1.BootNotificationResponse;
24
+ Querystring: ChargingStationKeyQuerystring;
25
+ }>): Promise<BootConfig | undefined>;
26
+ getBootConfig(request: FastifyRequest<{
27
+ Querystring: ChargingStationKeyQuerystring;
28
+ }>): Promise<Boot | undefined>;
29
+ deleteBootConfig(request: FastifyRequest<{
30
+ Querystring: ChargingStationKeyQuerystring;
31
+ }>): Promise<Boot | undefined>;
32
+ updatePassword(request: FastifyRequest<{
33
+ Body: UpdateChargingStationPasswordRequest;
34
+ Querystring: UpdateChargingStationPasswordQueryString;
35
+ }>): Promise<IMessageConfirmation>;
36
+ getNetworkProfiles(request: FastifyRequest<{
37
+ Querystring: NetworkProfileQuerystring;
38
+ }>): Promise<ChargingStationNetworkProfile[]>;
39
+ deleteNetworkProfiles(request: FastifyRequest<{
40
+ Querystring: NetworkProfileDeleteQuerystring;
41
+ }>): Promise<IMessageConfirmation>;
42
+ /**
43
+ * Overrides superclass method to generate the URL path based on the input {@link Namespace}
44
+ * and the module's endpoint prefix configuration.
45
+ *
46
+ * @param {Namespace} input - The input {@link Namespace}.
47
+ * @return {string} - The generated URL path.
48
+ */
49
+ protected _toDataPath(input: OCPP2_0_1_Namespace | OCPP1_6_Namespace | Namespace): string;
50
+ private updatePasswordOnStation;
51
+ private updatePasswordForStation;
52
+ }
@@ -0,0 +1,206 @@
1
+ // SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
5
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
7
+ 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;
8
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
9
+ };
10
+ var __metadata = (this && this.__metadata) || function (k, v) {
11
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
12
+ };
13
+ import { Logger } from 'tslog';
14
+ import { ConfigurationModule } from './module.js';
15
+ import { AbstractModuleApi, AsDataEndpoint, BootConfigSchema, HttpMethod, Namespace, OCPP1_6_Namespace, OCPP2_0_1, OCPP2_0_1_CallAction, OCPP2_0_1_Namespace, OCPPVersion, UpdateChargingStationPasswordSchema, } from '@citrineos/base';
16
+ import { Boot, ChargingStationKeyQuerySchema, ChargingStationNetworkProfile, Component, NetworkProfileDeleteQuerySchema, NetworkProfileQuerySchema, ServerNetworkProfile, SetNetworkProfile, UpdateChargingStationPasswordQuerySchema, Variable, VariableAttribute, } from '@citrineos/data';
17
+ import { Op } from 'sequelize';
18
+ import { generatePassword, isValidPassword } from '@citrineos/util';
19
+ import { v4 as uuidv4 } from 'uuid';
20
+ /**
21
+ * Server API for the Configuration component.
22
+ */
23
+ export class ConfigurationDataApi extends AbstractModuleApi {
24
+ /**
25
+ * Constructor for the class.
26
+ *
27
+ * @param {ConfigurationModule} ConfigurationComponent - The Configuration component.
28
+ * @param {FastifyInstance} server - The server instance.
29
+ * @param {Logger<ILogObj>} [logger] - Optional logger instance.
30
+ */
31
+ constructor(ConfigurationComponent, server, logger) {
32
+ super(ConfigurationComponent, server, null, logger);
33
+ }
34
+ putBootConfig(request) {
35
+ return this._module.bootRepository.createOrUpdateByKey(request.query.tenantId, request.body, request.query.stationId);
36
+ }
37
+ getBootConfig(request) {
38
+ return this._module.bootRepository.readByKey(request.query.tenantId, request.query.stationId);
39
+ }
40
+ deleteBootConfig(request) {
41
+ return this._module.bootRepository.deleteByKey(request.query.tenantId, request.query.stationId);
42
+ }
43
+ async updatePassword(request) {
44
+ const stationId = request.body.stationId;
45
+ const tenantId = request.query.tenantId;
46
+ this._logger.debug(`Updating password for ${stationId} station in tenant ${tenantId}`);
47
+ if (request.body.setOnCharger && !request.body.password) {
48
+ return {
49
+ success: false,
50
+ payload: 'Password is required when setOnCharger is true',
51
+ };
52
+ }
53
+ if (request.body.password && !isValidPassword(request.body.password)) {
54
+ return { success: false, payload: 'Invalid password' };
55
+ }
56
+ const password = request.body.password || generatePassword();
57
+ if (!request.body.setOnCharger) {
58
+ try {
59
+ await this.updatePasswordOnStation(password, stationId, tenantId, request.query.callbackUrl);
60
+ }
61
+ catch (error) {
62
+ this._logger.warn(`Failed updating password on ${stationId} station`, error);
63
+ return {
64
+ success: false,
65
+ payload: `Failed updating password on ${stationId} station`,
66
+ };
67
+ }
68
+ }
69
+ const variableAttributes = await this.updatePasswordForStation(password, tenantId, stationId);
70
+ this._logger.debug(`Successfully updated password for ${stationId} station`);
71
+ return {
72
+ success: true,
73
+ payload: `Updated ${variableAttributes.length} attributes`,
74
+ };
75
+ }
76
+ async getNetworkProfiles(request) {
77
+ return ChargingStationNetworkProfile.findAll({
78
+ where: { stationId: request.query.stationId, tenantId: request.query.tenantId },
79
+ include: [SetNetworkProfile, ServerNetworkProfile],
80
+ });
81
+ }
82
+ async deleteNetworkProfiles(request) {
83
+ const destroyedRows = await ChargingStationNetworkProfile.destroy({
84
+ where: {
85
+ stationId: request.query.stationId,
86
+ tenantId: request.query.tenantId,
87
+ configurationSlot: {
88
+ [Op.in]: request.query.configurationSlot,
89
+ },
90
+ },
91
+ });
92
+ return {
93
+ success: true,
94
+ payload: `${destroyedRows} rows successfully destroyed`,
95
+ };
96
+ }
97
+ /**
98
+ * Overrides superclass method to generate the URL path based on the input {@link Namespace}
99
+ * and the module's endpoint prefix configuration.
100
+ *
101
+ * @param {Namespace} input - The input {@link Namespace}.
102
+ * @return {string} - The generated URL path.
103
+ */
104
+ _toDataPath(input) {
105
+ const endpointPrefix = this._module.config.modules.configuration.endpointPrefix;
106
+ return super._toDataPath(input, endpointPrefix);
107
+ }
108
+ async updatePasswordOnStation(password, stationId, tenantId, callbackUrl) {
109
+ const correlationId = uuidv4();
110
+ const cacheCallbackPromise = this._module.cache.onChange(correlationId, this._module.config.maxCachingSeconds, stationId);
111
+ const messageConfirmation = await this._module.sendCall(stationId, tenantId, OCPPVersion.OCPP2_0_1, OCPP2_0_1_CallAction.SetVariables, {
112
+ setVariableData: [
113
+ {
114
+ variable: { name: 'BasicAuthPassword' },
115
+ attributeValue: password,
116
+ attributeType: OCPP2_0_1.AttributeEnumType.Actual,
117
+ component: { name: 'SecurityCtrlr' },
118
+ },
119
+ ],
120
+ }, callbackUrl, correlationId);
121
+ if (!messageConfirmation.success) {
122
+ throw new Error(`Failed sending request to ${stationId} station for updating password`);
123
+ }
124
+ const responseJsonString = await cacheCallbackPromise;
125
+ if (!responseJsonString) {
126
+ throw new Error(`${stationId} station did not respond in time for updating password`);
127
+ }
128
+ const setVariablesResponse = JSON.parse(responseJsonString);
129
+ const passwordUpdated = setVariablesResponse.setVariableResult.every((result) => result.attributeStatus === OCPP2_0_1.SetVariableStatusEnumType.Accepted);
130
+ if (!passwordUpdated) {
131
+ throw new Error(`Failure updating password on ${stationId} station`);
132
+ }
133
+ }
134
+ async updatePasswordForStation(password, tenantId, stationId) {
135
+ const timestamp = new Date().toISOString();
136
+ const variableAttributes = await this._module.deviceModelRepository.createOrUpdateDeviceModelByStationId(tenantId, {
137
+ component: {
138
+ name: 'SecurityCtrlr',
139
+ },
140
+ variable: {
141
+ name: 'BasicAuthPassword',
142
+ },
143
+ variableAttribute: [
144
+ {
145
+ type: OCPP2_0_1.AttributeEnumType.Actual,
146
+ value: password,
147
+ mutability: OCPP2_0_1.MutabilityEnumType.WriteOnly,
148
+ },
149
+ ],
150
+ variableCharacteristics: {
151
+ dataType: OCPP2_0_1.DataEnumType.passwordString,
152
+ supportsMonitoring: false,
153
+ },
154
+ }, stationId, timestamp);
155
+ for (let variableAttribute of variableAttributes) {
156
+ variableAttribute = await variableAttribute.reload({
157
+ include: [Variable, Component],
158
+ });
159
+ await this._module.deviceModelRepository.updateResultByStationId(tenantId, {
160
+ attributeType: variableAttribute.type,
161
+ attributeStatus: OCPP2_0_1.SetVariableStatusEnumType.Accepted,
162
+ attributeStatusInfo: { reasonCode: 'SetOnCharger' },
163
+ component: variableAttribute.component,
164
+ variable: variableAttribute.variable,
165
+ }, stationId, timestamp);
166
+ }
167
+ return variableAttributes;
168
+ }
169
+ }
170
+ __decorate([
171
+ AsDataEndpoint(Namespace.BootConfig, HttpMethod.Put, ChargingStationKeyQuerySchema, BootConfigSchema),
172
+ __metadata("design:type", Function),
173
+ __metadata("design:paramtypes", [Object]),
174
+ __metadata("design:returntype", Promise)
175
+ ], ConfigurationDataApi.prototype, "putBootConfig", null);
176
+ __decorate([
177
+ AsDataEndpoint(Namespace.BootConfig, HttpMethod.Get, ChargingStationKeyQuerySchema),
178
+ __metadata("design:type", Function),
179
+ __metadata("design:paramtypes", [Object]),
180
+ __metadata("design:returntype", Promise)
181
+ ], ConfigurationDataApi.prototype, "getBootConfig", null);
182
+ __decorate([
183
+ AsDataEndpoint(Namespace.BootConfig, HttpMethod.Delete, ChargingStationKeyQuerySchema),
184
+ __metadata("design:type", Function),
185
+ __metadata("design:paramtypes", [Object]),
186
+ __metadata("design:returntype", Promise)
187
+ ], ConfigurationDataApi.prototype, "deleteBootConfig", null);
188
+ __decorate([
189
+ AsDataEndpoint(OCPP2_0_1_Namespace.PasswordType, HttpMethod.Post, UpdateChargingStationPasswordQuerySchema, UpdateChargingStationPasswordSchema),
190
+ __metadata("design:type", Function),
191
+ __metadata("design:paramtypes", [Object]),
192
+ __metadata("design:returntype", Promise)
193
+ ], ConfigurationDataApi.prototype, "updatePassword", null);
194
+ __decorate([
195
+ AsDataEndpoint(OCPP2_0_1_Namespace.ServerNetworkProfile, HttpMethod.Get, NetworkProfileQuerySchema),
196
+ __metadata("design:type", Function),
197
+ __metadata("design:paramtypes", [Object]),
198
+ __metadata("design:returntype", Promise)
199
+ ], ConfigurationDataApi.prototype, "getNetworkProfiles", null);
200
+ __decorate([
201
+ AsDataEndpoint(OCPP2_0_1_Namespace.ServerNetworkProfile, HttpMethod.Delete, NetworkProfileDeleteQuerySchema),
202
+ __metadata("design:type", Function),
203
+ __metadata("design:paramtypes", [Object]),
204
+ __metadata("design:returntype", Promise)
205
+ ], ConfigurationDataApi.prototype, "deleteNetworkProfiles", null);
206
+ //# sourceMappingURL=DataApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataApi.js","sourceRoot":"","sources":["../../src/module/DataApi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { IDeviceModelRepository } from '@citrineos/data';
2
+ export declare class DeviceModelService {
3
+ protected _deviceModelRepository: IDeviceModelRepository;
4
+ constructor(deviceModelRepository: IDeviceModelRepository);
5
+ /**
6
+ * Fetches the ItemsPerMessageSetVariables attribute from the device model.
7
+ * Returns null if no such attribute exists.
8
+ * It is possible for there to be multiple ItemsPerMessageSetVariables attributes if component instances or evses
9
+ * are associated with alternate options. That structure is not supported by this logic, and that
10
+ * structure is a violation of Part 2 - Specification of OCPP 2.0.1.
11
+ * In that case, the first attribute will be returned.
12
+ * @param tenantId
13
+ * @param stationId Charging station identifier.
14
+ * @returns ItemsPerMessageSetVariables as a number or null if no such attribute exists.
15
+ */
16
+ getItemsPerMessageSetVariablesByStationId(tenantId: number, stationId: string): Promise<number | null>;
17
+ /**
18
+ * Fetches the ItemsPerMessageGetVariables attribute from the device model.
19
+ * Returns null if no such attribute exists.
20
+ * It is possible for there to be multiple ItemsPerMessageGetVariables attributes if component instances or evses
21
+ * are associated with alternate options. That structure is not supported by this logic, and that
22
+ * structure is a violation of Part 2 - Specification of OCPP 2.0.1.
23
+ * In that case, the first attribute will be returned.
24
+ * @param tenantId
25
+ * @param stationId Charging station identifier.
26
+ * @returns ItemsPerMessageGetVariables as a number or null if no such attribute exists.
27
+ */
28
+ getItemsPerMessageGetVariablesByStationId(tenantId: number, stationId: string): Promise<number | null>;
29
+ updateDeviceModel(chargingStation: any, tenantId: number, stationId: string, timestamp: string): Promise<void>;
30
+ }