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>,
+ ],
+ ]);
+ this.validatePayload.bind(this);
}
public async incomingRequestHandler(
ChargingStationUtils.isIncomingRequestCommandSupported(commandName, chargingStation)
) {
try {
+ this.validatePayload(chargingStation, commandName, commandPayload);
// Call the method to build the response
response = await this.incomingRequestHandlers.get(commandName)(
chargingStation,
);
} catch (error) {
// Log
- logger.error(chargingStation.logPrefix() + ' Handle request error: %j', error);
+ logger.error(chargingStation.logPrefix() + ' Handle request error:', error);
throw error;
}
} else {
);
}
+ private validatePayload(
+ chargingStation: ChargingStation,
+ commandName: OCPP16IncomingRequestCommand,
+ commandPayload: JsonType
+ ): boolean {
+ if (this.jsonSchemas.has(commandName)) {
+ return this.validateIncomingRequestPayload(
+ chargingStation,
+ commandName,
+ this.jsonSchemas.get(commandName),
+ commandPayload
+ );
+ }
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command ${commandName} PDU validation`
+ );
+ return false;
+ }
+
// Simulate charging station restart
private handleRequestReset(
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,