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