import type { DefinedError, ErrorObject, JSONSchemaType } from 'ajv';
+import { OCPP16Constants, OCPP20Constants } from './internal';
import { type ChargingStation, ChargingStationConfigurationUtils } from '../../charging-station';
import { BaseError } from '../../exception';
import {
type SampledValueTemplate,
StandardParametersKey,
type StatusNotificationRequest,
+ type StatusNotificationResponse,
} from '../../types';
import { Constants, FileUtils, Utils, logger } from '../../utils';
): boolean {
if (connectorId < 0) {
logger.error(
- `${chargingStation.logPrefix()} ${ocppCommand} incoming request received with invalid connector Id ${connectorId}`
+ `${chargingStation.logPrefix()} ${ocppCommand} incoming request received with invalid connector id ${connectorId}`
);
return false;
}
if (obj[key] instanceof Date) {
(obj as JsonObject)[key] = (obj[key] as Date).toISOString();
} else if (obj[key] !== null && typeof obj[key] === 'object') {
- this.convertDateToISOString<T>(obj[key] as T);
+ OCPPServiceUtils.convertDateToISOString<T>(obj[key] as T);
}
}
}
}
}
+ public static startHeartbeatInterval(chargingStation: ChargingStation, interval: number): void {
+ if (!chargingStation.heartbeatSetInterval) {
+ chargingStation.startHeartbeat();
+ } else if (chargingStation.getHeartbeatInterval() !== interval) {
+ chargingStation.restartHeartbeat();
+ }
+ }
+
+ public static async sendAndSetConnectorStatus(
+ chargingStation: ChargingStation,
+ connectorId: number,
+ status: ConnectorStatusEnum
+ ) {
+ OCPPServiceUtils.checkConnectorStatusTransition(chargingStation, connectorId, status);
+ await chargingStation.ocppRequestService.requestHandler<
+ StatusNotificationRequest,
+ StatusNotificationResponse
+ >(
+ chargingStation,
+ RequestCommand.STATUS_NOTIFICATION,
+ OCPPServiceUtils.buildStatusNotificationRequest(chargingStation, connectorId, status)
+ );
+ chargingStation.getConnectorStatus(connectorId).status = status;
+ }
+
+ protected static checkConnectorStatusTransition(
+ chargingStation: ChargingStation,
+ connectorId: number,
+ status: ConnectorStatusEnum
+ ): boolean {
+ const fromStatus = chargingStation.getConnectorStatus(connectorId).status;
+ let transitionAllowed = false;
+ 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
+ ) {
+ transitionAllowed = true;
+ }
+ break;
+ 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
+ ) {
+ transitionAllowed = true;
+ }
+ break;
+ 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`
+ );
+ }
+ if (transitionAllowed === false) {
+ logger.warn(
+ `${chargingStation.logPrefix()} OCPP ${
+ chargingStation.stationInfo.ocppVersion
+ } connector id ${connectorId} status transition from '${
+ chargingStation.getConnectorStatus(connectorId).status
+ }' to '${status}' is not allowed`
+ );
+ }
+ return transitionAllowed;
+ }
+
protected static parseJsonSchemaFile<T extends JsonType>(
filePath: string,
ocppVersion: OCPPVersion,
const onPhaseStr = phase ? `on phase ${phase} ` : '';
if (Constants.SUPPORTED_MEASURANDS.includes(measurand) === false) {
logger.warn(
- `${chargingStation.logPrefix()} Trying to get unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}`
+ `${chargingStation.logPrefix()} Trying to get unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connector id ${connectorId}`
);
return;
}
)?.value?.includes(measurand) === false
) {
logger.debug(
- `${chargingStation.logPrefix()} Trying to get MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId} not found in '${
+ `${chargingStation.logPrefix()} Trying to get MeterValues measurand '${measurand}' ${onPhaseStr}in template on connector id ${connectorId} not found in '${
StandardParametersKey.MeterValuesSampledData
}' OCPP parameter`
);
) === false
) {
logger.warn(
- `${chargingStation.logPrefix()} Unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}`
+ `${chargingStation.logPrefix()} Unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connector id ${connectorId}`
);
} else if (
phase &&
}
}
if (measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) {
- const errorMsg = `Missing MeterValues for default measurand '${measurand}' in template on connectorId ${connectorId}`;
+ const errorMsg = `Missing MeterValues for default measurand '${measurand}' in template on connector id ${connectorId}`;
logger.error(`${chargingStation.logPrefix()} ${errorMsg}`);
throw new BaseError(errorMsg);
}
logger.debug(
- `${chargingStation.logPrefix()} No MeterValues for measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}`
+ `${chargingStation.logPrefix()} No MeterValues for measurand '${measurand}' ${onPhaseStr}in template on connector id ${connectorId}`
);
}