await this.chargingStation.ocppRequestService.requestHandler<
AuthorizeRequest,
AuthorizeResponse
- >(RequestCommand.AUTHORIZE, {
+ >(this.chargingStation, RequestCommand.AUTHORIZE, {
idTag,
});
this.connectorsStatus.get(connectorId).authorizeRequests++;
startResponse = await this.chargingStation.ocppRequestService.requestHandler<
StartTransactionRequest,
StartTransactionResponse
- >(RequestCommand.START_TRANSACTION, {
+ >(this.chargingStation, RequestCommand.START_TRANSACTION, {
connectorId,
idTag,
});
startResponse = await this.chargingStation.ocppRequestService.requestHandler<
StartTransactionRequest,
StartTransactionResponse
- >(RequestCommand.START_TRANSACTION, {
+ >(this.chargingStation, RequestCommand.START_TRANSACTION, {
connectorId,
idTag,
});
startResponse = await this.chargingStation.ocppRequestService.requestHandler<
StartTransactionRequest,
StartTransactionResponse
- >(RequestCommand.START_TRANSACTION, { connectorId });
+ >(this.chargingStation, RequestCommand.START_TRANSACTION, { connectorId });
PerformanceStatistics.endMeasure(measureId, beginId);
return startResponse;
}
await this.chargingStation.ocppRequestService.requestHandler<
MeterValuesRequest,
MeterValuesResponse
- >(RequestCommand.METER_VALUES, {
+ >(this.chargingStation, RequestCommand.METER_VALUES, {
connectorId,
transactionId,
meterValue: transactionEndMeterValue,
stopResponse = await this.chargingStation.ocppRequestService.requestHandler<
StopTransactionRequest,
StopTransactionResponse
- >(RequestCommand.STOP_TRANSACTION, {
+ >(this.chargingStation, RequestCommand.STOP_TRANSACTION, {
transactionId,
meterStop: this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
idTag: this.chargingStation.getTransactionIdTag(transactionId),
// eslint-disable-next-line @typescript-eslint/no-misused-promises
this.heartbeatSetInterval = setInterval(async (): Promise<void> => {
await this.ocppRequestService.requestHandler<HeartbeatRequest, HeartbeatResponse>(
+ this,
RequestCommand.HEARTBEAT
);
}, this.getHeartbeatInterval());
interval
);
await this.ocppRequestService.requestHandler<MeterValuesRequest, MeterValuesResponse>(
+ this,
RequestCommand.METER_VALUES,
{
connectorId,
await this.ocppRequestService.requestHandler<
StatusNotificationRequest,
StatusNotificationResponse
- >(RequestCommand.STATUS_NOTIFICATION, {
+ >(this, RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: ChargePointStatus.UNAVAILABLE,
errorCode: ChargePointErrorCode.NO_ERROR,
switch (this.getOcppVersion()) {
case OCPPVersion.VERSION_16:
this.ocppIncomingRequestService =
- OCPP16IncomingRequestService.getInstance<OCPP16IncomingRequestService>(this);
+ OCPP16IncomingRequestService.getInstance<OCPP16IncomingRequestService>();
this.ocppRequestService = OCPP16RequestService.getInstance<OCPP16RequestService>(
- this,
- OCPP16ResponseService.getInstance<OCPP16ResponseService>(this)
+ OCPP16ResponseService.getInstance<OCPP16ResponseService>()
);
break;
default:
BootNotificationRequest,
BootNotificationResponse
>(
+ this,
RequestCommand.BOOT_NOTIFICATION,
{
chargePointModel: this.bootNotificationRequest.chargePointModel,
);
// Process the message
await this.ocppIncomingRequestService.incomingRequestHandler(
+ this,
messageId,
commandName,
commandPayload
// Send error
messageType === MessageType.CALL_MESSAGE &&
(await this.ocppRequestService.sendError(
+ this,
messageId,
error as OCPPError,
commandName ?? requestCommandName ?? null
BootNotificationRequest,
BootNotificationResponse
>(
+ this,
RequestCommand.BOOT_NOTIFICATION,
{
chargePointModel: this.bootNotificationRequest.chargePointModel,
await this.ocppRequestService.requestHandler<
StatusNotificationRequest,
StatusNotificationResponse
- >(RequestCommand.STATUS_NOTIFICATION, {
+ >(this, RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: this.getConnectorStatus(connectorId).bootStatus,
errorCode: ChargePointErrorCode.NO_ERROR,
await this.ocppRequestService.requestHandler<
StatusNotificationRequest,
StatusNotificationResponse
- >(RequestCommand.STATUS_NOTIFICATION, {
+ >(this, RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: this.getConnectorStatus(connectorId).bootStatus,
errorCode: ChargePointErrorCode.NO_ERROR,
await this.ocppRequestService.requestHandler<
StatusNotificationRequest,
StatusNotificationResponse
- >(RequestCommand.STATUS_NOTIFICATION, {
+ >(this, RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: this.getConnectorStatus(connectorId).status,
errorCode: ChargePointErrorCode.NO_ERROR,
await this.ocppRequestService.requestHandler<
StatusNotificationRequest,
StatusNotificationResponse
- >(RequestCommand.STATUS_NOTIFICATION, {
+ >(this, RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: ChargePointStatus.AVAILABLE,
errorCode: ChargePointErrorCode.NO_ERROR,
this.getEnergyActiveImportRegisterByTransactionId(transactionId)
);
await this.ocppRequestService.requestHandler<MeterValuesRequest, MeterValuesResponse>(
+ this,
RequestCommand.METER_VALUES,
{
connectorId,
await this.ocppRequestService.requestHandler<
StopTransactionRequest,
StopTransactionResponse
- >(RequestCommand.STOP_TRANSACTION, {
+ >(this, RequestCommand.STOP_TRANSACTION, {
transactionId,
meterStop: this.getEnergyActiveImportRegisterByTransactionId(transactionId),
idTag: this.getTransactionIdTag(transactionId),
export default class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
private incomingRequestHandlers: Map<OCPP16IncomingRequestCommand, IncomingRequestHandler>;
- public constructor(chargingStation: ChargingStation) {
+ public constructor() {
if (new.target?.name === moduleName) {
throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
}
- super(chargingStation);
+ super();
this.incomingRequestHandlers = new Map<OCPP16IncomingRequestCommand, IncomingRequestHandler>([
[OCPP16IncomingRequestCommand.RESET, this.handleRequestReset.bind(this)],
[OCPP16IncomingRequestCommand.CLEAR_CACHE, this.handleRequestClearCache.bind(this)],
}
public async incomingRequestHandler(
+ chargingStation: ChargingStation,
messageId: string,
commandName: OCPP16IncomingRequestCommand,
commandPayload: JsonType
): Promise<void> {
let response: JsonType;
if (
- this.chargingStation.getOcppStrictCompliance() &&
- this.chargingStation.isInPendingState() &&
+ chargingStation.getOcppStrictCompliance() &&
+ chargingStation.isInPendingState() &&
(commandName === OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION ||
commandName === OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION)
) {
);
}
if (
- this.chargingStation.isRegistered() ||
- (!this.chargingStation.getOcppStrictCompliance() && this.chargingStation.isInUnknownState())
+ chargingStation.isRegistered() ||
+ (!chargingStation.getOcppStrictCompliance() && chargingStation.isInUnknownState())
) {
if (this.incomingRequestHandlers.has(commandName)) {
try {
// Call the method to build the response
- response = await this.incomingRequestHandlers.get(commandName)(commandPayload);
+ response = await this.incomingRequestHandlers.get(commandName)(
+ chargingStation,
+ commandPayload
+ );
} catch (error) {
// Log
- logger.error(this.chargingStation.logPrefix() + ' Handle request error: %j', error);
+ logger.error(chargingStation.logPrefix() + ' Handle request error: %j', error);
throw error;
}
} else {
);
}
// Send the built response
- await this.chargingStation.ocppRequestService.sendResponse(messageId, response, commandName);
+ await chargingStation.ocppRequestService.sendResponse(
+ chargingStation,
+ messageId,
+ response,
+ commandName
+ );
}
// Simulate charging station restart
- private handleRequestReset(commandPayload: ResetRequest): DefaultResponse {
+ private handleRequestReset(
+ chargingStation: ChargingStation,
+ commandPayload: ResetRequest
+ ): DefaultResponse {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
setImmediate(async (): Promise<void> => {
- await this.chargingStation.reset(
- (commandPayload.type + 'Reset') as OCPP16StopTransactionReason
- );
+ await chargingStation.reset((commandPayload.type + 'Reset') as OCPP16StopTransactionReason);
});
logger.info(
- `${this.chargingStation.logPrefix()} ${
+ `${chargingStation.logPrefix()} ${
commandPayload.type
} reset command received, simulating it. The station will be back online in ${Utils.formatDurationMilliSeconds(
- this.chargingStation.stationInfo.resetTime
+ chargingStation.stationInfo.resetTime
)}`
);
return Constants.OCPP_RESPONSE_ACCEPTED;
}
private async handleRequestUnlockConnector(
+ chargingStation: ChargingStation,
commandPayload: UnlockConnectorRequest
): Promise<UnlockConnectorResponse> {
const connectorId = commandPayload.connectorId;
if (connectorId === 0) {
logger.error(
- this.chargingStation.logPrefix() + ' Trying to unlock connector ' + connectorId.toString()
+ chargingStation.logPrefix() + ' Trying to unlock connector ' + connectorId.toString()
);
return Constants.OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED;
}
- if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted) {
- const transactionId = this.chargingStation.getConnectorStatus(connectorId).transactionId;
+ if (chargingStation.getConnectorStatus(connectorId)?.transactionStarted) {
+ const transactionId = chargingStation.getConnectorStatus(connectorId).transactionId;
if (
- this.chargingStation.getBeginEndMeterValues() &&
- this.chargingStation.getOcppStrictCompliance() &&
- !this.chargingStation.getOutOfOrderEndMeterValues()
+ chargingStation.getBeginEndMeterValues() &&
+ chargingStation.getOcppStrictCompliance() &&
+ !chargingStation.getOutOfOrderEndMeterValues()
) {
// FIXME: Implement OCPP version agnostic helpers
const transactionEndMeterValue = OCPP16ServiceUtils.buildTransactionEndMeterValue(
- this.chargingStation,
+ chargingStation,
connectorId,
- this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId)
+ chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId)
);
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16MeterValuesRequest,
OCPP16MeterValuesResponse
- >(OCPP16RequestCommand.METER_VALUES, {
+ >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
connectorId,
transactionId,
meterValue: transactionEndMeterValue,
});
}
- const stopResponse = await this.chargingStation.ocppRequestService.requestHandler<
+ const stopResponse = await chargingStation.ocppRequestService.requestHandler<
OCPP16StopTransactionRequest,
OCPP16StopTransactionResponse
- >(OCPP16RequestCommand.STOP_TRANSACTION, {
+ >(chargingStation, OCPP16RequestCommand.STOP_TRANSACTION, {
transactionId,
- meterStop: this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
- idTag: this.chargingStation.getTransactionIdTag(transactionId),
+ meterStop: chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
+ idTag: chargingStation.getTransactionIdTag(transactionId),
reason: OCPP16StopTransactionReason.UNLOCK_COMMAND,
});
if (stopResponse.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
}
return Constants.OCPP_RESPONSE_UNLOCK_FAILED;
}
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: OCPP16ChargePointStatus.AVAILABLE,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.AVAILABLE;
+ chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.AVAILABLE;
return Constants.OCPP_RESPONSE_UNLOCKED;
}
private handleRequestGetConfiguration(
+ chargingStation: ChargingStation,
commandPayload: GetConfigurationRequest
): GetConfigurationResponse {
const configurationKey: OCPPConfigurationKey[] = [];
const unknownKey: string[] = [];
if (Utils.isEmptyArray(commandPayload.key)) {
- for (const configuration of this.chargingStation.ocppConfiguration.configurationKey) {
+ for (const configuration of chargingStation.ocppConfiguration.configurationKey) {
if (Utils.isUndefined(configuration.visible)) {
configuration.visible = true;
}
}
} else {
for (const key of commandPayload.key) {
- const keyFound = this.chargingStation.getConfigurationKey(key);
+ const keyFound = chargingStation.getConfigurationKey(key);
if (keyFound) {
if (Utils.isUndefined(keyFound.visible)) {
keyFound.visible = true;
}
private handleRequestChangeConfiguration(
+ chargingStation: ChargingStation,
commandPayload: ChangeConfigurationRequest
): ChangeConfigurationResponse {
// JSON request fields type sanity check
if (!Utils.isString(commandPayload.key)) {
logger.error(
- `${this.chargingStation.logPrefix()} ${
+ `${chargingStation.logPrefix()} ${
OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION
} request key field is not a string:`,
commandPayload
}
if (!Utils.isString(commandPayload.value)) {
logger.error(
- `${this.chargingStation.logPrefix()} ${
+ `${chargingStation.logPrefix()} ${
OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION
} request value field is not a string:`,
commandPayload
);
}
- const keyToChange = this.chargingStation.getConfigurationKey(commandPayload.key, true);
+ const keyToChange = chargingStation.getConfigurationKey(commandPayload.key, true);
if (!keyToChange) {
return Constants.OCPP_CONFIGURATION_RESPONSE_NOT_SUPPORTED;
} else if (keyToChange && keyToChange.readonly) {
} else if (keyToChange && !keyToChange.readonly) {
let valueChanged = false;
if (keyToChange.value !== commandPayload.value) {
- this.chargingStation.setConfigurationKeyValue(
- commandPayload.key,
- commandPayload.value,
- true
- );
+ chargingStation.setConfigurationKeyValue(commandPayload.key, commandPayload.value, true);
valueChanged = true;
}
let triggerHeartbeatRestart = false;
if (keyToChange.key === OCPP16StandardParametersKey.HeartBeatInterval && valueChanged) {
- this.chargingStation.setConfigurationKeyValue(
+ chargingStation.setConfigurationKeyValue(
OCPP16StandardParametersKey.HeartbeatInterval,
commandPayload.value
);
triggerHeartbeatRestart = true;
}
if (keyToChange.key === OCPP16StandardParametersKey.HeartbeatInterval && valueChanged) {
- this.chargingStation.setConfigurationKeyValue(
+ chargingStation.setConfigurationKeyValue(
OCPP16StandardParametersKey.HeartBeatInterval,
commandPayload.value
);
triggerHeartbeatRestart = true;
}
if (triggerHeartbeatRestart) {
- this.chargingStation.restartHeartbeat();
+ chargingStation.restartHeartbeat();
}
if (keyToChange.key === OCPP16StandardParametersKey.WebSocketPingInterval && valueChanged) {
- this.chargingStation.restartWebSocketPing();
+ chargingStation.restartWebSocketPing();
}
if (keyToChange.reboot) {
return Constants.OCPP_CONFIGURATION_RESPONSE_REBOOT_REQUIRED;
}
private handleRequestSetChargingProfile(
+ chargingStation: ChargingStation,
commandPayload: SetChargingProfileRequest
): SetChargingProfileResponse {
if (
!OCPP16ServiceUtils.checkFeatureProfile(
- this.chargingStation,
+ chargingStation,
OCPP16SupportedFeatureProfiles.SmartCharging,
OCPP16IncomingRequestCommand.SET_CHARGING_PROFILE
)
) {
return Constants.OCPP_SET_CHARGING_PROFILE_RESPONSE_NOT_SUPPORTED;
}
- if (!this.chargingStation.getConnectorStatus(commandPayload.connectorId)) {
+ if (!chargingStation.getConnectorStatus(commandPayload.connectorId)) {
logger.error(
- `${this.chargingStation.logPrefix()} Trying to set charging profile(s) to a non existing connector Id ${
+ `${chargingStation.logPrefix()} Trying to set charging profile(s) to a non existing connector Id ${
commandPayload.connectorId
}`
);
commandPayload.csChargingProfiles.chargingProfilePurpose ===
ChargingProfilePurposeType.TX_PROFILE &&
(commandPayload.connectorId === 0 ||
- !this.chargingStation.getConnectorStatus(commandPayload.connectorId)?.transactionStarted)
+ !chargingStation.getConnectorStatus(commandPayload.connectorId)?.transactionStarted)
) {
return Constants.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED;
}
- this.chargingStation.setChargingProfile(
+ chargingStation.setChargingProfile(
commandPayload.connectorId,
commandPayload.csChargingProfiles
);
logger.debug(
- `${this.chargingStation.logPrefix()} Charging profile(s) set on connector id ${
+ `${chargingStation.logPrefix()} Charging profile(s) set on connector id ${
commandPayload.connectorId
}, dump their stack: %j`,
- this.chargingStation.getConnectorStatus(commandPayload.connectorId).chargingProfiles
+ chargingStation.getConnectorStatus(commandPayload.connectorId).chargingProfiles
);
return Constants.OCPP_SET_CHARGING_PROFILE_RESPONSE_ACCEPTED;
}
private handleRequestClearChargingProfile(
+ chargingStation: ChargingStation,
commandPayload: ClearChargingProfileRequest
): ClearChargingProfileResponse {
if (
!OCPP16ServiceUtils.checkFeatureProfile(
- this.chargingStation,
+ chargingStation,
OCPP16SupportedFeatureProfiles.SmartCharging,
OCPP16IncomingRequestCommand.CLEAR_CHARGING_PROFILE
)
) {
return Constants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN;
}
- const connectorStatus = this.chargingStation.getConnectorStatus(commandPayload.connectorId);
+ const connectorStatus = chargingStation.getConnectorStatus(commandPayload.connectorId);
if (!connectorStatus) {
logger.error(
- `${this.chargingStation.logPrefix()} Trying to clear a charging profile(s) to a non existing connector Id ${
+ `${chargingStation.logPrefix()} Trying to clear a charging profile(s) to a non existing connector Id ${
commandPayload.connectorId
}`
);
if (commandPayload.connectorId && !Utils.isEmptyArray(connectorStatus.chargingProfiles)) {
connectorStatus.chargingProfiles = [];
logger.debug(
- `${this.chargingStation.logPrefix()} Charging profile(s) cleared on connector id ${
+ `${chargingStation.logPrefix()} Charging profile(s) cleared on connector id ${
commandPayload.connectorId
}, dump their stack: %j`,
connectorStatus.chargingProfiles
}
if (!commandPayload.connectorId) {
let clearedCP = false;
- for (const connectorId of this.chargingStation.connectors.keys()) {
- if (
- !Utils.isEmptyArray(this.chargingStation.getConnectorStatus(connectorId).chargingProfiles)
- ) {
- this.chargingStation
+ for (const connectorId of chargingStation.connectors.keys()) {
+ if (!Utils.isEmptyArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) {
+ chargingStation
.getConnectorStatus(connectorId)
.chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => {
let clearCurrentCP = false;
if (clearCurrentCP) {
connectorStatus.chargingProfiles[index] = {} as OCPP16ChargingProfile;
logger.debug(
- `${this.chargingStation.logPrefix()} Matching charging profile(s) cleared on connector id ${
+ `${chargingStation.logPrefix()} Matching charging profile(s) cleared on connector id ${
commandPayload.connectorId
}, dump their stack: %j`,
connectorStatus.chargingProfiles
}
private async handleRequestChangeAvailability(
+ chargingStation: ChargingStation,
commandPayload: ChangeAvailabilityRequest
): Promise<ChangeAvailabilityResponse> {
const connectorId: number = commandPayload.connectorId;
- if (!this.chargingStation.getConnectorStatus(connectorId)) {
+ if (!chargingStation.getConnectorStatus(connectorId)) {
logger.error(
- `${this.chargingStation.logPrefix()} Trying to change the availability of a non existing connector Id ${connectorId.toString()}`
+ `${chargingStation.logPrefix()} Trying to change the availability of a non existing connector Id ${connectorId.toString()}`
);
return Constants.OCPP_AVAILABILITY_RESPONSE_REJECTED;
}
: OCPP16ChargePointStatus.UNAVAILABLE;
if (connectorId === 0) {
let response: ChangeAvailabilityResponse = Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED;
- for (const id of this.chargingStation.connectors.keys()) {
- if (this.chargingStation.getConnectorStatus(id)?.transactionStarted) {
+ for (const id of chargingStation.connectors.keys()) {
+ if (chargingStation.getConnectorStatus(id)?.transactionStarted) {
response = Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED;
}
- this.chargingStation.getConnectorStatus(id).availability = commandPayload.type;
+ chargingStation.getConnectorStatus(id).availability = commandPayload.type;
if (response === Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId: id,
status: chargePointStatus,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(id).status = chargePointStatus;
+ chargingStation.getConnectorStatus(id).status = chargePointStatus;
}
}
return response;
} else if (
connectorId > 0 &&
- (this.chargingStation.getConnectorStatus(0).availability ===
- OCPP16AvailabilityType.OPERATIVE ||
- (this.chargingStation.getConnectorStatus(0).availability ===
+ (chargingStation.getConnectorStatus(0).availability === OCPP16AvailabilityType.OPERATIVE ||
+ (chargingStation.getConnectorStatus(0).availability ===
OCPP16AvailabilityType.INOPERATIVE &&
commandPayload.type === OCPP16AvailabilityType.INOPERATIVE))
) {
- if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted) {
- this.chargingStation.getConnectorStatus(connectorId).availability = commandPayload.type;
+ if (chargingStation.getConnectorStatus(connectorId)?.transactionStarted) {
+ chargingStation.getConnectorStatus(connectorId).availability = commandPayload.type;
return Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED;
}
- this.chargingStation.getConnectorStatus(connectorId).availability = commandPayload.type;
- await this.chargingStation.ocppRequestService.requestHandler<
+ chargingStation.getConnectorStatus(connectorId).availability = commandPayload.type;
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: chargePointStatus,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(connectorId).status = chargePointStatus;
+ chargingStation.getConnectorStatus(connectorId).status = chargePointStatus;
return Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED;
}
return Constants.OCPP_AVAILABILITY_RESPONSE_REJECTED;
}
private async handleRequestRemoteStartTransaction(
+ chargingStation: ChargingStation,
commandPayload: RemoteStartTransactionRequest
): Promise<DefaultResponse> {
const transactionConnectorId = commandPayload.connectorId;
- const connectorStatus = this.chargingStation.getConnectorStatus(transactionConnectorId);
+ const connectorStatus = chargingStation.getConnectorStatus(transactionConnectorId);
if (transactionConnectorId) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId: transactionConnectorId,
status: OCPP16ChargePointStatus.PREPARING,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
connectorStatus.status = OCPP16ChargePointStatus.PREPARING;
- if (this.chargingStation.isChargingStationAvailable() && connectorStatus) {
+ if (chargingStation.isChargingStationAvailable() && connectorStatus) {
// Check if authorized
- if (this.chargingStation.getAuthorizeRemoteTxRequests()) {
+ if (chargingStation.getAuthorizeRemoteTxRequests()) {
let authorized = false;
if (
- this.chargingStation.getLocalAuthListEnabled() &&
- this.chargingStation.hasAuthorizedTags() &&
- this.chargingStation.authorizedTags.find((value) => value === commandPayload.idTag)
+ chargingStation.getLocalAuthListEnabled() &&
+ chargingStation.hasAuthorizedTags() &&
+ chargingStation.authorizedTags.find((value) => value === commandPayload.idTag)
) {
connectorStatus.localAuthorizeIdTag = commandPayload.idTag;
connectorStatus.idTagLocalAuthorized = true;
authorized = true;
- } else if (this.chargingStation.getMayAuthorizeAtRemoteStart()) {
+ } else if (chargingStation.getMayAuthorizeAtRemoteStart()) {
connectorStatus.authorizeIdTag = commandPayload.idTag;
const authorizeResponse: OCPP16AuthorizeResponse =
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16AuthorizeRequest,
OCPP16AuthorizeResponse
- >(OCPP16RequestCommand.AUTHORIZE, {
+ >(chargingStation, OCPP16RequestCommand.AUTHORIZE, {
idTag: commandPayload.idTag,
});
if (authorizeResponse?.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
}
} else {
logger.warn(
- `${this.chargingStation.logPrefix()} The charging station configuration expects authorize at remote start transaction but local authorization or authorize isn't enabled`
+ `${chargingStation.logPrefix()} The charging station configuration expects authorize at remote start transaction but local authorization or authorize isn't enabled`
);
}
if (authorized) {
// Authorization successful, start transaction
if (
this.setRemoteStartTransactionChargingProfile(
+ chargingStation,
transactionConnectorId,
commandPayload.chargingProfile
)
connectorStatus.transactionRemoteStarted = true;
if (
(
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StartTransactionRequest,
OCPP16StartTransactionResponse
- >(OCPP16RequestCommand.START_TRANSACTION, {
+ >(chargingStation, OCPP16RequestCommand.START_TRANSACTION, {
connectorId: transactionConnectorId,
idTag: commandPayload.idTag,
})
).idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED
) {
logger.debug(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Transaction remotely STARTED on ' +
- this.chargingStation.stationInfo.chargingStationId +
+ chargingStation.stationInfo.chargingStationId +
'#' +
transactionConnectorId.toString() +
' for idTag ' +
return Constants.OCPP_RESPONSE_ACCEPTED;
}
return this.notifyRemoteStartTransactionRejected(
+ chargingStation,
transactionConnectorId,
commandPayload.idTag
);
}
return this.notifyRemoteStartTransactionRejected(
+ chargingStation,
transactionConnectorId,
commandPayload.idTag
);
}
return this.notifyRemoteStartTransactionRejected(
+ chargingStation,
transactionConnectorId,
commandPayload.idTag
);
// No authorization check required, start transaction
if (
this.setRemoteStartTransactionChargingProfile(
+ chargingStation,
transactionConnectorId,
commandPayload.chargingProfile
)
connectorStatus.transactionRemoteStarted = true;
if (
(
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StartTransactionRequest,
OCPP16StartTransactionResponse
- >(OCPP16RequestCommand.START_TRANSACTION, {
+ >(chargingStation, OCPP16RequestCommand.START_TRANSACTION, {
connectorId: transactionConnectorId,
idTag: commandPayload.idTag,
})
).idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED
) {
logger.debug(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Transaction remotely STARTED on ' +
- this.chargingStation.stationInfo.chargingStationId +
+ chargingStation.stationInfo.chargingStationId +
'#' +
transactionConnectorId.toString() +
' for idTag ' +
return Constants.OCPP_RESPONSE_ACCEPTED;
}
return this.notifyRemoteStartTransactionRejected(
+ chargingStation,
transactionConnectorId,
commandPayload.idTag
);
}
return this.notifyRemoteStartTransactionRejected(
+ chargingStation,
transactionConnectorId,
commandPayload.idTag
);
}
return this.notifyRemoteStartTransactionRejected(
+ chargingStation,
transactionConnectorId,
commandPayload.idTag
);
}
- return this.notifyRemoteStartTransactionRejected(transactionConnectorId, commandPayload.idTag);
+ return this.notifyRemoteStartTransactionRejected(
+ chargingStation,
+ transactionConnectorId,
+ commandPayload.idTag
+ );
}
private async notifyRemoteStartTransactionRejected(
+ chargingStation: ChargingStation,
connectorId: number,
idTag: string
): Promise<DefaultResponse> {
if (
- this.chargingStation.getConnectorStatus(connectorId).status !==
- OCPP16ChargePointStatus.AVAILABLE
+ chargingStation.getConnectorStatus(connectorId).status !== OCPP16ChargePointStatus.AVAILABLE
) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: OCPP16ChargePointStatus.AVAILABLE,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(connectorId).status =
- OCPP16ChargePointStatus.AVAILABLE;
+ chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.AVAILABLE;
}
logger.warn(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Remote starting transaction REJECTED on connector Id ' +
connectorId.toString() +
', idTag ' +
idTag +
', availability ' +
- this.chargingStation.getConnectorStatus(connectorId).availability +
+ chargingStation.getConnectorStatus(connectorId).availability +
', status ' +
- this.chargingStation.getConnectorStatus(connectorId).status
+ chargingStation.getConnectorStatus(connectorId).status
);
return Constants.OCPP_RESPONSE_REJECTED;
}
private setRemoteStartTransactionChargingProfile(
+ chargingStation: ChargingStation,
connectorId: number,
cp: OCPP16ChargingProfile
): boolean {
if (cp && cp.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE) {
- this.chargingStation.setChargingProfile(connectorId, cp);
+ chargingStation.setChargingProfile(connectorId, cp);
logger.debug(
- `${this.chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}, dump their stack: %j`,
- this.chargingStation.getConnectorStatus(connectorId).chargingProfiles
+ `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}, dump their stack: %j`,
+ chargingStation.getConnectorStatus(connectorId).chargingProfiles
);
return true;
} else if (cp && cp.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE) {
logger.warn(
- `${this.chargingStation.logPrefix()} Not allowed to set ${
+ `${chargingStation.logPrefix()} Not allowed to set ${
cp.chargingProfilePurpose
} charging profile(s) at remote start transaction`
);
}
private async handleRequestRemoteStopTransaction(
+ chargingStation: ChargingStation,
commandPayload: RemoteStopTransactionRequest
): Promise<DefaultResponse> {
const transactionId = commandPayload.transactionId;
- for (const connectorId of this.chargingStation.connectors.keys()) {
+ for (const connectorId of chargingStation.connectors.keys()) {
if (
connectorId > 0 &&
- this.chargingStation.getConnectorStatus(connectorId)?.transactionId === transactionId
+ chargingStation.getConnectorStatus(connectorId)?.transactionId === transactionId
) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: OCPP16ChargePointStatus.FINISHING,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(connectorId).status =
- OCPP16ChargePointStatus.FINISHING;
+ chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.FINISHING;
if (
- this.chargingStation.getBeginEndMeterValues() &&
- this.chargingStation.getOcppStrictCompliance() &&
- !this.chargingStation.getOutOfOrderEndMeterValues()
+ chargingStation.getBeginEndMeterValues() &&
+ chargingStation.getOcppStrictCompliance() &&
+ !chargingStation.getOutOfOrderEndMeterValues()
) {
// FIXME: Implement OCPP version agnostic helpers
const transactionEndMeterValue = OCPP16ServiceUtils.buildTransactionEndMeterValue(
- this.chargingStation,
+ chargingStation,
connectorId,
- this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId)
+ chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId)
);
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16MeterValuesRequest,
OCPP16MeterValuesResponse
- >(OCPP16RequestCommand.METER_VALUES, {
+ >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
connectorId,
transactionId,
meterValue: transactionEndMeterValue,
});
}
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StopTransactionRequest,
OCPP16StopTransactionResponse
- >(OCPP16RequestCommand.STOP_TRANSACTION, {
+ >(chargingStation, OCPP16RequestCommand.STOP_TRANSACTION, {
transactionId,
- meterStop:
- this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
- idTag: this.chargingStation.getTransactionIdTag(transactionId),
+ meterStop: chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId),
+ idTag: chargingStation.getTransactionIdTag(transactionId),
});
return Constants.OCPP_RESPONSE_ACCEPTED;
}
}
logger.info(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to remote stop a non existing transaction ' +
transactionId.toString()
);
}
private async handleRequestGetDiagnostics(
+ chargingStation: ChargingStation,
commandPayload: GetDiagnosticsRequest
): Promise<GetDiagnosticsResponse> {
if (
!OCPP16ServiceUtils.checkFeatureProfile(
- this.chargingStation,
+ chargingStation,
OCPP16SupportedFeatureProfiles.FirmwareManagement,
OCPP16IncomingRequestCommand.GET_DIAGNOSTICS
)
return Constants.OCPP_RESPONSE_EMPTY;
}
logger.debug(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' ' +
OCPP16IncomingRequestCommand.GET_DIAGNOSTICS +
' request received: %j',
.readdirSync(path.resolve(__dirname, '../../../../'))
.filter((file) => file.endsWith('.log'))
.map((file) => path.join('./', file));
- const diagnosticsArchive =
- this.chargingStation.stationInfo.chargingStationId + '_logs.tar.gz';
+ const diagnosticsArchive = chargingStation.stationInfo.chargingStationId + '_logs.tar.gz';
tar.create({ gzip: true }, logFiles).pipe(fs.createWriteStream(diagnosticsArchive));
ftpClient = new Client();
const accessResponse = await ftpClient.access({
// eslint-disable-next-line @typescript-eslint/no-misused-promises
ftpClient.trackProgress(async (info) => {
logger.info(
- `${this.chargingStation.logPrefix()} ${
+ `${chargingStation.logPrefix()} ${
info.bytes / 1024
} bytes transferred from diagnostics archive ${info.name}`
);
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
DiagnosticsStatusNotificationRequest,
DiagnosticsStatusNotificationResponse
- >(OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
status: OCPP16DiagnosticsStatus.Uploading,
});
});
uri.pathname + diagnosticsArchive
);
if (uploadResponse.code === 226) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
DiagnosticsStatusNotificationRequest,
DiagnosticsStatusNotificationResponse
- >(OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
status: OCPP16DiagnosticsStatus.Uploaded,
});
if (ftpClient) {
OCPP16IncomingRequestCommand.GET_DIAGNOSTICS
);
} catch (error) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
DiagnosticsStatusNotificationRequest,
DiagnosticsStatusNotificationResponse
- >(OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
status: OCPP16DiagnosticsStatus.UploadFailed,
});
if (ftpClient) {
ftpClient.close();
}
return this.handleIncomingRequestError(
+ chargingStation,
OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
error as Error,
{ errorResponse: Constants.OCPP_RESPONSE_EMPTY }
}
} else {
logger.error(
- `${this.chargingStation.logPrefix()} Unsupported protocol ${
+ `${chargingStation.logPrefix()} Unsupported protocol ${
uri.protocol
} to transfer the diagnostic logs archive`
);
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
DiagnosticsStatusNotificationRequest,
DiagnosticsStatusNotificationResponse
- >(OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
status: OCPP16DiagnosticsStatus.UploadFailed,
});
return Constants.OCPP_RESPONSE_EMPTY;
}
private handleRequestTriggerMessage(
+ chargingStation: ChargingStation,
commandPayload: OCPP16TriggerMessageRequest
): OCPP16TriggerMessageResponse {
if (
!OCPP16ServiceUtils.checkFeatureProfile(
- this.chargingStation,
+ chargingStation,
OCPP16SupportedFeatureProfiles.RemoteTrigger,
OCPP16IncomingRequestCommand.TRIGGER_MESSAGE
)
// TODO: factor out the check on connector id
if (commandPayload?.connectorId < 0) {
logger.warn(
- `${this.chargingStation.logPrefix()} ${
+ `${chargingStation.logPrefix()} ${
OCPP16IncomingRequestCommand.TRIGGER_MESSAGE
} incoming request received with invalid connectorId ${commandPayload.connectorId}`
);
switch (commandPayload.requestedMessage) {
case MessageTrigger.BootNotification:
setTimeout(() => {
- this.chargingStation.ocppRequestService
+ chargingStation.ocppRequestService
.requestHandler<OCPP16BootNotificationRequest, OCPP16BootNotificationResponse>(
+ chargingStation,
OCPP16RequestCommand.BOOT_NOTIFICATION,
{
- chargePointModel:
- this.chargingStation.getBootNotificationRequest().chargePointModel,
- chargePointVendor:
- this.chargingStation.getBootNotificationRequest().chargePointVendor,
+ chargePointModel: chargingStation.getBootNotificationRequest().chargePointModel,
+ chargePointVendor: chargingStation.getBootNotificationRequest().chargePointVendor,
chargeBoxSerialNumber:
- this.chargingStation.getBootNotificationRequest().chargeBoxSerialNumber,
- firmwareVersion:
- this.chargingStation.getBootNotificationRequest().firmwareVersion,
+ chargingStation.getBootNotificationRequest().chargeBoxSerialNumber,
+ firmwareVersion: chargingStation.getBootNotificationRequest().firmwareVersion,
chargePointSerialNumber:
- this.chargingStation.getBootNotificationRequest().chargePointSerialNumber,
- iccid: this.chargingStation.getBootNotificationRequest().iccid,
- imsi: this.chargingStation.getBootNotificationRequest().imsi,
- meterSerialNumber:
- this.chargingStation.getBootNotificationRequest().meterSerialNumber,
- meterType: this.chargingStation.getBootNotificationRequest().meterType,
+ chargingStation.getBootNotificationRequest().chargePointSerialNumber,
+ iccid: chargingStation.getBootNotificationRequest().iccid,
+ imsi: chargingStation.getBootNotificationRequest().imsi,
+ meterSerialNumber: chargingStation.getBootNotificationRequest().meterSerialNumber,
+ meterType: chargingStation.getBootNotificationRequest().meterType,
},
{ skipBufferingOnError: true, triggerMessage: true }
)
.then((value) => {
- this.chargingStation.bootNotificationResponse = value;
+ chargingStation.bootNotificationResponse = value;
})
.catch(() => {
/* This is intentional */
return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED;
case MessageTrigger.Heartbeat:
setTimeout(() => {
- this.chargingStation.ocppRequestService
+ chargingStation.ocppRequestService
.requestHandler<OCPP16HeartbeatRequest, OCPP16HeartbeatResponse>(
+ chargingStation,
OCPP16RequestCommand.HEARTBEAT,
null,
{
case MessageTrigger.StatusNotification:
setTimeout(() => {
if (commandPayload?.connectorId) {
- this.chargingStation.ocppRequestService
+ chargingStation.ocppRequestService
.requestHandler<OCPP16StatusNotificationRequest, OCPP16StatusNotificationResponse>(
+ chargingStation,
OCPP16RequestCommand.STATUS_NOTIFICATION,
{
connectorId: commandPayload.connectorId,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
- status: this.chargingStation.getConnectorStatus(commandPayload.connectorId)
- .status,
+ status: chargingStation.getConnectorStatus(commandPayload.connectorId).status,
},
{
triggerMessage: true,
/* This is intentional */
});
} else {
- for (const connectorId of this.chargingStation.connectors.keys()) {
- this.chargingStation.ocppRequestService
+ for (const connectorId of chargingStation.connectors.keys()) {
+ chargingStation.ocppRequestService
.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
>(
+ chargingStation,
OCPP16RequestCommand.STATUS_NOTIFICATION,
{
connectorId,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
- status: this.chargingStation.getConnectorStatus(connectorId).status,
+ status: chargingStation.getConnectorStatus(connectorId).status,
},
{
triggerMessage: true,
}
} catch (error) {
return this.handleIncomingRequestError(
+ chargingStation,
OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
error as Error,
{ errorResponse: Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_REJECTED }
const moduleName = 'OCPP16RequestService';
export default class OCPP16RequestService extends OCPPRequestService {
- public constructor(chargingStation: ChargingStation, ocppResponseService: OCPPResponseService) {
+ public constructor(ocppResponseService: OCPPResponseService) {
if (new.target?.name === moduleName) {
throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
}
- super(chargingStation, ocppResponseService);
+ super(ocppResponseService);
}
public async requestHandler<Request extends JsonType, Response extends JsonType>(
+ chargingStation: ChargingStation,
commandName: OCPP16RequestCommand,
commandParams?: JsonType,
params?: RequestParams
): Promise<Response> {
if (Object.values(OCPP16RequestCommand).includes(commandName)) {
return (await this.sendMessage(
+ chargingStation,
Utils.generateUUID(),
- this.buildRequestPayload<Request>(commandName, commandParams),
+ this.buildRequestPayload<Request>(chargingStation, commandName, commandParams),
commandName,
params
)) as unknown as Response;
}
private buildRequestPayload<Request extends JsonType>(
+ chargingStation: ChargingStation,
commandName: OCPP16RequestCommand,
commandParams?: JsonType
): Request {
...(!Utils.isUndefined(commandParams?.idTag)
? { idTag: commandParams?.idTag }
: { idTag: Constants.DEFAULT_IDTAG }),
- meterStart: this.chargingStation.getEnergyActiveImportRegisterByConnectorId(
+ meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId(
commandParams?.connectorId as number
),
timestamp: new Date().toISOString(),
} as unknown as Request;
case OCPP16RequestCommand.STOP_TRANSACTION:
- connectorId = this.chargingStation.getConnectorIdByTransactionId(
+ connectorId = chargingStation.getConnectorIdByTransactionId(
commandParams?.transactionId as number
);
return {
meterStop: commandParams?.meterStop,
timestamp: new Date().toISOString(),
...(commandParams?.reason && { reason: commandParams.reason }),
- ...(this.chargingStation.getTransactionDataMeterValues() && {
+ ...(chargingStation.getTransactionDataMeterValues() && {
transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(
- this.chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
+ chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
OCPP16ServiceUtils.buildTransactionEndMeterValue(
- this.chargingStation,
+ chargingStation,
connectorId,
commandParams?.meterStop as number
)
export default class OCPP16ResponseService extends OCPPResponseService {
private responseHandlers: Map<OCPP16RequestCommand, ResponseHandler>;
- public constructor(chargingStation: ChargingStation) {
+ public constructor() {
if (new.target?.name === moduleName) {
throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
}
- super(chargingStation);
+ super();
this.responseHandlers = new Map<OCPP16RequestCommand, ResponseHandler>([
[OCPP16RequestCommand.BOOT_NOTIFICATION, this.handleResponseBootNotification.bind(this)],
[OCPP16RequestCommand.HEARTBEAT, this.handleResponseHeartbeat.bind(this)],
}
public async responseHandler(
+ chargingStation: ChargingStation,
commandName: OCPP16RequestCommand,
payload: JsonType,
requestPayload: JsonType
): Promise<void> {
- if (
- this.chargingStation.isRegistered() ||
- commandName === OCPP16RequestCommand.BOOT_NOTIFICATION
- ) {
+ if (chargingStation.isRegistered() || commandName === OCPP16RequestCommand.BOOT_NOTIFICATION) {
if (this.responseHandlers.has(commandName)) {
try {
- await this.responseHandlers.get(commandName)(payload, requestPayload);
+ await this.responseHandlers.get(commandName)(chargingStation, payload, requestPayload);
} catch (error) {
- logger.error(
- this.chargingStation.logPrefix() + ' Handle request response error: %j',
- error
- );
+ logger.error(chargingStation.logPrefix() + ' Handle request response error: %j', error);
throw error;
}
} else {
}
}
- private handleResponseBootNotification(payload: OCPP16BootNotificationResponse): void {
+ private handleResponseBootNotification(
+ chargingStation: ChargingStation,
+ payload: OCPP16BootNotificationResponse
+ ): void {
if (payload.status === OCPP16RegistrationStatus.ACCEPTED) {
- this.chargingStation.addConfigurationKey(
+ chargingStation.addConfigurationKey(
OCPP16StandardParametersKey.HeartbeatInterval,
payload.interval.toString(),
{},
{ overwrite: true, save: true }
);
- this.chargingStation.addConfigurationKey(
+ chargingStation.addConfigurationKey(
OCPP16StandardParametersKey.HeartBeatInterval,
payload.interval.toString(),
{ visible: false },
{ overwrite: true, save: true }
);
- this.chargingStation.heartbeatSetInterval
- ? this.chargingStation.restartHeartbeat()
- : this.chargingStation.startHeartbeat();
+ chargingStation.heartbeatSetInterval
+ ? chargingStation.restartHeartbeat()
+ : chargingStation.startHeartbeat();
}
if (Object.values(OCPP16RegistrationStatus).includes(payload.status)) {
- const logMsg = `${this.chargingStation.logPrefix()} Charging station in '${
+ const logMsg = `${chargingStation.logPrefix()} Charging station in '${
payload.status
}' state on the central server`;
payload.status === OCPP16RegistrationStatus.REJECTED
: logger.info(logMsg);
} else {
logger.error(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Charging station boot notification response received: %j with undefined registration status',
payload
);
private handleResponseHeartbeat(): void {}
private handleResponseAuthorize(
+ chargingStation: ChargingStation,
payload: OCPP16AuthorizeResponse,
requestPayload: OCPP16AuthorizeRequest
): void {
let authorizeConnectorId: number;
- for (const connectorId of this.chargingStation.connectors.keys()) {
+ for (const connectorId of chargingStation.connectors.keys()) {
if (
connectorId > 0 &&
- this.chargingStation.getConnectorStatus(connectorId)?.authorizeIdTag ===
- requestPayload.idTag
+ chargingStation.getConnectorStatus(connectorId)?.authorizeIdTag === requestPayload.idTag
) {
authorizeConnectorId = connectorId;
break;
}
}
if (payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) {
- this.chargingStation.getConnectorStatus(authorizeConnectorId).idTagAuthorized = true;
+ chargingStation.getConnectorStatus(authorizeConnectorId).idTagAuthorized = true;
logger.debug(
- `${this.chargingStation.logPrefix()} IdTag ${
+ `${chargingStation.logPrefix()} IdTag ${
requestPayload.idTag
} authorized on connector ${authorizeConnectorId}`
);
} else {
- this.chargingStation.getConnectorStatus(authorizeConnectorId).idTagAuthorized = false;
- delete this.chargingStation.getConnectorStatus(authorizeConnectorId).authorizeIdTag;
+ chargingStation.getConnectorStatus(authorizeConnectorId).idTagAuthorized = false;
+ delete chargingStation.getConnectorStatus(authorizeConnectorId).authorizeIdTag;
logger.debug(
- `${this.chargingStation.logPrefix()} IdTag ${requestPayload.idTag} refused with status '${
+ `${chargingStation.logPrefix()} IdTag ${requestPayload.idTag} refused with status '${
payload.idTagInfo.status
}' on connector ${authorizeConnectorId}`
);
}
private async handleResponseStartTransaction(
+ chargingStation: ChargingStation,
payload: OCPP16StartTransactionResponse,
requestPayload: OCPP16StartTransactionRequest
): Promise<void> {
const connectorId = requestPayload.connectorId;
let transactionConnectorId: number;
- for (const id of this.chargingStation.connectors.keys()) {
+ for (const id of chargingStation.connectors.keys()) {
if (id > 0 && id === connectorId) {
transactionConnectorId = id;
break;
}
if (!transactionConnectorId) {
logger.error(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to start a transaction on a non existing connector Id ' +
connectorId.toString()
);
return;
}
if (
- this.chargingStation.getConnectorStatus(connectorId).transactionRemoteStarted &&
- this.chargingStation.getAuthorizeRemoteTxRequests() &&
- this.chargingStation.getLocalAuthListEnabled() &&
- this.chargingStation.hasAuthorizedTags() &&
- !this.chargingStation.getConnectorStatus(connectorId).idTagLocalAuthorized
+ chargingStation.getConnectorStatus(connectorId).transactionRemoteStarted &&
+ chargingStation.getAuthorizeRemoteTxRequests() &&
+ chargingStation.getLocalAuthListEnabled() &&
+ chargingStation.hasAuthorizedTags() &&
+ !chargingStation.getConnectorStatus(connectorId).idTagLocalAuthorized
) {
logger.error(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to start a transaction with a not local authorized idTag ' +
- this.chargingStation.getConnectorStatus(connectorId).localAuthorizeIdTag +
+ chargingStation.getConnectorStatus(connectorId).localAuthorizeIdTag +
' on connector Id ' +
connectorId.toString()
);
- await this.resetConnectorOnStartTransactionError(connectorId);
+ await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
return;
}
if (
- this.chargingStation.getConnectorStatus(connectorId).transactionRemoteStarted &&
- this.chargingStation.getAuthorizeRemoteTxRequests() &&
- this.chargingStation.getMayAuthorizeAtRemoteStart() &&
- !this.chargingStation.getConnectorStatus(connectorId).idTagLocalAuthorized &&
- !this.chargingStation.getConnectorStatus(connectorId).idTagAuthorized
+ chargingStation.getConnectorStatus(connectorId).transactionRemoteStarted &&
+ chargingStation.getAuthorizeRemoteTxRequests() &&
+ chargingStation.getMayAuthorizeAtRemoteStart() &&
+ !chargingStation.getConnectorStatus(connectorId).idTagLocalAuthorized &&
+ !chargingStation.getConnectorStatus(connectorId).idTagAuthorized
) {
logger.error(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to start a transaction with a not authorized idTag ' +
- this.chargingStation.getConnectorStatus(connectorId).authorizeIdTag +
+ chargingStation.getConnectorStatus(connectorId).authorizeIdTag +
' on connector Id ' +
connectorId.toString()
);
- await this.resetConnectorOnStartTransactionError(connectorId);
+ await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
return;
}
if (
- this.chargingStation.getConnectorStatus(connectorId).idTagAuthorized &&
- this.chargingStation.getConnectorStatus(connectorId).authorizeIdTag !== requestPayload.idTag
+ chargingStation.getConnectorStatus(connectorId).idTagAuthorized &&
+ chargingStation.getConnectorStatus(connectorId).authorizeIdTag !== requestPayload.idTag
) {
logger.error(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to start a transaction with an idTag ' +
requestPayload.idTag +
' different from the authorize request one ' +
- this.chargingStation.getConnectorStatus(connectorId).authorizeIdTag +
+ chargingStation.getConnectorStatus(connectorId).authorizeIdTag +
' on connector Id ' +
connectorId.toString()
);
- await this.resetConnectorOnStartTransactionError(connectorId);
+ await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
return;
}
if (
- this.chargingStation.getConnectorStatus(connectorId).idTagLocalAuthorized &&
- this.chargingStation.getConnectorStatus(connectorId).localAuthorizeIdTag !==
- requestPayload.idTag
+ chargingStation.getConnectorStatus(connectorId).idTagLocalAuthorized &&
+ chargingStation.getConnectorStatus(connectorId).localAuthorizeIdTag !== requestPayload.idTag
) {
logger.error(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to start a transaction with an idTag ' +
requestPayload.idTag +
' different from the local authorized one ' +
- this.chargingStation.getConnectorStatus(connectorId).localAuthorizeIdTag +
+ chargingStation.getConnectorStatus(connectorId).localAuthorizeIdTag +
' on connector Id ' +
connectorId.toString()
);
- await this.resetConnectorOnStartTransactionError(connectorId);
+ await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
return;
}
- if (this.chargingStation.getConnectorStatus(connectorId)?.transactionStarted) {
+ if (chargingStation.getConnectorStatus(connectorId)?.transactionStarted) {
logger.debug(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to start a transaction on an already used connector ' +
connectorId.toString() +
': %j',
- this.chargingStation.getConnectorStatus(connectorId)
+ chargingStation.getConnectorStatus(connectorId)
);
return;
}
if (
- this.chargingStation.getConnectorStatus(connectorId)?.status !==
+ chargingStation.getConnectorStatus(connectorId)?.status !==
OCPP16ChargePointStatus.AVAILABLE &&
- this.chargingStation.getConnectorStatus(connectorId)?.status !==
- OCPP16ChargePointStatus.PREPARING
+ chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.PREPARING
) {
logger.error(
- `${this.chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()} with status ${
- this.chargingStation.getConnectorStatus(connectorId)?.status
+ `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()} with status ${
+ chargingStation.getConnectorStatus(connectorId)?.status
}`
);
return;
}
if (!Number.isInteger(payload.transactionId)) {
logger.warn(
- `${this.chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()} with a non integer transaction Id ${
+ `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()} with a non integer transaction Id ${
payload.transactionId
}, converting to integer`
);
}
if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
- this.chargingStation.getConnectorStatus(connectorId).transactionStarted = true;
- this.chargingStation.getConnectorStatus(connectorId).transactionId = payload.transactionId;
- this.chargingStation.getConnectorStatus(connectorId).transactionIdTag = requestPayload.idTag;
- this.chargingStation.getConnectorStatus(
+ chargingStation.getConnectorStatus(connectorId).transactionStarted = true;
+ chargingStation.getConnectorStatus(connectorId).transactionId = payload.transactionId;
+ chargingStation.getConnectorStatus(connectorId).transactionIdTag = requestPayload.idTag;
+ chargingStation.getConnectorStatus(
connectorId
).transactionEnergyActiveImportRegisterValue = 0;
- this.chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue =
+ chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue =
OCPP16ServiceUtils.buildTransactionBeginMeterValue(
- this.chargingStation,
+ chargingStation,
connectorId,
requestPayload.meterStart
);
- this.chargingStation.getBeginEndMeterValues() &&
- (await this.chargingStation.ocppRequestService.requestHandler<
+ chargingStation.getBeginEndMeterValues() &&
+ (await chargingStation.ocppRequestService.requestHandler<
OCPP16MeterValuesRequest,
OCPP16MeterValuesResponse
- >(OCPP16RequestCommand.METER_VALUES, {
+ >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
connectorId,
transactionId: payload.transactionId,
- meterValue:
- this.chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
+ meterValue: chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
}));
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: OCPP16ChargePointStatus.CHARGING,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(connectorId).status =
- OCPP16ChargePointStatus.CHARGING;
+ chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.CHARGING;
logger.info(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Transaction ' +
payload.transactionId.toString() +
' STARTED on ' +
- this.chargingStation.stationInfo.chargingStationId +
+ chargingStation.stationInfo.chargingStationId +
'#' +
connectorId.toString() +
' for idTag ' +
requestPayload.idTag
);
- if (this.chargingStation.stationInfo.powerSharedByConnectors) {
- this.chargingStation.stationInfo.powerDivider++;
+ if (chargingStation.stationInfo.powerSharedByConnectors) {
+ chargingStation.stationInfo.powerDivider++;
}
- const configuredMeterValueSampleInterval = this.chargingStation.getConfigurationKey(
+ const configuredMeterValueSampleInterval = chargingStation.getConfigurationKey(
OCPP16StandardParametersKey.MeterValueSampleInterval
);
- this.chargingStation.startMeterValues(
+ chargingStation.startMeterValues(
connectorId,
configuredMeterValueSampleInterval
? Utils.convertToInt(configuredMeterValueSampleInterval.value) * 1000
);
} else {
logger.warn(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Starting transaction id ' +
payload.transactionId.toString() +
" REJECTED with status '" +
"', idTag " +
requestPayload.idTag
);
- await this.resetConnectorOnStartTransactionError(connectorId);
+ await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
}
}
- private async resetConnectorOnStartTransactionError(connectorId: number): Promise<void> {
- this.chargingStation.resetConnectorStatus(connectorId);
+ private async resetConnectorOnStartTransactionError(
+ chargingStation: ChargingStation,
+ connectorId: number
+ ): Promise<void> {
+ chargingStation.resetConnectorStatus(connectorId);
if (
- this.chargingStation.getConnectorStatus(connectorId).status !==
- OCPP16ChargePointStatus.AVAILABLE
+ chargingStation.getConnectorStatus(connectorId).status !== OCPP16ChargePointStatus.AVAILABLE
) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId,
status: OCPP16ChargePointStatus.AVAILABLE,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(connectorId).status =
- OCPP16ChargePointStatus.AVAILABLE;
+ chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.AVAILABLE;
}
}
private async handleResponseStopTransaction(
+ chargingStation: ChargingStation,
payload: OCPP16StopTransactionResponse,
requestPayload: OCPP16StopTransactionRequest
): Promise<void> {
- const transactionConnectorId = this.chargingStation.getConnectorIdByTransactionId(
+ const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
requestPayload.transactionId
);
if (!transactionConnectorId) {
logger.error(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Trying to stop a non existing transaction ' +
requestPayload.transactionId.toString()
);
return;
}
if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
- this.chargingStation.getBeginEndMeterValues() &&
- !this.chargingStation.getOcppStrictCompliance() &&
- this.chargingStation.getOutOfOrderEndMeterValues() &&
- (await this.chargingStation.ocppRequestService.requestHandler<
+ chargingStation.getBeginEndMeterValues() &&
+ !chargingStation.getOcppStrictCompliance() &&
+ chargingStation.getOutOfOrderEndMeterValues() &&
+ (await chargingStation.ocppRequestService.requestHandler<
OCPP16MeterValuesRequest,
OCPP16MeterValuesResponse
- >(OCPP16RequestCommand.METER_VALUES, {
+ >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
connectorId: transactionConnectorId,
transactionId: requestPayload.transactionId,
meterValue: OCPP16ServiceUtils.buildTransactionEndMeterValue(
- this.chargingStation,
+ chargingStation,
transactionConnectorId,
requestPayload.meterStop
),
}));
if (
- !this.chargingStation.isChargingStationAvailable() ||
- !this.chargingStation.isConnectorAvailable(transactionConnectorId)
+ !chargingStation.isChargingStationAvailable() ||
+ !chargingStation.isConnectorAvailable(transactionConnectorId)
) {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16StatusNotificationRequest,
OCPP16StatusNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId: transactionConnectorId,
status: OCPP16ChargePointStatus.UNAVAILABLE,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(transactionConnectorId).status =
+ chargingStation.getConnectorStatus(transactionConnectorId).status =
OCPP16ChargePointStatus.UNAVAILABLE;
} else {
- await this.chargingStation.ocppRequestService.requestHandler<
+ await chargingStation.ocppRequestService.requestHandler<
OCPP16BootNotificationRequest,
OCPP16BootNotificationResponse
- >(OCPP16RequestCommand.STATUS_NOTIFICATION, {
+ >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
connectorId: transactionConnectorId,
status: OCPP16ChargePointStatus.AVAILABLE,
errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
});
- this.chargingStation.getConnectorStatus(transactionConnectorId).status =
+ chargingStation.getConnectorStatus(transactionConnectorId).status =
OCPP16ChargePointStatus.AVAILABLE;
}
- if (this.chargingStation.stationInfo.powerSharedByConnectors) {
- this.chargingStation.stationInfo.powerDivider--;
+ if (chargingStation.stationInfo.powerSharedByConnectors) {
+ chargingStation.stationInfo.powerDivider--;
}
logger.info(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Transaction ' +
requestPayload.transactionId.toString() +
' STOPPED on ' +
- this.chargingStation.stationInfo.chargingStationId +
+ chargingStation.stationInfo.chargingStationId +
'#' +
transactionConnectorId.toString()
);
- this.chargingStation.resetConnectorStatus(transactionConnectorId);
+ chargingStation.resetConnectorStatus(transactionConnectorId);
} else {
logger.warn(
- this.chargingStation.logPrefix() +
+ chargingStation.logPrefix() +
' Stopping transaction id ' +
requestPayload.transactionId.toString() +
" REJECTED with status '" +
import logger from '../../utils/Logger';
export default abstract class OCPPIncomingRequestService {
- private static readonly instances: Map<string, OCPPIncomingRequestService> = new Map<
- string,
- OCPPIncomingRequestService
- >();
+ private static instance: OCPPIncomingRequestService | null = null;
- protected chargingStation: ChargingStation;
-
- protected constructor(chargingStation: ChargingStation) {
- this.chargingStation = chargingStation;
+ protected constructor() {
+ // This is intentional
}
- public static getInstance<T extends OCPPIncomingRequestService>(
- this: new (chargingStation: ChargingStation) => T,
- chargingStation: ChargingStation
- ): T {
- if (!OCPPIncomingRequestService.instances.has(chargingStation.hashId)) {
- OCPPIncomingRequestService.instances.set(chargingStation.hashId, new this(chargingStation));
+ public static getInstance<T extends OCPPIncomingRequestService>(this: new () => T): T {
+ if (!OCPPIncomingRequestService.instance) {
+ OCPPIncomingRequestService.instance = new this();
}
- return OCPPIncomingRequestService.instances.get(chargingStation.hashId) as T;
+ return OCPPIncomingRequestService.instance as T;
}
protected handleIncomingRequestError<T>(
+ chargingStation: ChargingStation,
commandName: IncomingRequestCommand,
error: Error,
params: HandleErrorParams<T> = { throwError: true }
): T {
logger.error(
- this.chargingStation.logPrefix() + ' Incoming request command %s error: %j',
+ chargingStation.logPrefix() + ' Incoming request command %s error: %j',
commandName,
error
);
}
public abstract incomingRequestHandler(
+ chargingStation: ChargingStation,
messageId: string,
commandName: IncomingRequestCommand,
commandPayload: JsonType
} from '../../types/ocpp/Requests';
import { JsonObject, JsonType } from '../../types/JsonType';
-import type ChargingStation from '../ChargingStation';
+import ChargingStation from '../ChargingStation';
import Constants from '../../utils/Constants';
import { EmptyObject } from '../../types/EmptyObject';
import { ErrorType } from '../../types/ocpp/ErrorType';
import logger from '../../utils/Logger';
export default abstract class OCPPRequestService {
- private static readonly instances: Map<string, OCPPRequestService> = new Map<
- string,
- OCPPRequestService
- >();
+ private static instance: OCPPRequestService | null = null;
- protected readonly chargingStation: ChargingStation;
private readonly ocppResponseService: OCPPResponseService;
- protected constructor(
- chargingStation: ChargingStation,
- ocppResponseService: OCPPResponseService
- ) {
- this.chargingStation = chargingStation;
+ protected constructor(ocppResponseService: OCPPResponseService) {
this.ocppResponseService = ocppResponseService;
this.requestHandler.bind(this);
this.sendResponse.bind(this);
}
public static getInstance<T extends OCPPRequestService>(
- this: new (chargingStation: ChargingStation, ocppResponseService: OCPPResponseService) => T,
- chargingStation: ChargingStation,
+ this: new (ocppResponseService: OCPPResponseService) => T,
ocppResponseService: OCPPResponseService
): T {
- if (!OCPPRequestService.instances.has(chargingStation.hashId)) {
- OCPPRequestService.instances.set(
- chargingStation.hashId,
- new this(chargingStation, ocppResponseService)
- );
+ if (!OCPPRequestService.instance) {
+ OCPPRequestService.instance = new this(ocppResponseService);
}
- return OCPPRequestService.instances.get(chargingStation.hashId) as T;
+ return OCPPRequestService.instance as T;
}
public async sendResponse(
+ chargingStation: ChargingStation,
messageId: string,
messagePayload: JsonType,
commandName: IncomingRequestCommand
try {
// Send response message
return await this.internalSendMessage(
+ chargingStation,
messageId,
messagePayload,
MessageType.CALL_RESULT_MESSAGE,
commandName
);
} catch (error) {
- this.handleRequestError(commandName, error as Error);
+ this.handleRequestError(chargingStation, commandName, error as Error);
}
}
public async sendError(
+ chargingStation: ChargingStation,
messageId: string,
ocppError: OCPPError,
commandName: RequestCommand | IncomingRequestCommand
try {
// Send error message
return await this.internalSendMessage(
+ chargingStation,
messageId,
ocppError,
MessageType.CALL_ERROR_MESSAGE,
commandName
);
} catch (error) {
- this.handleRequestError(commandName, error as Error);
+ this.handleRequestError(chargingStation, commandName, error as Error);
}
}
protected async sendMessage(
+ chargingStation: ChargingStation,
messageId: string,
messagePayload: JsonType,
commandName: RequestCommand,
): Promise<ResponseType> {
try {
return await this.internalSendMessage(
+ chargingStation,
messageId,
messagePayload,
MessageType.CALL_MESSAGE,
params
);
} catch (error) {
- this.handleRequestError(commandName, error as Error, { throwError: false });
+ this.handleRequestError(chargingStation, commandName, error as Error, { throwError: false });
}
}
private async internalSendMessage(
+ chargingStation: ChargingStation,
messageId: string,
messagePayload: JsonType | OCPPError,
messageType: MessageType,
}
): Promise<ResponseType> {
if (
- (this.chargingStation.isInUnknownState() &&
- commandName === RequestCommand.BOOT_NOTIFICATION) ||
- (!this.chargingStation.getOcppStrictCompliance() &&
- this.chargingStation.isInUnknownState()) ||
- this.chargingStation.isInAcceptedState() ||
- (this.chargingStation.isInPendingState() &&
+ (chargingStation.isInUnknownState() && commandName === RequestCommand.BOOT_NOTIFICATION) ||
+ (!chargingStation.getOcppStrictCompliance() && chargingStation.isInUnknownState()) ||
+ chargingStation.isInAcceptedState() ||
+ (chargingStation.isInPendingState() &&
(params.triggerMessage || messageType === MessageType.CALL_RESULT_MESSAGE))
) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
return Utils.promiseWithTimeout(
new Promise((resolve, reject) => {
const messageToSend = this.buildMessageToSend(
+ chargingStation,
messageId,
messagePayload,
messageType,
responseCallback,
errorCallback
);
- if (this.chargingStation.getEnableStatistics()) {
- this.chargingStation.performanceStatistics.addRequestStatistic(
- commandName,
- messageType
- );
+ if (chargingStation.getEnableStatistics()) {
+ chargingStation.performanceStatistics.addRequestStatistic(commandName, messageType);
}
// Check if wsConnection opened
- if (this.chargingStation.isWebSocketConnectionOpened()) {
+ if (chargingStation.isWebSocketConnectionOpened()) {
// Yes: Send Message
const beginId = PerformanceStatistics.beginMeasure(commandName);
// FIXME: Handle sending error
- this.chargingStation.wsConnection.send(messageToSend);
+ chargingStation.wsConnection.send(messageToSend);
PerformanceStatistics.endMeasure(commandName, beginId);
logger.debug(
- `${this.chargingStation.logPrefix()} >> Command '${commandName}' sent ${this.getMessageTypeString(
+ `${chargingStation.logPrefix()} >> Command '${commandName}' sent ${this.getMessageTypeString(
messageType
)} payload: ${messageToSend}`
);
} else if (!params.skipBufferingOnError) {
// Buffer it
- this.chargingStation.bufferMessage(messageToSend);
+ chargingStation.bufferMessage(messageToSend);
const ocppError = new OCPPError(
ErrorType.GENERIC_ERROR,
`WebSocket closed for buffered message id '${messageId}' with content '${messageToSend}'`,
/**
* Function that will receive the request's response
*
+ * @param chargingStation
* @param payload
* @param requestPayload
*/
payload: JsonType,
requestPayload: JsonType
): Promise<void> {
- if (self.chargingStation.getEnableStatistics()) {
- self.chargingStation.performanceStatistics.addRequestStatistic(
+ if (chargingStation.getEnableStatistics()) {
+ chargingStation.performanceStatistics.addRequestStatistic(
commandName,
MessageType.CALL_RESULT_MESSAGE
);
// Handle the request's response
try {
await self.ocppResponseService.responseHandler(
+ chargingStation,
commandName as RequestCommand,
payload,
requestPayload
} catch (error) {
reject(error);
} finally {
- self.chargingStation.requests.delete(messageId);
+ chargingStation.requests.delete(messageId);
}
}
* @param requestStatistic
*/
function errorCallback(error: OCPPError, requestStatistic = true): void {
- if (requestStatistic && self.chargingStation.getEnableStatistics()) {
- self.chargingStation.performanceStatistics.addRequestStatistic(
+ if (requestStatistic && chargingStation.getEnableStatistics()) {
+ chargingStation.performanceStatistics.addRequestStatistic(
commandName,
MessageType.CALL_ERROR_MESSAGE
);
}
logger.error(
- `${self.chargingStation.logPrefix()} Error %j occurred when calling command %s with message data %j`,
+ `${chargingStation.logPrefix()} Error %j occurred when calling command %s with message data %j`,
error,
commandName,
messagePayload
);
- self.chargingStation.requests.delete(messageId);
+ chargingStation.requests.delete(messageId);
reject(error);
}
}),
(messagePayload as JsonObject)?.details ?? {}
),
() => {
- messageType === MessageType.CALL_MESSAGE &&
- this.chargingStation.requests.delete(messageId);
+ messageType === MessageType.CALL_MESSAGE && chargingStation.requests.delete(messageId);
}
);
}
throw new OCPPError(
ErrorType.SECURITY_ERROR,
- `Cannot send command ${commandName} payload when the charging station is in ${this.chargingStation.getRegistrationStatus()} state on the central server`,
+ `Cannot send command ${commandName} payload when the charging station is in ${chargingStation.getRegistrationStatus()} state on the central server`,
commandName
);
}
private buildMessageToSend(
+ chargingStation: ChargingStation,
messageId: string,
messagePayload: JsonType | OCPPError,
messageType: MessageType,
// Request
case MessageType.CALL_MESSAGE:
// Build request
- this.chargingStation.requests.set(messageId, [
+ chargingStation.requests.set(messageId, [
responseCallback,
errorCallback,
commandName,
}
private handleRequestError(
+ chargingStation: ChargingStation,
commandName: RequestCommand | IncomingRequestCommand,
error: Error,
params: HandleErrorParams<EmptyObject> = { throwError: true }
): void {
- logger.error(
- this.chargingStation.logPrefix() + ' Request command %s error: %j',
- commandName,
- error
- );
+ logger.error(chargingStation.logPrefix() + ' Request command %s error: %j', commandName, error);
if (params?.throwError) {
throw error;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public abstract requestHandler<Request extends JsonType, Response extends JsonType>(
+ chargingStation: ChargingStation,
commandName: RequestCommand,
commandParams?: JsonType,
params?: RequestParams
import { RequestCommand } from '../../types/ocpp/Requests';
export default abstract class OCPPResponseService {
- private static readonly instances: Map<string, OCPPResponseService> = new Map<
- string,
- OCPPResponseService
- >();
+ private static instance: OCPPResponseService | null = null;
- protected readonly chargingStation: ChargingStation;
-
- protected constructor(chargingStation: ChargingStation) {
- this.chargingStation = chargingStation;
+ protected constructor() {
+ // This is intentional
}
- public static getInstance<T extends OCPPResponseService>(
- this: new (chargingStation: ChargingStation) => T,
- chargingStation: ChargingStation
- ): T {
- if (!OCPPResponseService.instances.has(chargingStation.hashId)) {
- OCPPResponseService.instances.set(chargingStation.hashId, new this(chargingStation));
+ public static getInstance<T extends OCPPResponseService>(this: new () => T): T {
+ if (!OCPPResponseService.instance) {
+ OCPPResponseService.instance = new this();
}
- return OCPPResponseService.instances.get(chargingStation.hashId) as T;
+ return OCPPResponseService.instance as T;
}
public abstract responseHandler(
+ chargingStation: ChargingStation,
commandName: RequestCommand,
payload: JsonType,
requestPayload: JsonType
OCPP16StatusNotificationRequest,
} from './1.6/Requests';
+import ChargingStation from '../../charging-station/ChargingStation';
import { JsonType } from '../JsonType';
import { MessageType } from './MessageType';
import { OCPP16DiagnosticsStatus } from './1.6/DiagnosticsStatus';
JsonType
];
-export type IncomingRequestHandler = (commandPayload: JsonType) => JsonType | Promise<JsonType>;
+export type IncomingRequestHandler = (
+ chargingStation: ChargingStation,
+ commandPayload: JsonType
+) => JsonType | Promise<JsonType>;
export type ResponseType = JsonType | OCPPError;
OCPP16UnlockStatus,
} from './1.6/Responses';
+import ChargingStation from '../../charging-station/ChargingStation';
import { ErrorType } from './ErrorType';
import { JsonType } from '../JsonType';
import { MessageType } from './MessageType';
export type ErrorResponse = [MessageType.CALL_ERROR_MESSAGE, string, ErrorType, string, JsonType];
export type ResponseHandler = (
+ chargingStation: ChargingStation,
payload: JsonType,
requestPayload?: JsonType
) => void | Promise<void>;