Convert sendTransactionBeginMeterValues to OCPP message sending handler
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16RequestService.ts
1 // Partial Copyright Jerome Benoit. 2021. All Rights Reserved.
2
3 import {
4 AuthorizeRequest,
5 StartTransactionRequest,
6 StopTransactionRequest,
7 } from '../../../types/ocpp/1.6/Transaction';
8 import {
9 DiagnosticsStatusNotificationRequest,
10 HeartbeatRequest,
11 OCPP16BootNotificationRequest,
12 OCPP16RequestCommand,
13 StatusNotificationRequest,
14 } from '../../../types/ocpp/1.6/Requests';
15 import { MeterValuesRequest, OCPP16MeterValue } from '../../../types/ocpp/1.6/MeterValues';
16 import { ResponseType, SendParams } from '../../../types/ocpp/Requests';
17
18 import type ChargingStation from '../../ChargingStation';
19 import Constants from '../../../utils/Constants';
20 import { ErrorType } from '../../../types/ocpp/ErrorType';
21 import { JsonType } from '../../../types/JsonType';
22 import { OCPP16DiagnosticsStatus } from '../../../types/ocpp/1.6/DiagnosticsStatus';
23 import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
24 import OCPPError from '../../../exception/OCPPError';
25 import OCPPRequestService from '../OCPPRequestService';
26 import type OCPPResponseService from '../OCPPResponseService';
27 import Utils from '../../../utils/Utils';
28
29 const moduleName = 'OCPP16RequestService';
30
31 export default class OCPP16RequestService extends OCPPRequestService {
32 public constructor(chargingStation: ChargingStation, ocppResponseService: OCPPResponseService) {
33 if (new.target?.name === moduleName) {
34 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
35 }
36 super(chargingStation, ocppResponseService);
37 }
38
39 public async sendMessageHandler(
40 commandName: OCPP16RequestCommand,
41 commandParams?: JsonType,
42 params?: SendParams
43 ): Promise<ResponseType> {
44 if (Object.values(OCPP16RequestCommand).includes(commandName)) {
45 return this.sendMessage(
46 Utils.generateUUID(),
47 this.buildCommandPayload(commandName, commandParams),
48 commandName,
49 params
50 );
51 }
52 throw new OCPPError(
53 ErrorType.NOT_SUPPORTED,
54 `${moduleName}.sendMessageHandler: Unsupported OCPP command ${commandName}`,
55 commandName,
56 { commandName }
57 );
58 }
59
60 public async sendTransactionEndMeterValues(
61 connectorId: number,
62 transactionId: number,
63 endMeterValue: OCPP16MeterValue
64 ): Promise<void> {
65 const payload: MeterValuesRequest = {
66 connectorId,
67 transactionId,
68 meterValue: [endMeterValue],
69 };
70 await this.sendMessage(Utils.generateUUID(), payload, OCPP16RequestCommand.METER_VALUES);
71 }
72
73 public async sendDiagnosticsStatusNotification(
74 diagnosticsStatus: OCPP16DiagnosticsStatus
75 ): Promise<void> {
76 const payload: DiagnosticsStatusNotificationRequest = {
77 status: diagnosticsStatus,
78 };
79 await this.sendMessage(
80 Utils.generateUUID(),
81 payload,
82 OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION
83 );
84 }
85
86 private buildCommandPayload(
87 commandName: OCPP16RequestCommand,
88 commandParams?: JsonType
89 ): JsonType {
90 let connectorId: number;
91 switch (commandName) {
92 case OCPP16RequestCommand.AUTHORIZE:
93 return {
94 ...(!Utils.isUndefined(commandParams?.idTag)
95 ? { idTag: commandParams.idTag }
96 : { idTag: Constants.DEFAULT_IDTAG }),
97 } as AuthorizeRequest;
98 case OCPP16RequestCommand.BOOT_NOTIFICATION:
99 return {
100 chargePointModel: commandParams?.chargePointModel,
101 chargePointVendor: commandParams?.chargePointVendor,
102 ...(!Utils.isUndefined(commandParams?.chargeBoxSerialNumber) && {
103 chargeBoxSerialNumber: commandParams.chargeBoxSerialNumber,
104 }),
105 ...(!Utils.isUndefined(commandParams?.chargePointSerialNumber) && {
106 chargePointSerialNumber: commandParams.chargePointSerialNumber,
107 }),
108 ...(!Utils.isUndefined(commandParams?.firmwareVersion) && {
109 firmwareVersion: commandParams.firmwareVersion,
110 }),
111 ...(!Utils.isUndefined(commandParams?.iccid) && { iccid: commandParams.iccid }),
112 ...(!Utils.isUndefined(commandParams?.imsi) && { imsi: commandParams.imsi }),
113 ...(!Utils.isUndefined(commandParams?.meterSerialNumber) && {
114 meterSerialNumber: commandParams.meterSerialNumber,
115 }),
116 ...(!Utils.isUndefined(commandParams?.meterType) && {
117 meterType: commandParams.meterType,
118 }),
119 } as OCPP16BootNotificationRequest;
120 case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION:
121 return {
122 status: commandParams?.diagnosticsStatus,
123 } as DiagnosticsStatusNotificationRequest;
124 case OCPP16RequestCommand.HEARTBEAT:
125 return {} as HeartbeatRequest;
126 case OCPP16RequestCommand.METER_VALUES:
127 return {
128 connectorId: commandParams?.connectorId,
129 transactionId: commandParams?.transactionId,
130 meterValue: Array.isArray(commandParams?.meterValues)
131 ? commandParams?.meterValues
132 : [commandParams?.meterValue],
133 } as MeterValuesRequest;
134 case OCPP16RequestCommand.STATUS_NOTIFICATION:
135 return {
136 connectorId: commandParams?.connectorId,
137 status: commandParams?.status,
138 errorCode: commandParams?.errorCode,
139 } as StatusNotificationRequest;
140 case OCPP16RequestCommand.START_TRANSACTION:
141 return {
142 connectorId: commandParams?.connectorId,
143 ...(!Utils.isUndefined(commandParams?.idTag)
144 ? { idTag: commandParams?.idTag }
145 : { idTag: Constants.DEFAULT_IDTAG }),
146 meterStart: this.chargingStation.getEnergyActiveImportRegisterByConnectorId(
147 commandParams?.connectorId as number
148 ),
149 timestamp: new Date().toISOString(),
150 } as StartTransactionRequest;
151 case OCPP16RequestCommand.STOP_TRANSACTION:
152 for (const id of this.chargingStation.connectors.keys()) {
153 if (
154 id > 0 &&
155 this.chargingStation.getConnectorStatus(id)?.transactionId ===
156 commandParams?.transactionId
157 ) {
158 connectorId = id;
159 break;
160 }
161 }
162 return {
163 transactionId: commandParams?.transactionId,
164 ...(!Utils.isUndefined(commandParams?.idTag) && { idTag: commandParams.idTag }),
165 meterStop: commandParams?.meterStop,
166 timestamp: new Date().toISOString(),
167 ...(commandParams?.reason && { reason: commandParams.reason }),
168 ...(this.chargingStation.getTransactionDataMeterValues() && {
169 transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(
170 this.chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
171 OCPP16ServiceUtils.buildTransactionEndMeterValue(
172 this.chargingStation,
173 connectorId,
174 commandParams?.meterStop as number
175 )
176 ),
177 }),
178 } as StopTransactionRequest;
179 default:
180 throw new OCPPError(
181 ErrorType.NOT_SUPPORTED,
182 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
183 `${moduleName}.buildCommandPayload: Unsupported OCPP command: ${commandName}`,
184 commandName,
185 { commandName }
186 );
187 }
188 }
189 }