--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:AuthorizeRequest",
+ "title": "AuthorizeRequest",
+ "type": "object",
+ "properties": {
+ "idTag": {
+ "type": "string",
+ "maxLength": 20
+ }
+ },
+ "additionalProperties": false,
+ "required": ["idTag"]
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:BootNotificationRequest",
+ "title": "BootNotificationRequest",
+ "type": "object",
+ "properties": {
+ "chargePointVendor": {
+ "type": "string",
+ "maxLength": 20
+ },
+ "chargePointModel": {
+ "type": "string",
+ "maxLength": 20
+ },
+ "chargePointSerialNumber": {
+ "type": "string",
+ "maxLength": 50
+ },
+ "chargeBoxSerialNumber": {
+ "type": "string",
+ "maxLength": 50
+ },
+ "firmwareVersion": {
+ "type": "string",
+ "maxLength": 50
+ },
+ "iccid": {
+ "type": "string",
+ "maxLength": 20
+ },
+ "imsi": {
+ "type": "string",
+ "maxLength": 20
+ },
+ "meterType": {
+ "type": "string",
+ "maxLength": 25
+ },
+ "meterSerialNumber": {
+ "type": "string",
+ "maxLength": 50
+ }
+ },
+ "additionalProperties": false,
+ "required": ["chargePointVendor", "chargePointModel"]
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:DiagnosticsStatusNotificationRequest",
+ "title": "DiagnosticsStatusNotificationRequest",
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["Idle", "Uploaded", "UploadFailed", "Uploading"]
+ }
+ },
+ "additionalProperties": false,
+ "required": ["status"]
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:DiagnosticsStatusNotificationResponse",
+ "title": "DiagnosticsStatusNotificationResponse",
+ "type": "object",
+ "properties": {},
+ "additionalProperties": false
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:HeartbeatRequest",
+ "title": "HeartbeatRequest",
+ "type": "object",
+ "properties": {},
+ "additionalProperties": false
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:MeterValuesRequest",
+ "title": "MeterValuesRequest",
+ "type": "object",
+ "properties": {
+ "connectorId": {
+ "type": "integer"
+ },
+ "transactionId": {
+ "type": "integer"
+ },
+ "meterValue": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "sampledValue": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "string"
+ },
+ "context": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "Interruption.Begin",
+ "Interruption.End",
+ "Sample.Clock",
+ "Sample.Periodic",
+ "Transaction.Begin",
+ "Transaction.End",
+ "Trigger",
+ "Other"
+ ]
+ },
+ "format": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["Raw", "SignedData"]
+ },
+ "measurand": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "Energy.Active.Export.Register",
+ "Energy.Active.Import.Register",
+ "Energy.Reactive.Export.Register",
+ "Energy.Reactive.Import.Register",
+ "Energy.Active.Export.Interval",
+ "Energy.Active.Import.Interval",
+ "Energy.Reactive.Export.Interval",
+ "Energy.Reactive.Import.Interval",
+ "Power.Active.Export",
+ "Power.Active.Import",
+ "Power.Offered",
+ "Power.Reactive.Export",
+ "Power.Reactive.Import",
+ "Power.Factor",
+ "Current.Import",
+ "Current.Export",
+ "Current.Offered",
+ "Voltage",
+ "Frequency",
+ "Temperature",
+ "SoC",
+ "RPM"
+ ]
+ },
+ "phase": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["L1", "L2", "L3", "N", "L1-N", "L2-N", "L3-N", "L1-L2", "L2-L3", "L3-L1"]
+ },
+ "location": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["Cable", "EV", "Inlet", "Outlet", "Body"]
+ },
+ "unit": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "Wh",
+ "kWh",
+ "varh",
+ "kvarh",
+ "W",
+ "kW",
+ "VA",
+ "kVA",
+ "var",
+ "kvar",
+ "A",
+ "V",
+ "K",
+ "Celcius",
+ "Celsius",
+ "Fahrenheit",
+ "Percent"
+ ]
+ }
+ },
+ "additionalProperties": false,
+ "required": ["value"]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["timestamp", "sampledValue"]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["connectorId", "meterValue"]
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:StartTransactionRequest",
+ "title": "StartTransactionRequest",
+ "type": "object",
+ "properties": {
+ "connectorId": {
+ "type": "integer"
+ },
+ "idTag": {
+ "type": "string",
+ "maxLength": 20
+ },
+ "meterStart": {
+ "type": "integer"
+ },
+ "reservationId": {
+ "type": "integer"
+ },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["connectorId", "idTag", "meterStart", "timestamp"]
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:StatusNotificationRequest",
+ "title": "StatusNotificationRequest",
+ "type": "object",
+ "properties": {
+ "connectorId": {
+ "type": "integer"
+ },
+ "errorCode": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "ConnectorLockFailure",
+ "EVCommunicationError",
+ "GroundFailure",
+ "HighTemperature",
+ "InternalError",
+ "LocalListConflict",
+ "NoError",
+ "OtherError",
+ "OverCurrentFailure",
+ "PowerMeterFailure",
+ "PowerSwitchFailure",
+ "ReaderFailure",
+ "ResetFailure",
+ "UnderVoltage",
+ "OverVoltage",
+ "WeakSignal"
+ ]
+ },
+ "info": {
+ "type": "string",
+ "maxLength": 50
+ },
+ "status": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "Available",
+ "Preparing",
+ "Charging",
+ "SuspendedEVSE",
+ "SuspendedEV",
+ "Finishing",
+ "Reserved",
+ "Unavailable",
+ "Faulted"
+ ]
+ },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "vendorId": {
+ "type": "string",
+ "maxLength": 255
+ },
+ "vendorErrorCode": {
+ "type": "string",
+ "maxLength": 50
+ }
+ },
+ "additionalProperties": false,
+ "required": ["connectorId", "errorCode", "status"]
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:StopTransactionRequest",
+ "title": "StopTransactionRequest",
+ "type": "object",
+ "properties": {
+ "idTag": {
+ "type": "string",
+ "maxLength": 20
+ },
+ "meterStop": {
+ "type": "integer"
+ },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "transactionId": {
+ "type": "integer"
+ },
+ "reason": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "EmergencyStop",
+ "EVDisconnected",
+ "HardReset",
+ "Local",
+ "Other",
+ "PowerLoss",
+ "Reboot",
+ "Remote",
+ "SoftReset",
+ "UnlockCommand",
+ "DeAuthorized"
+ ]
+ },
+ "transactionData": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "timestamp": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "sampledValue": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "value": {
+ "type": "string"
+ },
+ "context": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "Interruption.Begin",
+ "Interruption.End",
+ "Sample.Clock",
+ "Sample.Periodic",
+ "Transaction.Begin",
+ "Transaction.End",
+ "Trigger",
+ "Other"
+ ]
+ },
+ "format": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["Raw", "SignedData"]
+ },
+ "measurand": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "Energy.Active.Export.Register",
+ "Energy.Active.Import.Register",
+ "Energy.Reactive.Export.Register",
+ "Energy.Reactive.Import.Register",
+ "Energy.Active.Export.Interval",
+ "Energy.Active.Import.Interval",
+ "Energy.Reactive.Export.Interval",
+ "Energy.Reactive.Import.Interval",
+ "Power.Active.Export",
+ "Power.Active.Import",
+ "Power.Offered",
+ "Power.Reactive.Export",
+ "Power.Reactive.Import",
+ "Power.Factor",
+ "Current.Import",
+ "Current.Export",
+ "Current.Offered",
+ "Voltage",
+ "Frequency",
+ "Temperature",
+ "SoC",
+ "RPM"
+ ]
+ },
+ "phase": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["L1", "L2", "L3", "N", "L1-N", "L2-N", "L3-N", "L1-L2", "L2-L3", "L3-L1"]
+ },
+ "location": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["Cable", "EV", "Inlet", "Outlet", "Body"]
+ },
+ "unit": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": [
+ "Wh",
+ "kWh",
+ "varh",
+ "kvarh",
+ "W",
+ "kW",
+ "VA",
+ "kVA",
+ "var",
+ "kvar",
+ "A",
+ "V",
+ "K",
+ "Celcius",
+ "Fahrenheit",
+ "Percent"
+ ]
+ }
+ },
+ "additionalProperties": false,
+ "required": ["value"]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["timestamp", "sampledValue"]
+ }
+ }
+ },
+ "additionalProperties": false,
+ "required": ["transactionId", "timestamp", "meterStop"]
+}
import tar from 'tar';
import OCPPError from '../../../exception/OCPPError';
-import { JsonType } from '../../../types/JsonType';
+import { JsonObject, JsonType } from '../../../types/JsonType';
import { OCPP16ChargePointErrorCode } from '../../../types/ocpp/1.6/ChargePointErrorCode';
import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus';
import {
export default class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
private incomingRequestHandlers: Map<OCPP16IncomingRequestCommand, IncomingRequestHandler>;
- private resetJsonSchema: JSONSchemaType<ResetRequest>;
- private clearCacheJsonSchema: JSONSchemaType<OCPP16ClearCacheRequest>;
- private getConfigurationJsonSchema: JSONSchemaType<GetConfigurationRequest>;
- private changeConfigurationJsonSchema: JSONSchemaType<ChangeConfigurationRequest>;
- private unlockConnectorJsonSchema: JSONSchemaType<UnlockConnectorRequest>;
- private getDiagnosticsJsonSchema: JSONSchemaType<GetDiagnosticsRequest>;
- private setChargingProfileJsonSchema: JSONSchemaType<SetChargingProfileRequest>;
- private clearChargingProfileJsonSchema: JSONSchemaType<ClearChargingProfileRequest>;
- private changeAvailabilityJsonSchema: JSONSchemaType<ChangeAvailabilityRequest>;
- private remoteStartTransactionJsonSchema: JSONSchemaType<RemoteStartTransactionRequest>;
- private remoteStopTransactionJsonSchema: JSONSchemaType<RemoteStopTransactionRequest>;
- private triggerMessageJsonSchema: JSONSchemaType<OCPP16TriggerMessageRequest>;
+ private jsonSchemas: Map<OCPP16IncomingRequestCommand, JSONSchemaType<JsonObject>>;
public constructor() {
if (new.target?.name === moduleName) {
[OCPP16IncomingRequestCommand.GET_DIAGNOSTICS, this.handleRequestGetDiagnostics.bind(this)],
[OCPP16IncomingRequestCommand.TRIGGER_MESSAGE, this.handleRequestTriggerMessage.bind(this)],
]);
- this.resetJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/Reset.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<ResetRequest>;
- this.clearCacheJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/ClearCache.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16ClearCacheRequest>;
- this.getConfigurationJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/GetConfiguration.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<GetConfigurationRequest>;
- this.changeConfigurationJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/ChangeConfiguration.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<ChangeConfigurationRequest>;
- this.unlockConnectorJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/UnlockConnector.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<UnlockConnectorRequest>;
- this.getDiagnosticsJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/GetDiagnostics.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<GetDiagnosticsRequest>;
- this.setChargingProfileJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/SetChargingProfile.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<SetChargingProfileRequest>;
- this.clearChargingProfileJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfile.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<ClearChargingProfileRequest>;
- this.changeAvailabilityJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/ChangeAvailability.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<ChangeAvailabilityRequest>;
- this.remoteStartTransactionJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransaction.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<RemoteStartTransactionRequest>;
- this.remoteStopTransactionJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransaction.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<RemoteStopTransactionRequest>;
- this.triggerMessageJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/TriggerMessage.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16TriggerMessageRequest>;
+ this.jsonSchemas = new Map<OCPP16IncomingRequestCommand, JSONSchemaType<JsonObject>>([
+ [
+ OCPP16IncomingRequestCommand.RESET,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/Reset.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ResetRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CLEAR_CACHE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ClearCache.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16ClearCacheRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.UNLOCK_CONNECTOR,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/UnlockConnector.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<UnlockConnectorRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.GET_CONFIGURATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/GetConfiguration.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<GetConfigurationRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ChangeConfiguration.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ChangeConfigurationRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/GetDiagnostics.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<GetDiagnosticsRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.SET_CHARGING_PROFILE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/SetChargingProfile.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<SetChargingProfileRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CLEAR_CHARGING_PROFILE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfile.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ClearChargingProfileRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ChangeAvailability.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ChangeAvailabilityRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransaction.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<RemoteStartTransactionRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransaction.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<RemoteStopTransactionRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/TriggerMessage.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16TriggerMessageRequest>,
+ ],
+ ]);
}
public async incomingRequestHandler(
ChargingStationUtils.isIncomingRequestCommandSupported(commandName, chargingStation)
) {
try {
+ if (this.jsonSchemas.has(commandName)) {
+ this.validateIncomingRequestPayload(
+ chargingStation,
+ commandName,
+ this.jsonSchemas.get(commandName),
+ commandPayload
+ );
+ } else {
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: No JSON schema found for command ${commandName} PDU validation`
+ );
+ }
// Call the method to build the response
response = await this.incomingRequestHandlers.get(commandName)(
chargingStation,
chargingStation: ChargingStation,
commandPayload: ResetRequest
): DefaultResponse {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.RESET,
- this.resetJsonSchema,
- commandPayload
- );
// eslint-disable-next-line @typescript-eslint/no-misused-promises
setImmediate(async (): Promise<void> => {
await chargingStation.reset((commandPayload.type + 'Reset') as OCPP16StopTransactionReason);
return Constants.OCPP_RESPONSE_ACCEPTED;
}
- private handleRequestClearCache(
- chargingStation: ChargingStation,
- commandPayload: OCPP16ClearCacheRequest
- ): DefaultResponse {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.CLEAR_CACHE,
- this.clearCacheJsonSchema,
- commandPayload
- );
+ private handleRequestClearCache(): DefaultResponse {
return Constants.OCPP_RESPONSE_ACCEPTED;
}
chargingStation: ChargingStation,
commandPayload: UnlockConnectorRequest
): Promise<UnlockConnectorResponse> {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.UNLOCK_CONNECTOR,
- this.unlockConnectorJsonSchema,
- commandPayload
- );
const connectorId = commandPayload.connectorId;
if (connectorId === 0) {
logger.error(
chargingStation: ChargingStation,
commandPayload: GetConfigurationRequest
): GetConfigurationResponse {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.GET_CONFIGURATION,
- this.getConfigurationJsonSchema,
- commandPayload
- );
const configurationKey: OCPPConfigurationKey[] = [];
const unknownKey: string[] = [];
if (Utils.isEmptyArray(commandPayload.key)) {
chargingStation: ChargingStation,
commandPayload: ChangeConfigurationRequest
): ChangeConfigurationResponse {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION,
- this.changeConfigurationJsonSchema,
- commandPayload
- );
const keyToChange = ChargingStationConfigurationUtils.getConfigurationKey(
chargingStation,
commandPayload.key,
chargingStation: ChargingStation,
commandPayload: SetChargingProfileRequest
): SetChargingProfileResponse {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.SET_CHARGING_PROFILE,
- this.setChargingProfileJsonSchema,
- commandPayload
- );
if (
!OCPP16ServiceUtils.checkFeatureProfile(
chargingStation,
chargingStation: ChargingStation,
commandPayload: ClearChargingProfileRequest
): ClearChargingProfileResponse {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.CLEAR_CHARGING_PROFILE,
- this.clearChargingProfileJsonSchema,
- commandPayload
- );
if (
!OCPP16ServiceUtils.checkFeatureProfile(
chargingStation,
chargingStation: ChargingStation,
commandPayload: ChangeAvailabilityRequest
): Promise<ChangeAvailabilityResponse> {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY,
- this.changeAvailabilityJsonSchema,
- commandPayload
- );
const connectorId: number = commandPayload.connectorId;
if (!chargingStation.getConnectorStatus(connectorId)) {
logger.error(
chargingStation: ChargingStation,
commandPayload: RemoteStartTransactionRequest
): Promise<DefaultResponse> {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION,
- this.remoteStartTransactionJsonSchema,
- commandPayload
- );
const transactionConnectorId = commandPayload.connectorId;
const connectorStatus = chargingStation.getConnectorStatus(transactionConnectorId);
if (transactionConnectorId) {
chargingStation: ChargingStation,
commandPayload: RemoteStopTransactionRequest
): Promise<DefaultResponse> {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION,
- this.remoteStopTransactionJsonSchema,
- commandPayload
- );
const transactionId = commandPayload.transactionId;
for (const connectorId of chargingStation.connectors.keys()) {
if (
chargingStation: ChargingStation,
commandPayload: GetDiagnosticsRequest
): Promise<GetDiagnosticsResponse> {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
- this.getDiagnosticsJsonSchema,
- commandPayload
- );
if (
!OCPP16ServiceUtils.checkFeatureProfile(
chargingStation,
chargingStation: ChargingStation,
commandPayload: OCPP16TriggerMessageRequest
): OCPP16TriggerMessageResponse {
- this.validateIncomingRequestPayload(
- chargingStation,
- OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
- this.triggerMessageJsonSchema,
- commandPayload
- );
if (
!OCPP16ServiceUtils.checkFeatureProfile(
chargingStation,
// Partial Copyright Jerome Benoit. 2021. All Rights Reserved.
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+import { JSONSchemaType } from 'ajv';
+
import OCPPError from '../../../exception/OCPPError';
import { JsonObject, JsonType } from '../../../types/JsonType';
-import { OCPP16RequestCommand } from '../../../types/ocpp/1.6/Requests';
+import { OCPP16MeterValuesRequest } from '../../../types/ocpp/1.6/MeterValues';
+import {
+ DiagnosticsStatusNotificationRequest,
+ OCPP16BootNotificationRequest,
+ OCPP16HeartbeatRequest,
+ OCPP16RequestCommand,
+ OCPP16StatusNotificationRequest,
+} from '../../../types/ocpp/1.6/Requests';
+import {
+ OCPP16AuthorizeRequest,
+ OCPP16StartTransactionRequest,
+ OCPP16StopTransactionRequest,
+} from '../../../types/ocpp/1.6/Transaction';
import { ErrorType } from '../../../types/ocpp/ErrorType';
import { RequestParams } from '../../../types/ocpp/Requests';
import Constants from '../../../utils/Constants';
+import logger from '../../../utils/Logger';
import Utils from '../../../utils/Utils';
import type ChargingStation from '../../ChargingStation';
import { ChargingStationUtils } from '../../ChargingStationUtils';
const moduleName = 'OCPP16RequestService';
export default class OCPP16RequestService extends OCPPRequestService {
+ private jsonSchemas: Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>;
+
public constructor(ocppResponseService: OCPPResponseService) {
if (new.target?.name === moduleName) {
throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
}
super(ocppResponseService);
+ this.jsonSchemas = new Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>([
+ [
+ OCPP16RequestCommand.AUTHORIZE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/Authorize.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16AuthorizeRequest>,
+ ],
+ [
+ OCPP16RequestCommand.BOOT_NOTIFICATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/BootNotification.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16BootNotificationRequest>,
+ ],
+ [
+ OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotification.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<DiagnosticsStatusNotificationRequest>,
+ ],
+ [
+ OCPP16RequestCommand.HEARTBEAT,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/Heartbeat.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16HeartbeatRequest>,
+ ],
+ [
+ OCPP16RequestCommand.METER_VALUES,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/MeterValues.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16MeterValuesRequest>,
+ ],
+ [
+ OCPP16RequestCommand.STATUS_NOTIFICATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/StatusNotification.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16StatusNotificationRequest>,
+ ],
+ [
+ OCPP16RequestCommand.START_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/StartTransaction.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16StartTransactionRequest>,
+ ],
+ [
+ OCPP16RequestCommand.STOP_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/StopTransaction.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16StopTransactionRequest>,
+ ],
+ ]);
}
public async requestHandler<Request extends JsonType, Response extends JsonType>(
params?: RequestParams
): Promise<Response> {
if (ChargingStationUtils.isRequestCommandSupported(commandName, chargingStation)) {
+ const requestPayload = this.buildRequestPayload<Request>(
+ chargingStation,
+ commandName,
+ commandParams
+ );
+ if (this.jsonSchemas.has(commandName)) {
+ this.validateRequestPayload(
+ chargingStation,
+ commandName,
+ this.jsonSchemas.get(commandName),
+ requestPayload
+ );
+ } else {
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.requestHandler: No JSON schema found for command ${commandName} PDU validation`
+ );
+ }
return (await this.sendMessage(
chargingStation,
Utils.generateUUID(),
- this.buildRequestPayload<Request>(chargingStation, commandName, commandParams),
+ requestPayload,
commandName,
params
)) as unknown as Response;
import { JSONSchemaType } from 'ajv';
import OCPPError from '../../../exception/OCPPError';
-import { JsonType } from '../../../types/JsonType';
+import { JsonObject, JsonType } from '../../../types/JsonType';
import { OCPP16ChargePointErrorCode } from '../../../types/ocpp/1.6/ChargePointErrorCode';
import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus';
import { OCPP16StandardParametersKey } from '../../../types/ocpp/1.6/Configuration';
OCPP16StatusNotificationRequest,
} from '../../../types/ocpp/1.6/Requests';
import {
+ DiagnosticsStatusNotificationResponse,
OCPP16BootNotificationResponse,
OCPP16HeartbeatResponse,
OCPP16RegistrationStatus,
export default class OCPP16ResponseService extends OCPPResponseService {
private responseHandlers: Map<OCPP16RequestCommand, ResponseHandler>;
- private bootNotificationResponseJsonSchema: JSONSchemaType<OCPP16BootNotificationResponse>;
- private heartbeatResponseJsonSchema: JSONSchemaType<OCPP16HeartbeatResponse>;
- private authorizeResponseJsonSchema: JSONSchemaType<OCPP16AuthorizeResponse>;
- private startTransactionResponseJsonSchema: JSONSchemaType<OCPP16StartTransactionResponse>;
- private stopTransactionResponseJsonSchema: JSONSchemaType<OCPP16StopTransactionResponse>;
- private statusNotificationResponseJsonSchema: JSONSchemaType<OCPP16StatusNotificationResponse>;
- private meterValuesResponseJsonSchema: JSONSchemaType<OCPP16MeterValuesResponse>;
+ private jsonSchemas: Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>;
public constructor() {
if (new.target?.name === moduleName) {
super();
this.responseHandlers = new Map<OCPP16RequestCommand, ResponseHandler>([
[OCPP16RequestCommand.BOOT_NOTIFICATION, this.handleResponseBootNotification.bind(this)],
- [OCPP16RequestCommand.HEARTBEAT, this.handleResponseHeartbeat.bind(this)],
+ [OCPP16RequestCommand.HEARTBEAT, this.emptyResponseHandler.bind(this)],
[OCPP16RequestCommand.AUTHORIZE, this.handleResponseAuthorize.bind(this)],
[OCPP16RequestCommand.START_TRANSACTION, this.handleResponseStartTransaction.bind(this)],
[OCPP16RequestCommand.STOP_TRANSACTION, this.handleResponseStopTransaction.bind(this)],
- [OCPP16RequestCommand.STATUS_NOTIFICATION, this.handleResponseStatusNotification.bind(this)],
- [OCPP16RequestCommand.METER_VALUES, this.handleResponseMeterValues.bind(this)],
+ [OCPP16RequestCommand.STATUS_NOTIFICATION, this.emptyResponseHandler.bind(this)],
+ [OCPP16RequestCommand.METER_VALUES, this.emptyResponseHandler.bind(this)],
+ [OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, this.emptyResponseHandler.bind(this)],
+ ]);
+ this.jsonSchemas = new Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>([
+ [
+ OCPP16RequestCommand.BOOT_NOTIFICATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/BootNotificationResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16BootNotificationResponse>,
+ ],
+ [
+ OCPP16RequestCommand.HEARTBEAT,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/HeartbeatResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16HeartbeatResponse>,
+ ],
+ [
+ OCPP16RequestCommand.AUTHORIZE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/AuthorizeResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16AuthorizeResponse>,
+ ],
+ [
+ OCPP16RequestCommand.START_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/StartTransactionResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16StartTransactionResponse>,
+ ],
+ [
+ OCPP16RequestCommand.STOP_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/StopTransactionResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16StopTransactionResponse>,
+ ],
+ [
+ OCPP16RequestCommand.STATUS_NOTIFICATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16StatusNotificationResponse>,
+ ],
+ [
+ OCPP16RequestCommand.METER_VALUES,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/MeterValuesResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16MeterValuesResponse>,
+ ],
+ [
+ OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<DiagnosticsStatusNotificationResponse>,
+ ],
]);
- this.bootNotificationResponseJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/BootNotificationResponse.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16BootNotificationResponse>;
- this.heartbeatResponseJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/HeartbeatResponse.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16HeartbeatResponse>;
- this.authorizeResponseJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/AuthorizeResponse.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16AuthorizeResponse>;
- this.startTransactionResponseJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/StartTransactionResponse.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16StartTransactionResponse>;
- this.stopTransactionResponseJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/StopTransactionResponse.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16StopTransactionResponse>;
- this.statusNotificationResponseJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16StatusNotificationResponse>;
- this.meterValuesResponseJsonSchema = JSON.parse(
- fs.readFileSync(
- path.resolve(
- path.dirname(fileURLToPath(import.meta.url)),
- '../../../assets/json-schemas/ocpp/1.6/MeterValuesResponse.json'
- ),
- 'utf8'
- )
- ) as JSONSchemaType<OCPP16MeterValuesResponse>;
}
public async responseHandler(
ChargingStationUtils.isRequestCommandSupported(commandName, chargingStation)
) {
try {
+ if (this.jsonSchemas.has(commandName)) {
+ this.validateResponsePayload(
+ chargingStation,
+ commandName,
+ this.jsonSchemas.get(commandName),
+ payload
+ );
+ } else {
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.responseHandler: No JSON schema found for command ${commandName} PDU validation`
+ );
+ }
await this.responseHandlers.get(commandName)(chargingStation, payload, requestPayload);
} catch (error) {
logger.error(chargingStation.logPrefix() + ' Handle request response error: %j', error);
chargingStation: ChargingStation,
payload: OCPP16BootNotificationResponse
): void {
- this.validateResponsePayload(
- chargingStation,
- OCPP16RequestCommand.BOOT_NOTIFICATION,
- this.bootNotificationResponseJsonSchema,
- payload
- );
if (payload.status === OCPP16RegistrationStatus.ACCEPTED) {
ChargingStationConfigurationUtils.addConfigurationKey(
chargingStation,
}
}
- private handleResponseHeartbeat(
- chargingStation: ChargingStation,
- payload: OCPP16HeartbeatResponse
- ): void {
- this.validateResponsePayload(
- chargingStation,
- OCPP16RequestCommand.HEARTBEAT,
- this.heartbeatResponseJsonSchema,
- payload
- );
- }
-
private handleResponseAuthorize(
chargingStation: ChargingStation,
payload: OCPP16AuthorizeResponse,
requestPayload: OCPP16AuthorizeRequest
): void {
- this.validateResponsePayload(
- chargingStation,
- OCPP16RequestCommand.AUTHORIZE,
- this.authorizeResponseJsonSchema,
- payload
- );
let authorizeConnectorId: number;
for (const connectorId of chargingStation.connectors.keys()) {
if (
payload: OCPP16StartTransactionResponse,
requestPayload: OCPP16StartTransactionRequest
): Promise<void> {
- this.validateResponsePayload(
- chargingStation,
- OCPP16RequestCommand.START_TRANSACTION,
- this.startTransactionResponseJsonSchema,
- payload
- );
const connectorId = requestPayload.connectorId;
let transactionConnectorId: number;
payload: OCPP16StopTransactionResponse,
requestPayload: OCPP16StopTransactionRequest
): Promise<void> {
- this.validateResponsePayload(
- chargingStation,
- OCPP16RequestCommand.STOP_TRANSACTION,
- this.stopTransactionResponseJsonSchema,
- payload
- );
const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
requestPayload.transactionId
);
);
}
}
-
- private handleResponseStatusNotification(
- chargingStation: ChargingStation,
- payload: OCPP16StatusNotificationResponse
- ): void {
- this.validateResponsePayload(
- chargingStation,
- OCPP16RequestCommand.STATUS_NOTIFICATION,
- this.statusNotificationResponseJsonSchema,
- payload
- );
- }
-
- private handleResponseMeterValues(
- chargingStation: ChargingStation,
- payload: OCPP16MeterValuesResponse
- ): void {
- this.validateResponsePayload(
- chargingStation,
- OCPP16RequestCommand.METER_VALUES,
- this.meterValuesResponseJsonSchema,
- payload
- );
- }
}
+import { JSONSchemaType } from 'ajv';
+import Ajv from 'ajv-draft-04';
+import ajvFormats from 'ajv-formats';
+
import OCPPError from '../../exception/OCPPError';
import PerformanceStatistics from '../../performance/PerformanceStatistics';
import { EmptyObject } from '../../types/EmptyObject';
export default abstract class OCPPRequestService {
private static instance: OCPPRequestService | null = null;
+ private ajv: Ajv;
private readonly ocppResponseService: OCPPResponseService;
this.requestHandler.bind(this);
this.sendResponse.bind(this);
this.sendError.bind(this);
+ this.ajv = new Ajv();
+ ajvFormats(this.ajv);
}
public static getInstance<T extends OCPPRequestService>(
}
}
+ protected validateRequestPayload<T extends JsonType>(
+ chargingStation: ChargingStation,
+ commandName: RequestCommand,
+ schema: JSONSchemaType<T>,
+ payload: T
+ ): boolean {
+ if (!chargingStation.getPayloadSchemaValidation()) {
+ return true;
+ }
+ const validate = this.ajv.compile(schema);
+ if (validate(payload)) {
+ return true;
+ }
+ logger.error(
+ `${chargingStation.logPrefix()} ${moduleName}.validateRequestPayload: Request PDU is invalid: %j`,
+ validate.errors
+ );
+ throw new OCPPError(
+ ErrorType.FORMATION_VIOLATION,
+ 'Request PDU is invalid',
+ commandName,
+ JSON.stringify(validate.errors, null, 2)
+ );
+ }
+
private async internalSendMessage(
chargingStation: ChargingStation,
messageId: string,
);
}
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ protected emptyResponseHandler() {}
+
public abstract responseHandler(
chargingStation: ChargingStation,
commandName: RequestCommand,