import { parentPort } from 'node:worker_threads';
import type { JSONSchemaType } from 'ajv';
+import { secondsToMilliseconds } from 'date-fns';
import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
import {
type ChargingStation,
addConfigurationKey,
getConfigurationKey,
+ hasReservationExpired,
resetConnectorStatus,
} from '../../../charging-station';
import { OCPPError } from '../../../exception';
import {
- type ChangeAvailabilityResponse,
type ChangeConfigurationResponse,
type ClearChargingProfileResponse,
ErrorType,
type OCPP16AuthorizeRequest,
type OCPP16AuthorizeResponse,
type OCPP16BootNotificationResponse,
+ type OCPP16ChangeAvailabilityResponse,
OCPP16ChargePointStatus,
type OCPP16DataTransferResponse,
type OCPP16DiagnosticsStatusNotificationResponse,
type OCPP16UpdateFirmwareResponse,
OCPPVersion,
RegistrationStatusEnumType,
+ ReservationTerminationReason,
type ResponseHandler,
type SetChargingProfileResponse,
type UnlockConnectorResponse,
],
[
OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY,
- OCPP16ServiceUtils.parseJsonSchemaFile<ChangeAvailabilityResponse>(
+ OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16ChangeAvailabilityResponse>(
'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
moduleName,
'constructor',
}
const authorizeConnectorIdDefined = !isNullOrUndefined(authorizeConnectorId);
if (payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) {
- authorizeConnectorIdDefined &&
- (chargingStation.getConnectorStatus(authorizeConnectorId!)!.idTagAuthorized = true);
+ if (authorizeConnectorIdDefined) {
+ // chargingStation.getConnectorStatus(authorizeConnectorId!)!.authorizeIdTag =
+ // requestPayload.idTag;
+ chargingStation.getConnectorStatus(authorizeConnectorId!)!.idTagAuthorized = true;
+ }
logger.debug(
`${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : ''
true &&
chargingStation.getAuthorizeRemoteTxRequests() === true &&
chargingStation.getLocalAuthListEnabled() === true &&
- chargingStation.hasIdTags() &&
+ chargingStation.hasIdTags() === true &&
chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false
) {
logger.error(
chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
true &&
chargingStation.getAuthorizeRemoteTxRequests() === true &&
- chargingStation.getMustAuthorizeAtRemoteStart() === true &&
+ chargingStation.getRemoteAuthorization() === true &&
chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
) {
);
return;
}
- if (!Number.isInteger(payload.transactionId)) {
+ if (!Number.isSafeInteger(payload.transactionId)) {
logger.warn(
`${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()} with a non integer transaction id ${
payload.transactionId
transactionConnectorId,
requestPayload.meterStart,
);
+ if (requestPayload.reservationId) {
+ const reservation = chargingStation.getReservationBy(
+ 'reservationId',
+ requestPayload.reservationId,
+ )!;
+ if (reservation.idTag !== requestPayload.idTag) {
+ logger.warn(
+ `${chargingStation.logPrefix()} Reserved transaction ${
+ payload.transactionId
+ } started with a different idTag ${requestPayload.idTag} than the reservation one ${
+ reservation.idTag
+ }`,
+ );
+ }
+ if (hasReservationExpired(reservation)) {
+ logger.warn(
+ `${chargingStation.logPrefix()} Reserved transaction ${
+ payload.transactionId
+ } started with expired reservation ${
+ requestPayload.reservationId
+ } (expiry date: ${reservation.expiryDate.toISOString()}))`,
+ );
+ }
+ await chargingStation.removeReservation(
+ reservation,
+ ReservationTerminationReason.TRANSACTION_STARTED,
+ );
+ }
chargingStation.getBeginEndMeterValues() &&
(await chargingStation.ocppRequestService.requestHandler<
OCPP16MeterValuesRequest,
chargingStation.startMeterValues(
transactionConnectorId,
configuredMeterValueSampleInterval
- ? convertToInt(configuredMeterValueSampleInterval.value) * 1000
+ ? secondsToMilliseconds(convertToInt(configuredMeterValueSampleInterval.value))
: Constants.DEFAULT_METER_VALUES_INTERVAL,
);
} else {
logger.warn(
- `${chargingStation.logPrefix()} Starting transaction with id ${payload.transactionId.toString()} REJECTED with status '${payload
- .idTagInfo?.status}', idTag '${requestPayload.idTag}'`,
+ `${chargingStation.logPrefix()} Starting transaction with id ${payload.transactionId.toString()} REJECTED on ${
+ chargingStation.stationInfo.chargingStationId
+ }#${transactionConnectorId.toString()} with status '${payload.idTagInfo?.status}', idTag '${
+ requestPayload.idTag
+ }'${
+ OCPP16ServiceUtils.hasReservation(
+ chargingStation,
+ transactionConnectorId,
+ requestPayload.idTag,
+ )
+ ? `, reservationId '${requestPayload.reservationId}'`
+ : ''
+ }`,
);
await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
}
): Promise<void> {
resetConnectorStatus(chargingStation.getConnectorStatus(connectorId)!);
chargingStation.stopMeterValues(connectorId);
- parentPort?.postMessage(buildUpdatedMessage(chargingStation));
if (
chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
) {
OCPP16ChargePointStatus.Available,
);
}
+ parentPort?.postMessage(buildUpdatedMessage(chargingStation));
}
private async handleResponseStopTransaction(