Untangle ChargingStation class from OCPP services classes
[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 { JsonObject, JsonType } from '../../../types/JsonType';
4
5 import type ChargingStation from '../../ChargingStation';
6 import Constants from '../../../utils/Constants';
7 import { ErrorType } from '../../../types/ocpp/ErrorType';
8 import { OCPP16RequestCommand } from '../../../types/ocpp/1.6/Requests';
9 import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
10 import OCPPError from '../../../exception/OCPPError';
11 import OCPPRequestService from '../OCPPRequestService';
12 import type OCPPResponseService from '../OCPPResponseService';
13 import { RequestParams } from '../../../types/ocpp/Requests';
14 import Utils from '../../../utils/Utils';
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 (Object.values(OCPP16RequestCommand).includes(commandName)) {
33 return (await this.sendMessage(
34 chargingStation,
35 Utils.generateUUID(),
36 this.buildRequestPayload<Request>(chargingStation, commandName, commandParams),
37 commandName,
38 params
39 )) as unknown as Response;
40 }
41 throw new OCPPError(
42 ErrorType.NOT_SUPPORTED,
43 `${moduleName}.requestHandler: Unsupported OCPP command ${commandName}`,
44 commandName,
45 { commandName }
46 );
47 }
48
49 private buildRequestPayload<Request extends JsonType>(
50 chargingStation: ChargingStation,
51 commandName: OCPP16RequestCommand,
52 commandParams?: JsonType
53 ): Request {
54 let connectorId: number;
55 commandParams = commandParams as JsonObject;
56 switch (commandName) {
57 case OCPP16RequestCommand.AUTHORIZE:
58 return {
59 ...(!Utils.isUndefined(commandParams?.idTag)
60 ? { idTag: commandParams.idTag }
61 : { idTag: Constants.DEFAULT_IDTAG }),
62 } as unknown as Request;
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 }),
84 } as unknown as Request;
85 case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION:
86 return {
87 status: commandParams?.diagnosticsStatus,
88 } as unknown as Request;
89 case OCPP16RequestCommand.HEARTBEAT:
90 return {} as unknown as Request;
91 case OCPP16RequestCommand.METER_VALUES:
92 return {
93 connectorId: commandParams?.connectorId,
94 transactionId: commandParams?.transactionId,
95 meterValue: Array.isArray(commandParams?.meterValue)
96 ? commandParams?.meterValue
97 : [commandParams?.meterValue],
98 } as unknown as Request;
99 case OCPP16RequestCommand.STATUS_NOTIFICATION:
100 return {
101 connectorId: commandParams?.connectorId,
102 status: commandParams?.status,
103 errorCode: commandParams?.errorCode,
104 } as unknown as Request;
105 case OCPP16RequestCommand.START_TRANSACTION:
106 return {
107 connectorId: commandParams?.connectorId,
108 ...(!Utils.isUndefined(commandParams?.idTag)
109 ? { idTag: commandParams?.idTag }
110 : { idTag: Constants.DEFAULT_IDTAG }),
111 meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId(
112 commandParams?.connectorId as number
113 ),
114 timestamp: new Date().toISOString(),
115 } as unknown as Request;
116 case OCPP16RequestCommand.STOP_TRANSACTION:
117 connectorId = chargingStation.getConnectorIdByTransactionId(
118 commandParams?.transactionId as number
119 );
120 return {
121 transactionId: commandParams?.transactionId,
122 ...(!Utils.isUndefined(commandParams?.idTag) && { idTag: commandParams.idTag }),
123 meterStop: commandParams?.meterStop,
124 timestamp: new Date().toISOString(),
125 ...(commandParams?.reason && { reason: commandParams.reason }),
126 ...(chargingStation.getTransactionDataMeterValues() && {
127 transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(
128 chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
129 OCPP16ServiceUtils.buildTransactionEndMeterValue(
130 chargingStation,
131 connectorId,
132 commandParams?.meterStop as number
133 )
134 ),
135 }),
136 } as unknown as Request;
137 default:
138 throw new OCPPError(
139 ErrorType.NOT_SUPPORTED,
140 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
141 `${moduleName}.buildRequestPayload: Unsupported OCPP command: ${commandName}`,
142 commandName,
143 { commandName }
144 );
145 }
146 }
147 }