import { fileURLToPath } from 'node:url';
import type { DefinedError, ErrorObject, JSONSchemaType } from 'ajv';
+import { isDate } from 'date-fns';
import { OCPP16Constants } from './1.6/OCPP16Constants';
import { OCPP20Constants } from './2.0/OCPP20Constants';
import { OCPPConstants } from './OCPPConstants';
-import { type ChargingStation, ChargingStationConfigurationUtils } from '../../charging-station';
+import { type ChargingStation, getConfigurationKey, getIdTagsFile } from '../../charging-station';
import { BaseError } from '../../exception';
import {
+ AuthorizationStatus,
+ type AuthorizeRequest,
+ type AuthorizeResponse,
ChargePointErrorCode,
+ type ConnectorStatus,
type ConnectorStatusEnum,
ErrorType,
FileType,
isNotEmptyString,
logPrefix,
logger,
+ min,
} from '../../utils';
export class OCPPServiceUtils {
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}'`,
public static convertDateToISOString<T extends JsonType>(obj: T): void {
for (const key in obj) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
- if (obj![key] instanceof Date) {
+ if (isDate(obj![key])) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
(obj![key] as string) = (obj![key] as Date).toISOString();
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
chargingStation.getConnectorStatus(connectorId)!.status = status;
}
+ public static async isIdTagAuthorized(
+ chargingStation: ChargingStation,
+ connectorId: number,
+ idTag: string,
+ ): Promise<boolean> {
+ if (!chargingStation.getLocalAuthListEnabled() && !chargingStation.getRemoteAuthorization()) {
+ logger.warn(
+ `${chargingStation.logPrefix()} The charging station expects to authorize RFID tags but nor local authorization nor remote authorization are enabled. Misbehavior may occur`,
+ );
+ }
+ if (
+ chargingStation.getLocalAuthListEnabled() === true &&
+ OCPPServiceUtils.isIdTagLocalAuthorized(chargingStation, idTag)
+ ) {
+ const connectorStatus: ConnectorStatus = chargingStation.getConnectorStatus(connectorId)!;
+ connectorStatus.localAuthorizeIdTag = idTag;
+ connectorStatus.idTagLocalAuthorized = true;
+ return true;
+ } else if (chargingStation.getRemoteAuthorization()) {
+ return await OCPPServiceUtils.isIdTagRemoteAuthorized(chargingStation, connectorId, idTag);
+ }
+ return false;
+ }
+
protected static checkConnectorStatusTransition(
chargingStation: ChargingStation,
connectorId: number,
}
if (
measurand !== MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER &&
- ChargingStationConfigurationUtils.getConfigurationKey(
+ getConfigurationKey(
chargingStation,
StandardParametersKey.MeterValuesSampledData,
)?.value?.includes(measurand) === false
phase &&
sampledValueTemplates[index]?.phase === phase &&
sampledValueTemplates[index]?.measurand === measurand &&
- ChargingStationConfigurationUtils.getConfigurationKey(
+ getConfigurationKey(
chargingStation,
StandardParametersKey.MeterValuesSampledData,
)?.value?.includes(measurand) === true
return sampledValueTemplates[index];
} else if (
!phase &&
- !sampledValueTemplates[index].phase &&
+ !sampledValueTemplates[index]?.phase &&
sampledValueTemplates[index]?.measurand === measurand &&
- ChargingStationConfigurationUtils.getConfigurationKey(
+ getConfigurationKey(
chargingStation,
StandardParametersKey.MeterValuesSampledData,
)?.value?.includes(measurand) === true
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,
- },
+ options?: { limitationEnabled?: boolean; unitMultiplier?: number },
): number {
options = {
...{
const parsedInt = parseInt(value);
const numberValue = isNaN(parsedInt) ? Infinity : parsedInt;
return options?.limitationEnabled
- ? Math.min(numberValue * options.unitMultiplier!, limit)
+ ? min(numberValue * options.unitMultiplier!, limit)
: numberValue * options.unitMultiplier!;
}
+ private static isIdTagLocalAuthorized(chargingStation: ChargingStation, idTag: string): boolean {
+ return (
+ chargingStation.hasIdTags() === true &&
+ isNotEmptyString(
+ chargingStation.idTagsCache
+ .getIdTags(getIdTagsFile(chargingStation.stationInfo)!)
+ ?.find((tag) => tag === idTag),
+ )
+ );
+ }
+
+ private static async isIdTagRemoteAuthorized(
+ chargingStation: ChargingStation,
+ connectorId: number,
+ idTag: string,
+ ): Promise<boolean> {
+ chargingStation.getConnectorStatus(connectorId)!.authorizeIdTag = idTag;
+ return (
+ (
+ await chargingStation.ocppRequestService.requestHandler<
+ AuthorizeRequest,
+ AuthorizeResponse
+ >(chargingStation, RequestCommand.AUTHORIZE, {
+ idTag,
+ })
+ )?.idTagInfo?.status === AuthorizationStatus.ACCEPTED
+ );
+ }
+
private static logPrefix = (
ocppVersion: OCPPVersion,
moduleName?: string,