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