Validate response PDU (#137)
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16RequestService.ts
CommitLineData
c8eeb62b
JB
1// Partial Copyright Jerome Benoit. 2021. All Rights Reserved.
2
8114d10e 3import OCPPError from '../../../exception/OCPPError';
5cc4b63b 4import { JsonObject, JsonType } from '../../../types/JsonType';
f22266fd 5import { OCPP16RequestCommand } from '../../../types/ocpp/1.6/Requests';
8114d10e 6import { ErrorType } from '../../../types/ocpp/ErrorType';
be9b0d50 7import { RequestParams } from '../../../types/ocpp/Requests';
8114d10e 8import Constants from '../../../utils/Constants';
c0560973 9import Utils from '../../../utils/Utils';
8114d10e 10import type ChargingStation from '../../ChargingStation';
65554cc3 11import { ChargingStationUtils } from '../../ChargingStationUtils';
8114d10e
JB
12import OCPPRequestService from '../OCPPRequestService';
13import type OCPPResponseService from '../OCPPResponseService';
14import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
c0560973 15
909dcf2d
JB
16const moduleName = 'OCPP16RequestService';
17
c0560973 18export default class OCPP16RequestService extends OCPPRequestService {
08f130a0 19 public constructor(ocppResponseService: OCPPResponseService) {
909dcf2d 20 if (new.target?.name === moduleName) {
06127450 21 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
9f2e3130 22 }
08f130a0 23 super(ocppResponseService);
9f2e3130
JB
24 }
25
5cc4b63b 26 public async requestHandler<Request extends JsonType, Response extends JsonType>(
08f130a0 27 chargingStation: ChargingStation,
94a464f9 28 commandName: OCPP16RequestCommand,
5cc4b63b 29 commandParams?: JsonType,
be9b0d50 30 params?: RequestParams
f22266fd 31 ): Promise<Response> {
ada189a8 32 if (ChargingStationUtils.isRequestCommandSupported(commandName, chargingStation)) {
f22266fd 33 return (await this.sendMessage(
08f130a0 34 chargingStation,
94a464f9 35 Utils.generateUUID(),
08f130a0 36 this.buildRequestPayload<Request>(chargingStation, commandName, commandParams),
94a464f9
JB
37 commandName,
38 params
f22266fd 39 )) as unknown as Response;
94a464f9
JB
40 }
41 throw new OCPPError(
42 ErrorType.NOT_SUPPORTED,
ada189a8 43 `${moduleName}.requestHandler: Unsupported OCPP command '${commandName}'`,
94a464f9 44 commandName,
7369e417 45 commandParams
94a464f9 46 );
c0560973
JB
47 }
48
5cc4b63b 49 private buildRequestPayload<Request extends JsonType>(
08f130a0 50 chargingStation: ChargingStation,
78085c42 51 commandName: OCPP16RequestCommand,
5cc4b63b 52 commandParams?: JsonType
f22266fd 53 ): Request {
68c993d5 54 let connectorId: number;
5cc4b63b 55 commandParams = commandParams as JsonObject;
78085c42
JB
56 switch (commandName) {
57 case OCPP16RequestCommand.AUTHORIZE:
58 return {
59 ...(!Utils.isUndefined(commandParams?.idTag)
60 ? { idTag: commandParams.idTag }
61 : { idTag: Constants.DEFAULT_IDTAG }),
f22266fd 62 } as unknown as Request;
78085c42
JB
63 case OCPP16RequestCommand.BOOT_NOTIFICATION:
64 return {
65 chargePointModel: commandParams?.chargePointModel,
66 chargePointVendor: commandParams?.chargePointVendor,
67 ...(!Utils.isUndefined(commandParams?.chargeBoxSerialNumber) && {
68 chargeBoxSerialNumber: commandParams.chargeBoxSerialNumber,
69 }),
70 ...(!Utils.isUndefined(commandParams?.chargePointSerialNumber) && {
71 chargePointSerialNumber: commandParams.chargePointSerialNumber,
72 }),
73 ...(!Utils.isUndefined(commandParams?.firmwareVersion) && {
74 firmwareVersion: commandParams.firmwareVersion,
75 }),
76 ...(!Utils.isUndefined(commandParams?.iccid) && { iccid: commandParams.iccid }),
77 ...(!Utils.isUndefined(commandParams?.imsi) && { imsi: commandParams.imsi }),
78 ...(!Utils.isUndefined(commandParams?.meterSerialNumber) && {
79 meterSerialNumber: commandParams.meterSerialNumber,
80 }),
81 ...(!Utils.isUndefined(commandParams?.meterType) && {
82 meterType: commandParams.meterType,
83 }),
f22266fd 84 } as unknown as Request;
78085c42
JB
85 case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION:
86 return {
87 status: commandParams?.diagnosticsStatus,
f22266fd 88 } as unknown as Request;
78085c42 89 case OCPP16RequestCommand.HEARTBEAT:
f22266fd 90 return {} as unknown as Request;
78085c42 91 case OCPP16RequestCommand.METER_VALUES:
7369e417
JB
92 // Sanity check
93 if (!Array.isArray(commandParams?.meterValue)) {
94 throw new OCPPError(
e3018bc4
JB
95 ErrorType.TYPE_CONSTRAINT_VIOLATION,
96 `${moduleName}.buildRequestPayload ${commandName}: Invalid array type for meterValue PDU field`,
7369e417
JB
97 commandName,
98 commandParams
99 );
100 }
78085c42
JB
101 return {
102 connectorId: commandParams?.connectorId,
103 transactionId: commandParams?.transactionId,
7369e417 104 meterValue: commandParams?.meterValue,
f22266fd 105 } as unknown as Request;
78085c42
JB
106 case OCPP16RequestCommand.STATUS_NOTIFICATION:
107 return {
108 connectorId: commandParams?.connectorId,
78085c42 109 status: commandParams?.status,
93b4a429 110 errorCode: commandParams?.errorCode,
f22266fd 111 } as unknown as Request;
78085c42
JB
112 case OCPP16RequestCommand.START_TRANSACTION:
113 return {
114 connectorId: commandParams?.connectorId,
115 ...(!Utils.isUndefined(commandParams?.idTag)
116 ? { idTag: commandParams?.idTag }
117 : { idTag: Constants.DEFAULT_IDTAG }),
08f130a0 118 meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId(
78085c42
JB
119 commandParams?.connectorId as number
120 ),
121 timestamp: new Date().toISOString(),
f22266fd 122 } as unknown as Request;
78085c42 123 case OCPP16RequestCommand.STOP_TRANSACTION:
08f130a0 124 connectorId = chargingStation.getConnectorIdByTransactionId(
f479a792
JB
125 commandParams?.transactionId as number
126 );
78085c42
JB
127 return {
128 transactionId: commandParams?.transactionId,
129 ...(!Utils.isUndefined(commandParams?.idTag) && { idTag: commandParams.idTag }),
130 meterStop: commandParams?.meterStop,
131 timestamp: new Date().toISOString(),
132 ...(commandParams?.reason && { reason: commandParams.reason }),
08f130a0 133 ...(chargingStation.getTransactionDataMeterValues() && {
78085c42 134 transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(
08f130a0 135 chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
78085c42 136 OCPP16ServiceUtils.buildTransactionEndMeterValue(
08f130a0 137 chargingStation,
68c993d5 138 connectorId,
78085c42
JB
139 commandParams?.meterStop as number
140 )
141 ),
142 }),
f22266fd 143 } as unknown as Request;
78085c42
JB
144 default:
145 throw new OCPPError(
146 ErrorType.NOT_SUPPORTED,
147 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
ada189a8 148 `${moduleName}.buildRequestPayload: Unsupported OCPP command '${commandName}'`,
78085c42 149 commandName,
7369e417 150 commandParams
78085c42
JB
151 );
152 }
153 }
c0560973 154}