Skip to content

Commit

Permalink
Merge pull request #1032 from SAP/fix-reserved-start-transaction
Browse files Browse the repository at this point in the history
fix: send preparing connector status before `StartTransaction`
  • Loading branch information
Jérôme Benoit authored Apr 11, 2024
2 parents dbbe79a + 923ac72 commit fc9818e
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 46 deletions.
19 changes: 13 additions & 6 deletions src/charging-station/ChargingStation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2221,21 +2221,28 @@ export class ChargingStation extends EventEmitter {
for (const [evseId, evseStatus] of this.evses) {
if (evseId > 0) {
for (const [connectorId, connectorStatus] of evseStatus.connectors) {
const connectorBootStatus = getBootConnectorStatus(this, connectorId, connectorStatus)
await sendAndSetConnectorStatus(this, connectorId, connectorBootStatus, evseId)
await sendAndSetConnectorStatus(
this,
connectorId,
getBootConnectorStatus(this, connectorId, connectorStatus),
evseId
)
}
}
}
} else {
for (const connectorId of this.connectors.keys()) {
if (connectorId > 0) {
const connectorBootStatus = getBootConnectorStatus(
await sendAndSetConnectorStatus(
this,
connectorId,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.getConnectorStatus(connectorId)!
getBootConnectorStatus(
this,
connectorId,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.getConnectorStatus(connectorId)!
)
)
await sendAndSetConnectorStatus(this, connectorId, connectorBootStatus)
}
}
}
Expand Down
30 changes: 9 additions & 21 deletions src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
): Promise<GenericResponse> {
const { connectorId: transactionConnectorId, idTag, chargingProfile } = commandPayload
if (!chargingStation.hasConnector(transactionConnectorId)) {
return await this.notifyRemoteStartTransactionRejected(
return this.notifyRemoteStartTransactionRejected(
chargingStation,
transactionConnectorId,
idTag
Expand All @@ -1163,7 +1163,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
!chargingStation.isChargingStationAvailable() ||
!chargingStation.isConnectorAvailable(transactionConnectorId)
) {
return await this.notifyRemoteStartTransactionRejected(
return this.notifyRemoteStartTransactionRejected(
chargingStation,
transactionConnectorId,
idTag
Expand All @@ -1174,17 +1174,12 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
chargingStation.getAuthorizeRemoteTxRequests() &&
!(await OCPP16ServiceUtils.isIdTagAuthorized(chargingStation, transactionConnectorId, idTag))
) {
return await this.notifyRemoteStartTransactionRejected(
return this.notifyRemoteStartTransactionRejected(
chargingStation,
transactionConnectorId,
idTag
)
}
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
transactionConnectorId,
OCPP16ChargePointStatus.Preparing
)
if (
chargingProfile != null &&
!this.setRemoteStartTransactionChargingProfile(
Expand All @@ -1193,33 +1188,26 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
chargingProfile
)
) {
return await this.notifyRemoteStartTransactionRejected(
return this.notifyRemoteStartTransactionRejected(
chargingStation,
transactionConnectorId,
idTag
)
}
logger.debug(
`${chargingStation.logPrefix()} Remote start transaction ACCEPTED on connector id ${transactionConnectorId}, idTag '${idTag}'`
`${chargingStation.logPrefix()} Remote start transaction ACCEPTED on ${chargingStation.stationInfo?.chargingStationId}#${transactionConnectorId}}, idTag '${idTag}'`
)
return OCPP16Constants.OCPP_RESPONSE_ACCEPTED
}

private async notifyRemoteStartTransactionRejected (
private notifyRemoteStartTransactionRejected (
chargingStation: ChargingStation,
connectorId: number,
idTag: string
): Promise<GenericResponse> {
): GenericResponse {
const connectorStatus = chargingStation.getConnectorStatus(connectorId)
if (connectorStatus?.status !== OCPP16ChargePointStatus.Available) {
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
connectorId,
OCPP16ChargePointStatus.Available
)
}
logger.debug(
`${chargingStation.logPrefix()} Remote start transaction REJECTED on connector id ${connectorId}, idTag '${idTag}', availability '${connectorStatus?.availability}', status '${connectorStatus?.status}'`
`${chargingStation.logPrefix()} Remote start transaction REJECTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId}, idTag '${idTag}', availability '${connectorStatus?.availability}', status '${connectorStatus?.status}'`
)
return OCPP16Constants.OCPP_RESPONSE_REJECTED
}
Expand All @@ -1232,7 +1220,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
if (chargingProfile.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE) {
OCPP16ServiceUtils.setChargingProfile(chargingStation, connectorId, chargingProfile)
logger.debug(
`${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}: %j`,
`${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on ${chargingStation.stationInfo?.chargingStationId}#${connectorId}`,
chargingProfile
)
return true
Expand Down
12 changes: 11 additions & 1 deletion src/charging-station/ocpp/1.6/OCPP16RequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,21 @@ export class OCPP16RequestService extends OCPPRequestService {
public async requestHandler<RequestType extends JsonType, ResponseType extends JsonType>(
chargingStation: ChargingStation,
commandName: OCPP16RequestCommand,
commandParams?: JsonType,
commandParams?: RequestType,
params?: RequestParams
): Promise<ResponseType> {
// FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
if (OCPP16ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) {
// Post request actions hook
switch (commandName) {
case OCPP16RequestCommand.START_TRANSACTION:
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
(commandParams as OCPP16StartTransactionRequest).connectorId,
OCPP16ChargePointStatus.Preparing
)
break
}
return (await this.sendMessage(
chargingStation,
generateUUID(),
Expand Down
16 changes: 2 additions & 14 deletions src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -816,22 +816,10 @@ export class OCPP16ResponseService extends OCPPResponseService {
chargingStation: ChargingStation,
connectorId: number
): Promise<void> {
chargingStation.stopMeterValues(connectorId)
const connectorStatus = chargingStation.getConnectorStatus(connectorId)
resetConnectorStatus(connectorStatus)
chargingStation.stopMeterValues(connectorId)
if (chargingStation.getReservationBy('connectorId', connectorId) != null) {
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
connectorId,
OCPP16ChargePointStatus.Reserved
)
} else if (connectorStatus?.status !== OCPP16ChargePointStatus.Available) {
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
connectorId,
OCPP16ChargePointStatus.Available
)
}
await OCPP16ServiceUtils.restoreConnectorStatus(chargingStation, connectorId, connectorStatus)
}

private async handleResponseStopTransaction (
Expand Down
3 changes: 2 additions & 1 deletion src/charging-station/ocpp/2.0/OCPP20RequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ export class OCPP20RequestService extends OCPPRequestService {
public async requestHandler<RequestType extends JsonType, ResponseType extends JsonType>(
chargingStation: ChargingStation,
commandName: OCPP20RequestCommand,
commandParams?: JsonType,
commandParams?: RequestType,
params?: RequestParams
): Promise<ResponseType> {
// FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
if (OCPP20ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) {
// TODO: post request actions hook
return (await this.sendMessage(
chargingStation,
generateUUID(),
Expand Down
3 changes: 1 addition & 2 deletions src/charging-station/ocpp/OCPPRequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,7 @@ export abstract class OCPPRequestService {
public abstract requestHandler<ReqType extends JsonType, ResType extends JsonType>(
chargingStation: ChargingStation,
commandName: RequestCommand,
// FIXME: should be ReqType
commandParams?: JsonType,
commandParams?: ReqType,
params?: RequestParams
): Promise<ResType>
}
16 changes: 15 additions & 1 deletion src/charging-station/ocpp/OCPPServiceUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
type AuthorizeResponse,
ChargePointErrorCode,
ChargingStationEvents,
type ConnectorStatusEnum,
type ConnectorStatus,
ConnectorStatusEnum,
CurrentType,
ErrorType,
FileType,
Expand Down Expand Up @@ -194,6 +195,18 @@ export const sendAndSetConnectorStatus = async (
})
}

export const restoreConnectorStatus = async (
chargingStation: ChargingStation,
connectorId: number,
connectorStatus: ConnectorStatus | undefined
): Promise<void> => {
if (connectorStatus?.reservation != null) {
await sendAndSetConnectorStatus(chargingStation, connectorId, ConnectorStatusEnum.Reserved)
} else if (connectorStatus?.status !== ConnectorStatusEnum.Available) {
await sendAndSetConnectorStatus(chargingStation, connectorId, ConnectorStatusEnum.Available)
}
}

const checkConnectorStatusTransition = (
chargingStation: ChargingStation,
connectorId: number,
Expand Down Expand Up @@ -1228,6 +1241,7 @@ const getMeasurandDefaultLocation = (
export class OCPPServiceUtils {
public static readonly getMessageTypeString = getMessageTypeString
public static readonly sendAndSetConnectorStatus = sendAndSetConnectorStatus
public static readonly restoreConnectorStatus = restoreConnectorStatus
public static readonly isIdTagAuthorized = isIdTagAuthorized
public static readonly buildTransactionEndMeterValue = buildTransactionEndMeterValue
protected static getSampledValueTemplate = getSampledValueTemplate
Expand Down

0 comments on commit fc9818e

Please sign in to comment.