-import fs from 'node:fs';
+import { readFileSync } from 'node:fs';
+import { dirname, join } from 'node:path';
+import { fileURLToPath } from 'node:url';
import type { DefinedError, ErrorObject, JSONSchemaType } from 'ajv';
-import { OCPP16Constants, OCPP20Constants } from './internal';
+import { OCPP16Constants } from './1.6/OCPP16Constants';
+import { OCPP20Constants } from './2.0/OCPP20Constants';
+import { OCPPConstants } from './OCPPConstants';
import { type ChargingStation, ChargingStationConfigurationUtils } from '../../charging-station';
import { BaseError } from '../../exception';
import {
type StatusNotificationRequest,
type StatusNotificationResponse,
} from '../../types';
-import { Constants, FileUtils, Utils, logger } from '../../utils';
+import { Utils, handleFileException, logger } from '../../utils';
export class OCPPServiceUtils {
protected constructor() {
public static buildStatusNotificationRequest(
chargingStation: ChargingStation,
connectorId: number,
- status: ConnectorStatusEnum
+ status: ConnectorStatusEnum,
+ evseId?: number
): StatusNotificationRequest {
switch (chargingStation.stationInfo.ocppVersion ?? OCPPVersion.VERSION_16) {
case OCPPVersion.VERSION_16:
timestamp: new Date(),
connectorStatus: status,
connectorId,
- evseId: connectorId,
+ evseId,
} as OCPP20StatusNotificationRequest;
default:
throw new BaseError('Cannot build status notification payload: OCPP version not supported');
public static async sendAndSetConnectorStatus(
chargingStation: ChargingStation,
connectorId: number,
- status: ConnectorStatusEnum
+ status: ConnectorStatusEnum,
+ evseId?: number,
+ options: { send: boolean } = { send: true }
) {
- OCPPServiceUtils.checkConnectorStatusTransition(chargingStation, connectorId, status);
- await chargingStation.ocppRequestService.requestHandler<
- StatusNotificationRequest,
- StatusNotificationResponse
- >(
- chargingStation,
- RequestCommand.STATUS_NOTIFICATION,
- OCPPServiceUtils.buildStatusNotificationRequest(chargingStation, connectorId, status)
- );
+ options = { send: true, ...options };
+ if (options.send) {
+ OCPPServiceUtils.checkConnectorStatusTransition(chargingStation, connectorId, status);
+ await chargingStation.ocppRequestService.requestHandler<
+ StatusNotificationRequest,
+ StatusNotificationResponse
+ >(
+ chargingStation,
+ RequestCommand.STATUS_NOTIFICATION,
+ OCPPServiceUtils.buildStatusNotificationRequest(
+ chargingStation,
+ connectorId,
+ status,
+ evseId
+ )
+ );
+ }
chargingStation.getConnectorStatus(connectorId).status = status;
}
switch (chargingStation.stationInfo.ocppVersion) {
case OCPPVersion.VERSION_16:
if (
- connectorId === 0 &&
- OCPP16Constants.ChargePointStatusChargingStationTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
- ) !== -1
- ) {
- transitionAllowed = true;
- } else if (
- OCPP16Constants.ChargePointStatusConnectorTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
- ) !== -1
+ (connectorId === 0 &&
+ OCPP16Constants.ChargePointStatusChargingStationTransitions.findIndex(
+ (transition) => transition.from === fromStatus && transition.to === status
+ ) !== -1) ||
+ (connectorId > 0 &&
+ OCPP16Constants.ChargePointStatusConnectorTransitions.findIndex(
+ (transition) => transition.from === fromStatus && transition.to === status
+ ) !== -1)
) {
transitionAllowed = true;
}
case OCPPVersion.VERSION_20:
case OCPPVersion.VERSION_201:
if (
- connectorId === 0 &&
- OCPP20Constants.ChargingStationStatusTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
- ) !== -1
- ) {
- transitionAllowed = true;
- } else if (
- OCPP20Constants.ConnectorStatusTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
- ) !== -1
+ (connectorId === 0 &&
+ OCPP20Constants.ChargingStationStatusTransitions.findIndex(
+ (transition) => transition.from === fromStatus && transition.to === status
+ ) !== -1) ||
+ (connectorId > 0 &&
+ OCPP20Constants.ConnectorStatusTransitions.findIndex(
+ (transition) => transition.from === fromStatus && transition.to === status
+ ) !== -1)
) {
transitionAllowed = true;
}
}
protected static parseJsonSchemaFile<T extends JsonType>(
- filePath: string,
+ relativePath: string,
ocppVersion: OCPPVersion,
moduleName?: string,
methodName?: string
): JSONSchemaType<T> {
+ const filePath = join(dirname(fileURLToPath(import.meta.url)), relativePath);
try {
- return JSON.parse(fs.readFileSync(filePath, 'utf8')) as JSONSchemaType<T>;
+ return JSON.parse(readFileSync(filePath, 'utf8')) as JSONSchemaType<T>;
} catch (error) {
- FileUtils.handleFileException(
+ handleFileException(
filePath,
FileType.JsonSchema,
error as NodeJS.ErrnoException,
phase?: MeterValuePhase
): SampledValueTemplate | undefined {
const onPhaseStr = phase ? `on phase ${phase} ` : '';
- if (Constants.SUPPORTED_MEASURANDS.includes(measurand) === false) {
+ if (OCPPConstants.OCPP_MEASURANDS_SUPPORTED.includes(measurand) === false) {
logger.warn(
`${chargingStation.logPrefix()} Trying to get unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connector id ${connectorId}`
);
index++
) {
if (
- Constants.SUPPORTED_MEASURANDS.includes(
+ OCPPConstants.OCPP_MEASURANDS_SUPPORTED.includes(
sampledValueTemplates[index]?.measurand ??
MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
) === false
unitMultiplier: 1,
}
): number {
- options.limitationEnabled = options?.limitationEnabled ?? true;
- options.unitMultiplier = options?.unitMultiplier ?? 1;
+ options = {
+ ...{
+ limitationEnabled: true,
+ unitMultiplier: 1,
+ },
+ ...options,
+ };
const parsedInt = parseInt(value);
const numberValue = isNaN(parsedInt) ? Infinity : parsedInt;
return options?.limitationEnabled