Add helper to get connector id for a transaction id
[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 connectorId = this.chargingStation.getConnectorIdByTransactionId(
126 commandParams?.transactionId as number
127 );
128 return {
129 transactionId: commandParams?.transactionId,
130 ...(!Utils.isUndefined(commandParams?.idTag) && { idTag: commandParams.idTag }),
131 meterStop: commandParams?.meterStop,
132 timestamp: new Date().toISOString(),
133 ...(commandParams?.reason && { reason: commandParams.reason }),
134 ...(this.chargingStation.getTransactionDataMeterValues() && {
135 transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(
136 this.chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
137 OCPP16ServiceUtils.buildTransactionEndMeterValue(
138 this.chargingStation,
139 connectorId,
140 commandParams?.meterStop as number
141 )
142 ),
143 }),
144 } as StopTransactionRequest;
145 default:
146 throw new OCPPError(
147 ErrorType.NOT_SUPPORTED,
148 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
149 `${moduleName}.buildCommandPayload: Unsupported OCPP command: ${commandName}`,
150 commandName,
151 { commandName }
152 );
153 }
154 }
155 }