Fix metervalues payload format
[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 { ResponseType, SendParams } from '../../../types/ocpp/Requests';
16
17 import type ChargingStation from '../../ChargingStation';
18 import Constants from '../../../utils/Constants';
19 import { ErrorType } from '../../../types/ocpp/ErrorType';
20 import { JsonType } from '../../../types/JsonType';
21 import { MeterValuesRequest } from '../../../types/ocpp/1.6/MeterValues';
22 import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
23 import OCPPError from '../../../exception/OCPPError';
24 import OCPPRequestService from '../OCPPRequestService';
25 import type OCPPResponseService from '../OCPPResponseService';
26 import Utils from '../../../utils/Utils';
27
28 const moduleName = 'OCPP16RequestService';
29
30 export default class OCPP16RequestService extends OCPPRequestService {
31 public constructor(chargingStation: ChargingStation, ocppResponseService: OCPPResponseService) {
32 if (new.target?.name === moduleName) {
33 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
34 }
35 super(chargingStation, ocppResponseService);
36 }
37
38 public async sendMessageHandler(
39 commandName: OCPP16RequestCommand,
40 commandParams?: JsonType,
41 params?: SendParams
42 ): Promise<ResponseType> {
43 if (Object.values(OCPP16RequestCommand).includes(commandName)) {
44 return this.sendMessage(
45 Utils.generateUUID(),
46 this.buildCommandPayload(commandName, commandParams),
47 commandName,
48 params
49 );
50 }
51 throw new OCPPError(
52 ErrorType.NOT_SUPPORTED,
53 `${moduleName}.sendMessageHandler: Unsupported OCPP command ${commandName}`,
54 commandName,
55 { commandName }
56 );
57 }
58
59 private buildCommandPayload(
60 commandName: OCPP16RequestCommand,
61 commandParams?: JsonType
62 ): JsonType {
63 let connectorId: number;
64 switch (commandName) {
65 case OCPP16RequestCommand.AUTHORIZE:
66 return {
67 ...(!Utils.isUndefined(commandParams?.idTag)
68 ? { idTag: commandParams.idTag }
69 : { idTag: Constants.DEFAULT_IDTAG }),
70 } as AuthorizeRequest;
71 case OCPP16RequestCommand.BOOT_NOTIFICATION:
72 return {
73 chargePointModel: commandParams?.chargePointModel,
74 chargePointVendor: commandParams?.chargePointVendor,
75 ...(!Utils.isUndefined(commandParams?.chargeBoxSerialNumber) && {
76 chargeBoxSerialNumber: commandParams.chargeBoxSerialNumber,
77 }),
78 ...(!Utils.isUndefined(commandParams?.chargePointSerialNumber) && {
79 chargePointSerialNumber: commandParams.chargePointSerialNumber,
80 }),
81 ...(!Utils.isUndefined(commandParams?.firmwareVersion) && {
82 firmwareVersion: commandParams.firmwareVersion,
83 }),
84 ...(!Utils.isUndefined(commandParams?.iccid) && { iccid: commandParams.iccid }),
85 ...(!Utils.isUndefined(commandParams?.imsi) && { imsi: commandParams.imsi }),
86 ...(!Utils.isUndefined(commandParams?.meterSerialNumber) && {
87 meterSerialNumber: commandParams.meterSerialNumber,
88 }),
89 ...(!Utils.isUndefined(commandParams?.meterType) && {
90 meterType: commandParams.meterType,
91 }),
92 } as OCPP16BootNotificationRequest;
93 case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION:
94 return {
95 status: commandParams?.diagnosticsStatus,
96 } as DiagnosticsStatusNotificationRequest;
97 case OCPP16RequestCommand.HEARTBEAT:
98 return {} as HeartbeatRequest;
99 case OCPP16RequestCommand.METER_VALUES:
100 return {
101 connectorId: commandParams?.connectorId,
102 transactionId: commandParams?.transactionId,
103 meterValue: Array.isArray(commandParams?.meterValue)
104 ? commandParams?.meterValue
105 : [commandParams?.meterValue],
106 } as MeterValuesRequest;
107 case OCPP16RequestCommand.STATUS_NOTIFICATION:
108 return {
109 connectorId: commandParams?.connectorId,
110 status: commandParams?.status,
111 errorCode: commandParams?.errorCode,
112 } as StatusNotificationRequest;
113 case OCPP16RequestCommand.START_TRANSACTION:
114 return {
115 connectorId: commandParams?.connectorId,
116 ...(!Utils.isUndefined(commandParams?.idTag)
117 ? { idTag: commandParams?.idTag }
118 : { idTag: Constants.DEFAULT_IDTAG }),
119 meterStart: this.chargingStation.getEnergyActiveImportRegisterByConnectorId(
120 commandParams?.connectorId as number
121 ),
122 timestamp: new Date().toISOString(),
123 } as StartTransactionRequest;
124 case OCPP16RequestCommand.STOP_TRANSACTION:
125 for (const id of this.chargingStation.connectors.keys()) {
126 if (
127 id > 0 &&
128 this.chargingStation.getConnectorStatus(id)?.transactionId ===
129 commandParams?.transactionId
130 ) {
131 connectorId = id;
132 break;
133 }
134 }
135 return {
136 transactionId: commandParams?.transactionId,
137 ...(!Utils.isUndefined(commandParams?.idTag) && { idTag: commandParams.idTag }),
138 meterStop: commandParams?.meterStop,
139 timestamp: new Date().toISOString(),
140 ...(commandParams?.reason && { reason: commandParams.reason }),
141 ...(this.chargingStation.getTransactionDataMeterValues() && {
142 transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(
143 this.chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
144 OCPP16ServiceUtils.buildTransactionEndMeterValue(
145 this.chargingStation,
146 connectorId,
147 commandParams?.meterStop as number
148 )
149 ),
150 }),
151 } as StopTransactionRequest;
152 default:
153 throw new OCPPError(
154 ErrorType.NOT_SUPPORTED,
155 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
156 `${moduleName}.buildCommandPayload: Unsupported OCPP command: ${commandName}`,
157 commandName,
158 { commandName }
159 );
160 }
161 }
162 }