type AuthorizeRequest,
type AuthorizeResponse,
ChargePointErrorCode,
+ ChargingStationEvents,
type ConnectorStatus,
type ConnectorStatusEnum,
ErrorType,
isNotEmptyString,
logPrefix,
logger,
+ max,
+ min,
} from '../../utils';
export class OCPPServiceUtils {
// This is intentional
}
- public static ajvErrorsToErrorType(errors: ErrorObject[]): ErrorType {
- for (const error of errors as DefinedError[]) {
- switch (error.keyword) {
- case 'type':
- return ErrorType.TYPE_CONSTRAINT_VIOLATION;
- case 'dependencies':
- case 'required':
- return ErrorType.OCCURRENCE_CONSTRAINT_VIOLATION;
- case 'pattern':
- case 'format':
- return ErrorType.PROPERTY_CONSTRAINT_VIOLATION;
+ public static ajvErrorsToErrorType(errors: ErrorObject[] | null | undefined): ErrorType {
+ if (isNotEmptyArray(errors) === true) {
+ for (const error of errors as DefinedError[]) {
+ switch (error.keyword) {
+ case 'type':
+ return ErrorType.TYPE_CONSTRAINT_VIOLATION;
+ case 'dependencies':
+ case 'required':
+ return ErrorType.OCCURRENCE_CONSTRAINT_VIOLATION;
+ case 'pattern':
+ case 'format':
+ return ErrorType.PROPERTY_CONSTRAINT_VIOLATION;
+ }
}
}
return ErrorType.FORMAT_VIOLATION;
return true;
} else if (
isRequestCommand === true &&
- chargingStation.stationInfo?.commandsSupport?.outgoingCommands
+ chargingStation.stationInfo?.commandsSupport?.outgoingCommands?.[command]
) {
- return chargingStation.stationInfo?.commandsSupport?.outgoingCommands[command] ?? false;
+ return chargingStation.stationInfo?.commandsSupport?.outgoingCommands[command];
}
logger.error(`${chargingStation.logPrefix()} Unknown outgoing OCPP command '${command}'`);
return false;
return true;
} else if (
isIncomingRequestCommand === true &&
- chargingStation.stationInfo?.commandsSupport?.incomingCommands
+ chargingStation.stationInfo?.commandsSupport?.incomingCommands?.[command]
) {
- return chargingStation.stationInfo?.commandsSupport?.incomingCommands[command] ?? false;
+ return chargingStation.stationInfo?.commandsSupport?.incomingCommands[command];
}
logger.error(`${chargingStation.logPrefix()} Unknown incoming OCPP command '${command}'`);
return false;
const isMessageTrigger = Object.values(MessageTrigger).includes(messageTrigger);
if (isMessageTrigger === true && !chargingStation.stationInfo?.messageTriggerSupport) {
return true;
- } else if (isMessageTrigger === true && chargingStation.stationInfo?.messageTriggerSupport) {
- return chargingStation.stationInfo?.messageTriggerSupport[messageTrigger] ?? false;
+ } else if (
+ isMessageTrigger === true &&
+ chargingStation.stationInfo?.messageTriggerSupport?.[messageTrigger]
+ ) {
+ return chargingStation.stationInfo?.messageTriggerSupport[messageTrigger];
}
logger.error(
`${chargingStation.logPrefix()} Unknown incoming OCPP message trigger '${messageTrigger}'`,
status: ConnectorStatusEnum,
evseId?: number,
): StatusNotificationRequest {
- switch (chargingStation.stationInfo.ocppVersion ?? OCPPVersion.VERSION_16) {
+ switch (chargingStation.stationInfo?.ocppVersion) {
case OCPPVersion.VERSION_16:
return {
connectorId,
);
}
chargingStation.getConnectorStatus(connectorId)!.status = status;
+ chargingStation.emit(ChargingStationEvents.connectorStatusChanged, {
+ connectorId,
+ ...chargingStation.getConnectorStatus(connectorId),
+ });
}
public static async isIdTagAuthorized(
connectorId: number,
idTag: string,
): Promise<boolean> {
- if (!chargingStation.getLocalAuthListEnabled() && !chargingStation.getRemoteAuthorization()) {
+ if (
+ !chargingStation.getLocalAuthListEnabled() &&
+ !chargingStation.stationInfo?.remoteAuthorization
+ ) {
logger.warn(
`${chargingStation.logPrefix()} The charging station expects to authorize RFID tags but nor local authorization nor remote authorization are enabled. Misbehavior may occur`,
);
}
- let authorized = false;
if (
chargingStation.getLocalAuthListEnabled() === true &&
OCPPServiceUtils.isIdTagLocalAuthorized(chargingStation, idTag)
const connectorStatus: ConnectorStatus = chargingStation.getConnectorStatus(connectorId)!;
connectorStatus.localAuthorizeIdTag = idTag;
connectorStatus.idTagLocalAuthorized = true;
- authorized = true;
- } else if (chargingStation.getRemoteAuthorization()) {
- authorized = await OCPPServiceUtils.isIdTagRemoteAuthorized(
- chargingStation,
- connectorId,
- idTag,
- );
+ return true;
+ } else if (chargingStation.stationInfo?.remoteAuthorization) {
+ return await OCPPServiceUtils.isIdTagRemoteAuthorized(chargingStation, connectorId, idTag);
}
- return authorized;
+ return false;
}
protected static checkConnectorStatusTransition(
): boolean {
const fromStatus = chargingStation.getConnectorStatus(connectorId)!.status;
let transitionAllowed = false;
- switch (chargingStation.stationInfo.ocppVersion) {
+ switch (chargingStation.stationInfo?.ocppVersion) {
case OCPPVersion.VERSION_16:
if (
(connectorId === 0 &&
default:
throw new BaseError(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
- `Cannot check connector status transition: OCPP version ${chargingStation.stationInfo.ocppVersion} not supported`,
+ `Cannot check connector status transition: OCPP version ${chargingStation.stationInfo?.ocppVersion} not supported`,
);
}
if (transitionAllowed === false) {
logger.warn(
- `${chargingStation.logPrefix()} OCPP ${
- chargingStation.stationInfo.ocppVersion
- } connector id ${connectorId} status transition from '${
+ `${chargingStation.logPrefix()} OCPP ${chargingStation.stationInfo
+ ?.ocppVersion} connector id ${connectorId} status transition from '${
chargingStation.getConnectorStatus(connectorId)!.status
}' to '${status}' is not allowed`,
);
return sampledValueTemplates[index];
} else if (
!phase &&
- !sampledValueTemplates[index].phase &&
+ !sampledValueTemplates[index]?.phase &&
sampledValueTemplates[index]?.measurand === measurand &&
getConfigurationKey(
chargingStation,
return sampledValueTemplates[index];
} else if (
measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER &&
- (!sampledValueTemplates[index].measurand ||
- sampledValueTemplates[index].measurand === measurand)
+ (!sampledValueTemplates[index]?.measurand ||
+ sampledValueTemplates[index]?.measurand === measurand)
) {
return sampledValueTemplates[index];
}
}
protected static getLimitFromSampledValueTemplateCustomValue(
- value: string,
- limit: number,
- options: { limitationEnabled?: boolean; unitMultiplier?: number } = {
- limitationEnabled: true,
- unitMultiplier: 1,
- },
+ value: string | undefined,
+ maxLimit: number,
+ minLimit: number,
+ options?: { limitationEnabled?: boolean; fallbackValue?: number; unitMultiplier?: number },
): number {
options = {
...{
limitationEnabled: true,
unitMultiplier: 1,
+ fallbackValue: 0,
},
...options,
};
- const parsedInt = parseInt(value);
- const numberValue = isNaN(parsedInt) ? Infinity : parsedInt;
- return options?.limitationEnabled
- ? Math.min(numberValue * options.unitMultiplier!, limit)
- : numberValue * options.unitMultiplier!;
+ const parsedValue = parseInt(value ?? '');
+ if (options?.limitationEnabled) {
+ return max(
+ min((!isNaN(parsedValue) ? parsedValue : Infinity) * options.unitMultiplier!, maxLimit),
+ minLimit,
+ );
+ }
+ return (!isNaN(parsedValue) ? parsedValue : options.fallbackValue!) * options.unitMultiplier!;
}
private static isIdTagLocalAuthorized(chargingStation: ChargingStation, idTag: string): boolean {