-// Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
+// Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
import { createHash } from 'node:crypto'
import { EventEmitter } from 'node:events'
buildStartedMessage,
buildStoppedMessage,
buildUpdatedMessage,
- cloneObject,
+ clone,
convertToBoolean,
+ convertToDate,
convertToInt,
exponentialDelay,
formatDurationMilliSeconds,
public performanceStatistics!: PerformanceStatistics | undefined
public heartbeatSetInterval?: NodeJS.Timeout
public ocppRequestService!: OCPPRequestService
- public bootNotificationRequest!: BootNotificationRequest
- public bootNotificationResponse!: BootNotificationResponse | undefined
+ public bootNotificationRequest?: BootNotificationRequest
+ public bootNotificationResponse?: BootNotificationResponse
public powerDivider?: number
private stopping: boolean
private configurationFile!: string
`${
this.stationInfo?.supervisionUrlOcppConfiguration === true &&
isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- isNotEmptyString(getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!)?.value)
- ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!)!.value
+ isNotEmptyString(getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey)?.value)
+ ? getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey)?.value
: this.configuredSupervisionUrl.href
}/${this.stationInfo?.chargingStationId}`
)
return numberOfRunningTransactions
}
- public getConnectorIdByTransactionId (transactionId: number): number | undefined {
- if (this.hasEvses) {
+ public getConnectorIdByTransactionId (transactionId: number | undefined): number | undefined {
+ if (transactionId == null) {
+ return undefined
+ } else if (this.hasEvses) {
for (const evseStatus of this.evses.values()) {
for (const [connectorId, connectorStatus] of evseStatus.connectors) {
if (connectorStatus.transactionId === transactionId) {
}
public getEnergyActiveImportRegisterByTransactionId (
- transactionId: number,
+ transactionId: number | undefined,
rounded = false
): number {
return this.getEnergyActiveImportRegister(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.getConnectorStatus(this.getConnectorIdByTransactionId(transactionId)!)!,
+ this.getConnectorStatus(this.getConnectorIdByTransactionId(transactionId)!),
rounded
)
}
public getEnergyActiveImportRegisterByConnectorId (connectorId: number, rounded = false): number {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- return this.getEnergyActiveImportRegister(this.getConnectorStatus(connectorId)!, rounded)
+ return this.getEnergyActiveImportRegister(this.getConnectorStatus(connectorId), rounded)
}
public getAuthorizeRemoteTxRequests (): boolean {
this.stationInfo?.supervisionUrlOcppConfiguration === true &&
isNotEmptyString(this.stationInfo.supervisionUrlOcppKey)
) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- setConfigurationKeyValue(this, this.stationInfo.supervisionUrlOcppKey!, url)
+ setConfigurationKeyValue(this, this.stationInfo.supervisionUrlOcppKey, url)
} else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.stationInfo!.supervisionUrls = url
this.heartbeatSetInterval = setInterval(() => {
this.ocppRequestService
.requestHandler<HeartbeatRequest, HeartbeatResponse>(this, RequestCommand.HEARTBEAT)
- .catch((error) => {
+ .catch(error => {
logger.error(
`${this.logPrefix()} Error while sending '${RequestCommand.HEARTBEAT}':`,
error
logger.error(`${this.logPrefix()} Trying to start MeterValues on connector id ${connectorId}`)
return
}
- if (this.getConnectorStatus(connectorId) == null) {
+ const connectorStatus = this.getConnectorStatus(connectorId)
+ if (connectorStatus == null) {
logger.error(
`${this.logPrefix()} Trying to start MeterValues on non existing connector id
${connectorId}`
)
return
}
- if (this.getConnectorStatus(connectorId)?.transactionStarted === false) {
+ if (connectorStatus.transactionStarted === false) {
logger.error(
`${this.logPrefix()} Trying to start MeterValues on connector id ${connectorId} with no transaction started`
)
return
} else if (
- this.getConnectorStatus(connectorId)?.transactionStarted === true &&
- this.getConnectorStatus(connectorId)?.transactionId == null
+ connectorStatus.transactionStarted === true &&
+ connectorStatus.transactionId == null
) {
logger.error(
`${this.logPrefix()} Trying to start MeterValues on connector id ${connectorId} with no transaction id`
return
}
if (interval > 0) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.getConnectorStatus(connectorId)!.transactionSetInterval = setInterval(() => {
+ connectorStatus.transactionSetInterval = setInterval(() => {
const meterValue = buildMeterValue(
this,
connectorId,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.getConnectorStatus(connectorId)!.transactionId!,
+ connectorStatus.transactionId!,
interval
)
this.ocppRequestService
RequestCommand.METER_VALUES,
{
connectorId,
- transactionId: this.getConnectorStatus(connectorId)?.transactionId,
+ transactionId: connectorStatus.transactionId,
meterValue: [meterValue]
}
)
- .catch((error) => {
+ .catch(error => {
logger.error(
`${this.logPrefix()} Error while sending '${RequestCommand.METER_VALUES}':`,
error
}
public stopMeterValues (connectorId: number): void {
- if (this.getConnectorStatus(connectorId)?.transactionSetInterval != null) {
- clearInterval(this.getConnectorStatus(connectorId)?.transactionSetInterval)
+ const connectorStatus = this.getConnectorStatus(connectorId)
+ if (connectorStatus?.transactionSetInterval != null) {
+ clearInterval(connectorStatus.transactionSetInterval)
}
}
public startAutomaticTransactionGenerator (connectorIds?: number[]): void {
this.automaticTransactionGenerator = AutomaticTransactionGenerator.getInstance(this)
if (isNotEmptyArray(connectorIds)) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- for (const connectorId of connectorIds!) {
+ for (const connectorId of connectorIds) {
this.automaticTransactionGenerator?.startConnector(connectorId)
}
} else {
public stopAutomaticTransactionGenerator (connectorIds?: number[]): void {
if (isNotEmptyArray(connectorIds)) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- for (const connectorId of connectorIds!) {
+ for (const connectorId of connectorIds) {
this.automaticTransactionGenerator?.stopConnector(connectorId)
}
} else {
connectorId: number,
reason?: StopTransactionReason
): Promise<StopTransactionResponse> {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const transactionId = this.getConnectorStatus(connectorId)!.transactionId!
+ const transactionId = this.getConnectorStatus(connectorId)?.transactionId
if (
this.stationInfo?.beginEndMeterValues === true &&
this.stationInfo.ocppStrictCompliance === true &&
createSerialNumber(stationTemplate, stationInfo)
stationInfo.voltageOut = this.getVoltageOut(stationInfo)
if (isNotEmptyArray(stationTemplate.power)) {
- stationTemplate.power = stationTemplate.power as number[]
const powerArrayRandomIndex = Math.floor(secureRandom() * stationTemplate.power.length)
stationInfo.maximumPower =
stationTemplate.powerUnit === PowerUnits.KILO_WATT
? stationTemplate.power[powerArrayRandomIndex] * 1000
: stationTemplate.power[powerArrayRandomIndex]
} else {
- stationTemplate.power = stationTemplate.power as number
stationInfo.maximumPower =
stationTemplate.powerUnit === PowerUnits.KILO_WATT
- ? stationTemplate.power * 1000
+ ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ stationTemplate.power! * 1000
: stationTemplate.power
}
stationInfo.maximumAmperage = this.getMaximumAmperage(stationInfo)
stationTemplate.firmwareVersionPattern ?? Constants.SEMVER_PATTERN
if (
isNotEmptyString(stationInfo.firmwareVersion) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- !new RegExp(stationInfo.firmwareVersionPattern).test(stationInfo.firmwareVersion!)
+ !new RegExp(stationInfo.firmwareVersionPattern).test(stationInfo.firmwareVersion)
) {
logger.warn(
`${this.logPrefix()} Firmware version '${stationInfo.firmwareVersion}' in template file ${
) {
const patternGroup =
this.stationInfo.firmwareUpgrade?.versionUpgrade?.patternGroup ??
- this.stationInfo.firmwareVersion?.split('.').length
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const match = new RegExp(this.stationInfo.firmwareVersionPattern!)
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- .exec(this.stationInfo.firmwareVersion!)
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- ?.slice(1, patternGroup! + 1)
+ this.stationInfo.firmwareVersion.split('.').length
+ const match = new RegExp(this.stationInfo.firmwareVersionPattern)
+ .exec(this.stationInfo.firmwareVersion)
+ ?.slice(1, patternGroup + 1)
if (match != null) {
const patchLevelIndex = match.length - 1
match[patchLevelIndex] = (
this.initializeOcppConfiguration()
this.initializeOcppServices()
this.once(ChargingStationEvents.accepted, () => {
- this.startMessageSequence().catch((error) => {
+ this.startMessageSequence().catch(error => {
logger.error(`${this.logPrefix()} Error while starting the message sequence:`, error)
})
})
if (
this.stationInfo?.supervisionUrlOcppConfiguration === true &&
isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!) == null
+ getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey) == null
) {
addConfigurationKey(
this,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.stationInfo.supervisionUrlOcppKey!,
+ this.stationInfo.supervisionUrlOcppKey,
this.configuredSupervisionUrl.href,
{ reboot: true }
)
} else if (
this.stationInfo?.supervisionUrlOcppConfiguration === false &&
isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!) != null
+ getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey) != null
) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- deleteConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!, { save: false })
+ deleteConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey, { save: false })
}
if (
isNotEmptyString(this.stationInfo?.amperageLimitationOcppKey) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- getConfigurationKey(this, this.stationInfo.amperageLimitationOcppKey!) == null
+ getConfigurationKey(this, this.stationInfo.amperageLimitationOcppKey) == null
) {
addConfigurationKey(
this,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.stationInfo!.amperageLimitationOcppKey!,
+ this.stationInfo.amperageLimitationOcppKey,
// prettier-ignore
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- (this.stationInfo!.maximumAmperage! * getAmperageLimitationUnitDivider(this.stationInfo)).toString()
+ (this.stationInfo.maximumAmperage! * getAmperageLimitationUnitDivider(this.stationInfo)).toString()
)
}
if (getConfigurationKey(this, StandardParametersKey.SupportedFeatureProfiles) == null) {
private initializeConnectorsOrEvsesFromFile (configuration: ChargingStationConfiguration): void {
if (configuration.connectorsStatus != null && configuration.evsesStatus == null) {
for (const [connectorId, connectorStatus] of configuration.connectorsStatus.entries()) {
- this.connectors.set(connectorId, cloneObject<ConnectorStatus>(connectorStatus))
+ this.connectors.set(connectorId, clone<ConnectorStatus>(connectorStatus))
}
} else if (configuration.evsesStatus != null && configuration.connectorsStatus == null) {
for (const [evseId, evseStatusConfiguration] of configuration.evsesStatus.entries()) {
- const evseStatus = cloneObject<EvseStatusConfiguration>(evseStatusConfiguration)
+ const evseStatus = clone<EvseStatusConfiguration>(evseStatusConfiguration)
delete evseStatus.connectorsStatus
this.evses.set(evseId, {
...(evseStatus as EvseStatus),
this.logPrefix(),
this.templateFile
)
- this.connectors.set(connectorId, cloneObject<ConnectorStatus>(connectorStatus))
+ this.connectors.set(connectorId, clone<ConnectorStatus>(connectorStatus))
}
initializeConnectorsMapStatus(this.connectors, this.logPrefix())
this.saveConnectorsStatus()
const configurationFromFile = this.getConfigurationFromFile()
let configurationData: ChargingStationConfiguration =
configurationFromFile != null
- ? cloneObject<ChargingStationConfiguration>(configurationFromFile)
+ ? clone<ChargingStationConfiguration>(configurationFromFile)
: {}
if (this.stationInfo?.stationInfoPersistentConfiguration === true) {
configurationData.stationInfo = this.stationInfo
this.sharedLRUCache.deleteChargingStationConfiguration(this.configurationFileHash)
this.sharedLRUCache.setChargingStationConfiguration(configurationData)
this.configurationFileHash = configurationHash
- }).catch((error) => {
+ }).catch(error => {
handleFileException(
this.configurationFile,
FileType.ChargingStationConfiguration,
>(this, RequestCommand.BOOT_NOTIFICATION, this.bootNotificationRequest, {
skipBufferingOnError: true
})
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ this.bootNotificationResponse.currentTime = convertToDate(
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ this.bootNotificationResponse?.currentTime
+ )!
if (!this.isRegistered()) {
this.stationInfo?.registrationMaxRetries !== -1 && ++registrationRetryCount
await sleep(
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- this.bootNotificationResponse.interval != null
+ this.bootNotificationResponse?.interval != null
? secondsToMilliseconds(this.bootNotificationResponse.interval)
: Constants.DEFAULT_BOOT_NOTIFICATION_INTERVAL
)
}
} else {
logger.error(
- `${this.logPrefix()} Registration failure: maximum retries reached (${registrationRetryCount}) or retry disabled (${this
- .stationInfo?.registrationMaxRetries})`
+ `${this.logPrefix()} Registration failure: maximum retries reached (${registrationRetryCount}) or retry disabled (${
+ this.stationInfo?.registrationMaxRetries
+ })`
)
}
this.autoReconnectRetryCount = 0
logger.error(`${this.logPrefix()} WebSocket error:`, error)
}
- private getEnergyActiveImportRegister (connectorStatus: ConnectorStatus, rounded = false): number {
+ private getEnergyActiveImportRegister (
+ connectorStatus: ConnectorStatus | undefined,
+ rounded = false
+ ): number {
if (this.stationInfo?.meteringPerTransaction === true) {
return (
(rounded
- ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- Math.round(connectorStatus.transactionEnergyActiveImportRegisterValue!)
- : connectorStatus.transactionEnergyActiveImportRegisterValue) ?? 0
+ ? connectorStatus?.transactionEnergyActiveImportRegisterValue != null
+ ? Math.round(connectorStatus.transactionEnergyActiveImportRegisterValue)
+ : undefined
+ : connectorStatus?.transactionEnergyActiveImportRegisterValue) ?? 0
)
}
return (
(rounded
- ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- Math.round(connectorStatus.energyActiveImportRegisterValue!)
- : connectorStatus.energyActiveImportRegisterValue) ?? 0
+ ? connectorStatus?.energyActiveImportRegisterValue != null
+ ? Math.round(connectorStatus.energyActiveImportRegisterValue)
+ : undefined
+ : connectorStatus?.energyActiveImportRegisterValue) ?? 0
)
}
private getAmperageLimitation (): number | undefined {
if (
isNotEmptyString(this.stationInfo?.amperageLimitationOcppKey) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- getConfigurationKey(this, this.stationInfo!.amperageLimitationOcppKey!) != null
+ getConfigurationKey(this, this.stationInfo.amperageLimitationOcppKey) != null
) {
return (
- convertToInt(
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- getConfigurationKey(this, this.stationInfo!.amperageLimitationOcppKey!)!.value
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- ) / getAmperageLimitationUnitDivider(this.stationInfo!)
+ convertToInt(getConfigurationKey(this, this.stationInfo.amperageLimitationOcppKey)?.value) /
+ getAmperageLimitationUnitDivider(this.stationInfo)
)
}
}
let configuredSupervisionUrlIndex: number
switch (Configuration.getSupervisionUrlDistribution()) {
case SupervisionUrlDistribution.RANDOM:
- configuredSupervisionUrlIndex = Math.floor(
- secureRandom() * (supervisionUrls as string[]).length
- )
+ configuredSupervisionUrlIndex = Math.floor(secureRandom() * supervisionUrls.length)
break
case SupervisionUrlDistribution.ROUND_ROBIN:
case SupervisionUrlDistribution.CHARGING_STATION_AFFINITY:
SupervisionUrlDistribution.CHARGING_STATION_AFFINITY
}`
)
- configuredSupervisionUrlIndex = (this.index - 1) % (supervisionUrls as string[]).length
+ configuredSupervisionUrlIndex = (this.index - 1) % supervisionUrls.length
break
}
- configuredSupervisionUrl = (supervisionUrls as string[])[configuredSupervisionUrlIndex]
+ configuredSupervisionUrl = supervisionUrls[configuredSupervisionUrlIndex]
} else {
- configuredSupervisionUrl = supervisionUrls as string
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ configuredSupervisionUrl = supervisionUrls!
}
if (isNotEmptyString(configuredSupervisionUrl)) {
return new URL(configuredSupervisionUrl)