fix: send preparing connector status before `StartTransaction`
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 2.0 / OCPP20RequestService.ts
CommitLineData
a19b897d 1// Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
953d6b02 2
24d15716 3import type { ValidateFunction } from 'ajv'
953d6b02 4
66a7748d
JB
5import type { ChargingStation } from '../../../charging-station/index.js'
6import { OCPPError } from '../../../exception/index.js'
d270cc87 7import {
268a74bb
JB
8 ErrorType,
9 type JsonObject,
10 type JsonType,
96a52d08 11 type OCPP20BootNotificationRequest,
81533a20 12 type OCPP20HeartbeatRequest,
d270cc87 13 OCPP20RequestCommand,
6e939d9e 14 type OCPP20StatusNotificationRequest,
268a74bb 15 OCPPVersion,
66a7748d
JB
16 type RequestParams
17} from '../../../types/index.js'
18import { generateUUID } from '../../../utils/index.js'
19import { OCPPRequestService } from '../OCPPRequestService.js'
20import type { OCPPResponseService } from '../OCPPResponseService.js'
4c3f6c20
JB
21import { OCPP20Constants } from './OCPP20Constants.js'
22import { OCPP20ServiceUtils } from './OCPP20ServiceUtils.js'
953d6b02 23
66a7748d 24const moduleName = 'OCPP20RequestService'
953d6b02 25
268a74bb 26export class OCPP20RequestService extends OCPPRequestService {
d5490a13 27 protected payloadValidateFunctions: Map<OCPP20RequestCommand, ValidateFunction<JsonType>>
953d6b02 28
66a7748d 29 public constructor (ocppResponseService: OCPPResponseService) {
5199f9fd
JB
30 // if (new.target.name === moduleName) {
31 // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
b768993d 32 // }
1feac591 33 super(OCPPVersion.VERSION_201, ocppResponseService)
d5490a13 34 this.payloadValidateFunctions = new Map<OCPP20RequestCommand, ValidateFunction<JsonType>>([
d270cc87
JB
35 [
36 OCPP20RequestCommand.BOOT_NOTIFICATION,
24d15716
JB
37 this.ajv
38 .compile(
39 OCPP20ServiceUtils.parseJsonSchemaFile<OCPP20BootNotificationRequest>(
40 'assets/json-schemas/ocpp/2.0/BootNotificationRequest.json',
41 moduleName,
42 'constructor'
43 )
44 )
45 .bind(this)
d270cc87 46 ],
81533a20
JB
47 [
48 OCPP20RequestCommand.HEARTBEAT,
24d15716
JB
49 this.ajv
50 .compile(
51 OCPP20ServiceUtils.parseJsonSchemaFile<OCPP20HeartbeatRequest>(
52 'assets/json-schemas/ocpp/2.0/HeartbeatRequest.json',
53 moduleName,
54 'constructor'
55 )
56 )
57 .bind(this)
81533a20 58 ],
6e939d9e
JB
59 [
60 OCPP20RequestCommand.STATUS_NOTIFICATION,
24d15716
JB
61 this.ajv
62 .compile(
63 OCPP20ServiceUtils.parseJsonSchemaFile<OCPP20StatusNotificationRequest>(
64 'assets/json-schemas/ocpp/2.0/StatusNotificationRequest.json',
65 moduleName,
66 'constructor'
67 )
68 )
69 .bind(this)
66a7748d
JB
70 ]
71 ])
ba9a56a6 72 this.buildRequestPayload = this.buildRequestPayload.bind(this)
953d6b02
JB
73 }
74
75 public async requestHandler<RequestType extends JsonType, ResponseType extends JsonType>(
76 chargingStation: ChargingStation,
77 commandName: OCPP20RequestCommand,
a9671b9e 78 commandParams?: RequestType,
66a7748d 79 params?: RequestParams
953d6b02 80 ): Promise<ResponseType> {
62340a29 81 // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
66a7748d 82 if (OCPP20ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) {
a9671b9e 83 // TODO: post request actions hook
953d6b02
JB
84 return (await this.sendMessage(
85 chargingStation,
9bf0ef23 86 generateUUID(),
18bf8274 87 this.buildRequestPayload<RequestType>(chargingStation, commandName, commandParams),
953d6b02 88 commandName,
66a7748d
JB
89 params
90 )) as ResponseType
953d6b02
JB
91 }
92 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
93 throw new OCPPError(
94 ErrorType.NOT_SUPPORTED,
95 `Unsupported OCPP command '${commandName}'`,
96 commandName,
66a7748d
JB
97 commandParams
98 )
953d6b02
JB
99 }
100
101 private buildRequestPayload<Request extends JsonType>(
102 chargingStation: ChargingStation,
103 commandName: OCPP20RequestCommand,
66a7748d 104 commandParams?: JsonType
953d6b02 105 ): Request {
66a7748d 106 commandParams = commandParams as JsonObject
953d6b02 107 switch (commandName) {
d270cc87 108 case OCPP20RequestCommand.BOOT_NOTIFICATION:
66a7748d 109 return commandParams as unknown as Request
81533a20 110 case OCPP20RequestCommand.HEARTBEAT:
66a7748d 111 return OCPP20Constants.OCPP_RESPONSE_EMPTY as unknown as Request
6e939d9e
JB
112 case OCPP20RequestCommand.STATUS_NOTIFICATION:
113 return {
36c462a4 114 timestamp: new Date(),
66a7748d
JB
115 ...commandParams
116 } as unknown as Request
953d6b02
JB
117 default:
118 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
119 throw new OCPPError(
120 ErrorType.NOT_SUPPORTED,
121 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
122 `Unsupported OCPP command '${commandName}'`,
123 commandName,
66a7748d
JB
124 commandParams
125 )
953d6b02
JB
126 }
127 }
953d6b02 128}