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