},
plugins: ['@typescript-eslint', 'eslint-plugin-tsdoc'],
extends: [
- 'plugin:@typescript-eslint/recommended-type-checked',
+ 'plugin:@typescript-eslint/strict-type-checked',
'plugin:@typescript-eslint/stylistic-type-checked',
'plugin:import/typescript',
'standard-with-typescript'
import { build } from 'esbuild'
import { clean } from 'esbuild-plugin-clean'
import { copy } from 'esbuild-plugin-copy'
-
;(async () => {
const isDevelopmentBuild = env.BUILD === 'development'
const sourcemap = !!isDevelopmentBuild
public static getInstance (
chargingStation: ChargingStation
): AutomaticTransactionGenerator | undefined {
- if (!AutomaticTransactionGenerator.instances.has(chargingStation.stationInfo.hashId)) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ if (!AutomaticTransactionGenerator.instances.has(chargingStation.stationInfo!.hashId)) {
AutomaticTransactionGenerator.instances.set(
- chargingStation.stationInfo.hashId,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.hashId,
new AutomaticTransactionGenerator(chargingStation)
)
}
- return AutomaticTransactionGenerator.instances.get(chargingStation.stationInfo.hashId)
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ return AutomaticTransactionGenerator.instances.get(chargingStation.stationInfo!.hashId)
}
public start (): void {
private startConnectors (): void {
if (
- this.connectorsStatus?.size > 0 &&
+ this.connectorsStatus.size > 0 &&
this.connectorsStatus.size !== this.chargingStation.getNumberOfConnectors()
) {
this.connectorsStatus.clear()
)}`
)
while (this.connectorsStatus.get(connectorId)?.start === true) {
- await this.waitChargingStationServiceInitialization(connectorId)
await this.waitChargingStationAvailable(connectorId)
await this.waitConnectorAvailable(connectorId)
if (!this.canStartConnector(connectorId)) {
const wait = secondsToMilliseconds(
getRandomInteger(
this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
- .maxDelayBetweenTwoTransactions,
+ ?.maxDelayBetweenTwoTransactions,
this.chargingStation.getAutomaticTransactionGeneratorConfiguration()
- .minDelayBetweenTwoTransactions
+ ?.minDelayBetweenTwoTransactions
)
)
logger.info(`${this.logPrefix(connectorId)} waiting for ${formatDurationMilliSeconds(wait)}`)
const start = secureRandom()
if (
start <
- this.chargingStation.getAutomaticTransactionGeneratorConfiguration().probabilityOfStart
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ this.chargingStation.getAutomaticTransactionGeneratorConfiguration()!.probabilityOfStart
) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0
// Start transaction
const startResponse = await this.startTransaction(connectorId)
- if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
+ if (startResponse?.idTagInfo.status === AuthorizationStatus.ACCEPTED) {
// Wait until end of transaction
const waitTrxEnd = secondsToMilliseconds(
getRandomInteger(
- this.chargingStation.getAutomaticTransactionGeneratorConfiguration().maxDuration,
- this.chargingStation.getAutomaticTransactionGeneratorConfiguration().minDuration
+ this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.maxDuration,
+ this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.minDuration
)
)
logger.info(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.connectorsStatus.get(connectorId)!.startDate!.getTime() +
hoursToMilliseconds(
- this.chargingStation.getAutomaticTransactionGeneratorConfiguration().stopAfterHours
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ this.chargingStation.getAutomaticTransactionGeneratorConfiguration()!.stopAfterHours
) -
previousRunDuration
)
return true
}
- private async waitChargingStationServiceInitialization (connectorId: number): Promise<void> {
- let logged = false
- while (this.chargingStation?.ocppRequestService == null) {
- if (!logged) {
- logger.info(
- `${this.logPrefix(
- connectorId
- )} transaction loop waiting for charging station service to be initialized`
- )
- logged = true
- }
- await sleep(Constants.CHARGING_STATION_ATG_INITIALIZATION_TIME)
- }
- }
-
private async waitChargingStationAvailable (connectorId: number): Promise<void> {
let logged = false
while (!this.chargingStation.isChargingStationAvailable()) {
if (connectorStatus == null) {
return
}
- delete connectorStatus?.startDate
- delete connectorStatus?.lastRunDate
- delete connectorStatus?.stopDate
- delete connectorStatus?.stoppedDate
+ delete connectorStatus.startDate
+ delete connectorStatus.lastRunDate
+ delete connectorStatus.stopDate
+ delete connectorStatus.stoppedDate
if (
!this.started &&
(connectorStatus.start ||
- !this.chargingStation.getAutomaticTransactionGeneratorConfiguration().enable)
+ this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.enable !== true)
) {
connectorStatus.start = false
}
if (this.chargingStation.hasIdTags()) {
const idTag = IdTagsCache.getInstance().getIdTag(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.chargingStation.getAutomaticTransactionGeneratorConfiguration().idTagDistribution!,
+ this.chargingStation.getAutomaticTransactionGeneratorConfiguration()!.idTagDistribution!,
this.chargingStation,
connectorId
)
stopResponse = await this.chargingStation.stopTransactionOnConnector(connectorId, reason)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
++this.connectorsStatus.get(connectorId)!.stopTransactionRequests!
- if (stopResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
+ if (stopResponse.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
++this.connectorsStatus.get(connectorId)!.acceptedStopTransactionRequests!
} else {
private readonly logPrefix = (connectorId?: number): string => {
return logPrefix(
- ` ${this.chargingStation.stationInfo.chargingStationId} | ATG${
+ ` ${this.chargingStation.stationInfo?.chargingStationId} | ATG${
connectorId != null ? ` on connector #${connectorId}` : ''
}:`
)
): void {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
++this.connectorsStatus.get(connectorId)!.startTransactionRequests!
- if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
+ if (startResponse.idTagInfo.status === AuthorizationStatus.ACCEPTED) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
++this.connectorsStatus.get(connectorId)!.acceptedStartTransactionRequests!
} else {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
for (const stationTemplateUrl of Configuration.getStationTemplateUrls()!) {
try {
- const nbStations = stationTemplateUrl.numberOfStations ?? 0
+ const nbStations = stationTemplateUrl.numberOfStations
for (let index = 1; index <= nbStations; index++) {
await this.startChargingStation(index, stationTemplateUrl)
}
: ''
} worker(s) concurrently running in '${workerConfiguration.processType}' mode${
this.workerImplementation?.maxElementsPerWorker != null
- ? ` (${this.workerImplementation?.maxElementsPerWorker} charging station(s) per worker)`
+ ? ` (${this.workerImplementation.maxElementsPerWorker} charging station(s) per worker)`
: ''
}`
)
private initializeWorkerImplementation (workerConfiguration: WorkerConfiguration): void {
let elementsPerWorker: number | undefined
- switch (workerConfiguration?.elementsPerWorker) {
+ switch (workerConfiguration.elementsPerWorker) {
case 'auto':
elementsPerWorker =
this.numberOfChargingStations > availableParallelism()
if (isNotEmptyArray(stationTemplateUrls)) {
this.numberOfChargingStationTemplates = stationTemplateUrls.length
for (const stationTemplateUrl of stationTemplateUrls) {
- this.numberOfChargingStations += stationTemplateUrl.numberOfStations ?? 0
+ this.numberOfChargingStations += stationTemplateUrl.numberOfStations
}
} else {
console.warn(
private gracefulShutdown (): void {
this.stop()
.then(() => {
- console.info(`${chalk.green('Graceful shutdown')}`)
+ console.info(chalk.green('Graceful shutdown'))
this.uiServer?.stop()
// stop() asks for charging stations to stop by default
this.waitChargingStationsStopped()
export class ChargingStation extends EventEmitter {
public readonly index: number
public readonly templateFile: string
- public stationInfo!: ChargingStationInfo
+ public stationInfo?: ChargingStationInfo
public started: boolean
public starting: boolean
public idTagsCache: IdTagsCache
public ocppRequestService!: OCPPRequestService
public bootNotificationRequest!: BootNotificationRequest
public bootNotificationResponse!: BootNotificationResponse | undefined
- public powerDivider!: number
+ public powerDivider?: number
private stopping: boolean
private configurationFile!: string
private configurationFileHash!: string
return new URL(
`${
this.stationInfo?.supervisionUrlOcppConfiguration === true &&
- isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey) &&
+ 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
: this.configuredSupervisionUrl.href
- }/${this.stationInfo.chargingStationId}`
+ }/${this.stationInfo?.chargingStationId}`
)
}
public logPrefix = (): string => {
- if (isNotEmptyString(this?.stationInfo?.chargingStationId)) {
- return logPrefix(` ${this?.stationInfo?.chargingStationId} |`)
+ if (isNotEmptyString(this.stationInfo?.chargingStationId)) {
+ return logPrefix(` ${this.stationInfo?.chargingStationId} |`)
}
let stationTemplate: ChargingStationTemplate | undefined
try {
public hasIdTags (): boolean {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- return isNotEmptyArray(this.idTagsCache.getIdTags(getIdTagsFile(this.stationInfo)!))
+ return isNotEmptyArray(this.idTagsCache.getIdTags(getIdTagsFile(this.stationInfo!)!))
}
public getNumberOfPhases (stationInfo?: ChargingStationInfo): number {
- const localStationInfo: ChargingStationInfo = stationInfo ?? this.stationInfo
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ const localStationInfo: ChargingStationInfo = stationInfo ?? this.stationInfo!
switch (this.getCurrentOutType(stationInfo)) {
case CurrentType.AC:
return localStationInfo.numberOfPhases ?? 3
}
public isWebSocketConnectionOpened (): boolean {
- return this?.wsConnection?.readyState === WebSocket.OPEN
+ return this.wsConnection?.readyState === WebSocket.OPEN
}
public inUnknownState (): boolean {
- return this?.bootNotificationResponse?.status == null
+ return this.bootNotificationResponse?.status == null
}
public inPendingState (): boolean {
- return this?.bootNotificationResponse?.status === RegistrationStatusEnumType.PENDING
+ return this.bootNotificationResponse?.status === RegistrationStatusEnumType.PENDING
}
public inAcceptedState (): boolean {
- return this?.bootNotificationResponse?.status === RegistrationStatusEnumType.ACCEPTED
+ return this.bootNotificationResponse?.status === RegistrationStatusEnumType.ACCEPTED
}
public inRejectedState (): boolean {
- return this?.bootNotificationResponse?.status === RegistrationStatusEnumType.REJECTED
+ return this.bootNotificationResponse?.status === RegistrationStatusEnumType.REJECTED
}
public isRegistered (): boolean {
if (
this.getAmperageLimitation() != null &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.getAmperageLimitation()! < this.stationInfo.maximumAmperage!
+ this.getAmperageLimitation()! < this.stationInfo!.maximumAmperage!
) {
connectorAmperageLimitationPowerLimit =
(this.stationInfo?.currentOutType === CurrentType.AC
(this.hasEvses ? this.getNumberOfEvses() : this.getNumberOfConnectors())
)
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- DCElectricUtils.power(this.stationInfo.voltageOut!, this.getAmperageLimitation()!)) /
- this.powerDivider
+ DCElectricUtils.power(this.stationInfo!.voltageOut!, this.getAmperageLimitation()!)) /
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ this.powerDivider!
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const connectorMaximumPower = this.stationInfo.maximumPower! / this.powerDivider
+ const connectorMaximumPower = this.stationInfo!.maximumPower! / this.powerDivider!
const connectorChargingProfilesPowerLimit =
getChargingStationConnectorChargingProfilesPowerLimit(this, connectorId)
return min(
public setSupervisionUrl (url: string): void {
if (
this.stationInfo?.supervisionUrlOcppConfiguration === true &&
- isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey)
+ isNotEmptyString(this.stationInfo.supervisionUrlOcppKey)
) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
setConfigurationKeyValue(this, this.stationInfo.supervisionUrlOcppKey!, url)
} else {
- this.stationInfo.supervisionUrls = url
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ this.stationInfo!.supervisionUrls = url
this.saveStationInfo()
this.configuredSupervisionUrl = this.getConfiguredSupervisionUrl()
}
// Initialize
this.initialize()
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.idTagsCache.deleteIdTags(getIdTagsFile(this.stationInfo)!)
+ this.idTagsCache.deleteIdTags(getIdTagsFile(this.stationInfo!)!)
// Restart the ATG
this.stopAutomaticTransactionGenerator()
delete this.automaticTransactionGeneratorConfiguration
- if (this.getAutomaticTransactionGeneratorConfiguration().enable) {
+ if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) {
this.startAutomaticTransactionGenerator()
}
if (this.stationInfo?.enableStatistics === true) {
public async reset (reason?: StopTransactionReason): Promise<void> {
await this.stop(reason)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- await sleep(this.stationInfo.resetTime!)
+ await sleep(this.stationInfo!.resetTime!)
this.initialize()
this.start()
}
if (!checkChargingStation(this, this.logPrefix())) {
return
}
- if (this.stationInfo.supervisionUser != null && this.stationInfo.supervisionPassword != null) {
+ if (this.stationInfo?.supervisionUser != null && this.stationInfo.supervisionPassword != null) {
options.auth = `${this.stationInfo.supervisionUser}:${this.stationInfo.supervisionPassword}`
}
- if (params?.closeOpened === true) {
+ if (params.closeOpened === true) {
this.closeWSConnection()
}
- if (params?.terminateOpened === true) {
+ if (params.terminateOpened === true) {
this.terminateWSConnection()
}
}
}
- public getAutomaticTransactionGeneratorConfiguration (): AutomaticTransactionGeneratorConfiguration {
+ public getAutomaticTransactionGeneratorConfiguration ():
+ | AutomaticTransactionGeneratorConfiguration
+ | undefined {
if (this.automaticTransactionGeneratorConfiguration == null) {
let automaticTransactionGeneratorConfiguration:
| AutomaticTransactionGeneratorConfiguration
stationConfiguration?.automaticTransactionGenerator != null
) {
automaticTransactionGeneratorConfiguration =
- stationConfiguration?.automaticTransactionGenerator
+ stationConfiguration.automaticTransactionGenerator
} else {
automaticTransactionGeneratorConfiguration = stationTemplate?.AutomaticTransactionGenerator
}
const transactionId = this.getConnectorStatus(connectorId)?.transactionId
if (
this.stationInfo?.beginEndMeterValues === true &&
- this.stationInfo?.ocppStrictCompliance === true &&
- this.stationInfo?.outOfOrderEndMeterValues === false
+ this.stationInfo.ocppStrictCompliance === true &&
+ this.stationInfo.outOfOrderEndMeterValues === false
) {
const transactionEndMeterValue = buildTransactionEndMeterValue(
this,
if (this.hasEvses) {
for (const evseStatus of this.evses.values()) {
for (const connectorStatus of evseStatus.connectors.values()) {
- if (connectorStatus?.reservation?.[filterKey] === value) {
+ if (connectorStatus.reservation?.[filterKey] === value) {
return connectorStatus.reservation
}
}
}
} else {
for (const connectorStatus of this.connectors.values()) {
- if (connectorStatus?.reservation?.[filterKey] === value) {
+ if (connectorStatus.reservation?.[filterKey] === value) {
return connectorStatus.reservation
}
}
checkTemplate(stationTemplate, this.logPrefix(), this.templateFile)
const warnTemplateKeysDeprecationOnce = once(warnTemplateKeysDeprecation, this)
warnTemplateKeysDeprecationOnce(stationTemplate, this.logPrefix(), this.templateFile)
- if (stationTemplate?.Connectors != null) {
+ if (stationTemplate.Connectors != null) {
checkConnectorsConfiguration(stationTemplate, this.logPrefix(), this.templateFile)
}
const stationInfo: ChargingStationInfo = stationTemplateToStationInfo(stationTemplate)
stationInfo.hashId = getHashId(this.index, stationTemplate)
stationInfo.chargingStationId = getChargingStationId(this.index, stationTemplate)
- stationInfo.ocppVersion = stationTemplate?.ocppVersion ?? OCPPVersion.VERSION_16
+ stationInfo.ocppVersion = stationTemplate.ocppVersion ?? OCPPVersion.VERSION_16
createSerialNumber(stationTemplate, stationInfo)
stationInfo.voltageOut = this.getVoltageOut(stationInfo)
- if (isNotEmptyArray(stationTemplate?.power)) {
+ 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.powerUnit === PowerUnits.KILO_WATT
? stationTemplate.power[powerArrayRandomIndex] * 1000
: stationTemplate.power[powerArrayRandomIndex]
} else {
- stationTemplate.power = stationTemplate?.power as number
+ stationTemplate.power = stationTemplate.power as number
stationInfo.maximumPower =
- stationTemplate?.powerUnit === PowerUnits.KILO_WATT
+ stationTemplate.powerUnit === PowerUnits.KILO_WATT
? stationTemplate.power * 1000
: stationTemplate.power
}
stationInfo.maximumAmperage = this.getMaximumAmperage(stationInfo)
stationInfo.firmwareVersionPattern =
- stationTemplate?.firmwareVersionPattern ?? Constants.SEMVER_PATTERN
+ stationTemplate.firmwareVersionPattern ?? Constants.SEMVER_PATTERN
if (
isNotEmptyString(stationInfo.firmwareVersion) &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
},
reset: true
},
- stationTemplate?.firmwareUpgrade ?? {}
+ stationTemplate.firmwareUpgrade ?? {}
)
stationInfo.resetTime =
- stationTemplate?.resetTime != null
+ stationTemplate.resetTime != null
? secondsToMilliseconds(stationTemplate.resetTime)
: Constants.CHARGING_STATION_DEFAULT_RESET_TIME
return stationInfo
if (stationInfoPersistentConfiguration) {
stationInfo = this.getConfigurationFromFile()?.stationInfo
if (stationInfo != null) {
- delete stationInfo?.infoHash
+ delete stationInfo.infoHash
}
}
return stationInfo
const defaultStationInfo = Constants.DEFAULT_STATION_INFO
const stationInfoFromTemplate: ChargingStationInfo = this.getStationInfoFromTemplate()
const stationInfoFromFile: ChargingStationInfo | undefined = this.getStationInfoFromFile(
- stationInfoFromTemplate?.stationInfoPersistentConfiguration
+ stationInfoFromTemplate.stationInfoPersistentConfiguration
)
// Priority:
// 1. charging station info from template
}
stationInfoFromFile != null &&
propagateSerialNumber(
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.getTemplateFromFile()!,
+ this.getTemplateFromFile(),
stationInfoFromFile,
stationInfoFromTemplate
)
)
const stationConfiguration = this.getConfigurationFromFile()
if (
- stationConfiguration?.stationInfo?.templateHash === stationTemplate?.templateHash &&
+ stationConfiguration?.stationInfo?.templateHash === stationTemplate.templateHash &&
(stationConfiguration?.connectorsStatus != null || stationConfiguration?.evsesStatus != null)
) {
checkConfiguration(stationConfiguration, this.logPrefix(), this.configurationFile)
}
this.saveStationInfo()
this.configuredSupervisionUrl = this.getConfiguredSupervisionUrl()
- if (this.stationInfo?.enableStatistics === true) {
+ if (this.stationInfo.enableStatistics === true) {
this.performanceStatistics = PerformanceStatistics.getInstance(
this.stationInfo.hashId,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
logger.error(`${this.logPrefix()} Error while starting the message sequence:`, error)
})
})
- if (this.stationInfo?.autoRegister === true) {
+ if (this.stationInfo.autoRegister === true) {
this.bootNotificationResponse = {
currentTime: new Date(),
interval: millisecondsToSeconds(this.getHeartbeatInterval()),
}
if (
this.stationInfo?.supervisionUrlOcppConfiguration === true &&
- isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey) &&
+ isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!) == null
) {
)
} else if (
this.stationInfo?.supervisionUrlOcppConfiguration === false &&
- isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey) &&
+ isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!) != null
) {
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) {
+ if (configuration.connectorsStatus != null && configuration.evsesStatus == null) {
for (const [connectorId, connectorStatus] of configuration.connectorsStatus.entries()) {
this.connectors.set(connectorId, cloneObject<ConnectorStatus>(connectorStatus))
}
- } else if (configuration?.evsesStatus != null && configuration?.connectorsStatus == null) {
+ } else if (configuration.evsesStatus != null && configuration.connectorsStatus == null) {
for (const [evseId, evseStatusConfiguration] of configuration.evsesStatus.entries()) {
const evseStatus = cloneObject<EvseStatusConfiguration>(evseStatusConfiguration)
delete evseStatus.connectorsStatus
)
})
}
- } else if (configuration?.evsesStatus != null && configuration?.connectorsStatus != null) {
+ } else if (configuration.evsesStatus != null && configuration.connectorsStatus != null) {
const errorMsg = `Connectors and evses defined at the same time in configuration file ${this.configurationFile}`
logger.error(`${this.logPrefix()} ${errorMsg}`)
throw new BaseError(errorMsg)
}
private initializeConnectorsOrEvsesFromTemplate (stationTemplate: ChargingStationTemplate): void {
- if (stationTemplate?.Connectors != null && stationTemplate?.Evses == null) {
+ if (stationTemplate.Connectors != null && stationTemplate.Evses == null) {
this.initializeConnectorsFromTemplate(stationTemplate)
- } else if (stationTemplate?.Evses != null && stationTemplate?.Connectors == null) {
+ } else if (stationTemplate.Evses != null && stationTemplate.Connectors == null) {
this.initializeEvsesFromTemplate(stationTemplate)
- } else if (stationTemplate?.Evses != null && stationTemplate?.Connectors != null) {
+ } else if (stationTemplate.Evses != null && stationTemplate.Connectors != null) {
const errorMsg = `Connectors and evses defined at the same time in template file ${this.templateFile}`
logger.error(`${this.logPrefix()} ${errorMsg}`)
throw new BaseError(errorMsg)
}
private initializeConnectorsFromTemplate (stationTemplate: ChargingStationTemplate): void {
- if (stationTemplate?.Connectors == null && this.connectors.size === 0) {
+ if (stationTemplate.Connectors == null && this.connectors.size === 0) {
const errorMsg = `No already defined connectors and charging station information from template ${this.templateFile} with no connectors configuration defined`
logger.error(`${this.logPrefix()} ${errorMsg}`)
throw new BaseError(errorMsg)
}
- if (stationTemplate?.Connectors?.[0] == null) {
+ if (stationTemplate.Connectors?.[0] == null) {
logger.warn(
`${this.logPrefix()} Charging station information from template ${
this.templateFile
} with no connector id 0 configuration`
)
}
- if (stationTemplate?.Connectors != null) {
+ if (stationTemplate.Connectors != null) {
const { configuredMaxConnectors, templateMaxConnectors, templateMaxAvailableConnectors } =
checkConnectorsConfiguration(stationTemplate, this.logPrefix(), this.templateFile)
const connectorsConfigHash = createHash(Constants.DEFAULT_HASH_ALGORITHM)
.update(
- `${JSON.stringify(stationTemplate?.Connectors)}${configuredMaxConnectors.toString()}`
+ `${JSON.stringify(stationTemplate.Connectors)}${configuredMaxConnectors.toString()}`
)
.digest('hex')
const connectorsConfigChanged =
- this.connectors?.size !== 0 && this.connectorsConfigurationHash !== connectorsConfigHash
- if (this.connectors?.size === 0 || connectorsConfigChanged) {
+ this.connectors.size !== 0 && this.connectorsConfigurationHash !== connectorsConfigHash
+ if (this.connectors.size === 0 || connectorsConfigChanged) {
connectorsConfigChanged && this.connectors.clear()
this.connectorsConfigurationHash = connectorsConfigHash
if (templateMaxConnectors > 0) {
for (let connectorId = 0; connectorId <= configuredMaxConnectors; connectorId++) {
if (
connectorId === 0 &&
- (stationTemplate?.Connectors?.[connectorId] == null ||
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ (stationTemplate.Connectors[connectorId] == null ||
!this.getUseConnectorId0(stationTemplate))
) {
continue
}
const templateConnectorId =
- connectorId > 0 && stationTemplate?.randomConnectors === true
+ connectorId > 0 && stationTemplate.randomConnectors === true
? getRandomInteger(templateMaxAvailableConnectors, 1)
: connectorId
- const connectorStatus = stationTemplate?.Connectors[templateConnectorId]
+ const connectorStatus = stationTemplate.Connectors[templateConnectorId]
checkStationInfoConnectorStatus(
templateConnectorId,
connectorStatus,
}
private initializeEvsesFromTemplate (stationTemplate: ChargingStationTemplate): void {
- if (stationTemplate?.Evses == null && this.evses.size === 0) {
+ if (stationTemplate.Evses == null && this.evses.size === 0) {
const errorMsg = `No already defined evses and charging station information from template ${this.templateFile} with no evses configuration defined`
logger.error(`${this.logPrefix()} ${errorMsg}`)
throw new BaseError(errorMsg)
}
- if (stationTemplate?.Evses?.[0] == null) {
+ if (stationTemplate.Evses?.[0] == null) {
logger.warn(
`${this.logPrefix()} Charging station information from template ${
this.templateFile
} with no evse id 0 configuration`
)
}
- if (stationTemplate?.Evses?.[0]?.Connectors?.[0] == null) {
+ if (stationTemplate.Evses?.[0]?.Connectors[0] == null) {
logger.warn(
`${this.logPrefix()} Charging station information from template ${
this.templateFile
} with evse id 0 with no connector id 0 configuration`
)
}
- if (Object.keys(stationTemplate?.Evses?.[0]?.Connectors as object).length > 1) {
+ if (Object.keys(stationTemplate.Evses?.[0]?.Connectors as object).length > 1) {
logger.warn(
`${this.logPrefix()} Charging station information from template ${
this.templateFile
} with evse id 0 with more than one connector configuration, only connector id 0 configuration will be used`
)
}
- if (stationTemplate?.Evses != null) {
+ if (stationTemplate.Evses != null) {
const evsesConfigHash = createHash(Constants.DEFAULT_HASH_ALGORITHM)
- .update(JSON.stringify(stationTemplate?.Evses))
+ .update(JSON.stringify(stationTemplate.Evses))
.digest('hex')
const evsesConfigChanged =
- this.evses?.size !== 0 && this.evsesConfigurationHash !== evsesConfigHash
- if (this.evses?.size === 0 || evsesConfigChanged) {
+ this.evses.size !== 0 && this.evsesConfigurationHash !== evsesConfigHash
+ if (this.evses.size === 0 || evsesConfigChanged) {
evsesConfigChanged && this.evses.clear()
this.evsesConfigurationHash = evsesConfigHash
- const templateMaxEvses = getMaxNumberOfEvses(stationTemplate?.Evses)
+ const templateMaxEvses = getMaxNumberOfEvses(stationTemplate.Evses)
if (templateMaxEvses > 0) {
for (const evseKey in stationTemplate.Evses) {
const evseId = convertToInt(evseKey)
this.evses.set(evseId, {
connectors: buildConnectorsMap(
- stationTemplate?.Evses[evseKey]?.Connectors,
+ stationTemplate.Evses[evseKey].Connectors,
this.logPrefix(),
this.templateFile
),
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
cloneObject<ChargingStationConfiguration>(this.getConfigurationFromFile()!)
: {}
- if (
- this.stationInfo?.stationInfoPersistentConfiguration === true &&
- this.stationInfo != null
- ) {
+ if (this.stationInfo?.stationInfoPersistentConfiguration === true) {
configurationData.stationInfo = this.stationInfo
} else {
delete configurationData.stationInfo
this.stationInfo?.ocppPersistentConfiguration === true &&
Array.isArray(this.ocppConfiguration?.configurationKey)
) {
- configurationData.configurationKey = this.ocppConfiguration?.configurationKey
+ configurationData.configurationKey = this.ocppConfiguration.configurationKey
} else {
delete configurationData.configurationKey
}
if (!this.isRegistered()) {
this.stationInfo?.registrationMaxRetries !== -1 && ++registrationRetryCount
await sleep(
- this?.bootNotificationResponse?.interval != null
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ this.bootNotificationResponse.interval != null
? secondsToMilliseconds(this.bootNotificationResponse.interval)
: Constants.DEFAULT_BOOT_NOTIFICATION_INTERVAL
)
} while (
!this.isRegistered() &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- (registrationRetryCount <= this.stationInfo.registrationMaxRetries! ||
+ (registrationRetryCount <= this.stationInfo!.registrationMaxRetries! ||
this.stationInfo?.registrationMaxRetries === -1)
)
}
messageId
)!
logger.debug(
- `${this.logPrefix()} << Command '${
- requestCommandName ?? Constants.UNKNOWN_COMMAND
- }' received response payload: ${JSON.stringify(response)}`
+ `${this.logPrefix()} << Command '${requestCommandName}' received response payload: ${JSON.stringify(
+ response
+ )}`
)
responseCallback(commandPayload, requestPayload)
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const [, errorCallback, requestCommandName] = this.getCachedRequest(messageType, messageId)!
logger.debug(
- `${this.logPrefix()} << Command '${
- requestCommandName ?? Constants.UNKNOWN_COMMAND
- }' received error response payload: ${JSON.stringify(errorResponse)}`
+ `${this.logPrefix()} << Command '${requestCommandName}' received error response payload: ${JSON.stringify(
+ errorResponse
+ )}`
)
errorCallback(new OCPPError(errorType, errorMessage, requestCommandName, errorDetails))
}
(rounded
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Math.round(connectorStatus.transactionEnergyActiveImportRegisterValue!)
- : connectorStatus?.transactionEnergyActiveImportRegisterValue) ?? 0
+ : connectorStatus.transactionEnergyActiveImportRegisterValue) ?? 0
)
}
return (
(rounded
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Math.round(connectorStatus.energyActiveImportRegisterValue!)
- : connectorStatus?.energyActiveImportRegisterValue) ?? 0
+ : connectorStatus.energyActiveImportRegisterValue) ?? 0
)
}
private getConnectionTimeout (): number {
if (getConfigurationKey(this, StandardParametersKey.ConnectionTimeOut) != null) {
return convertToInt(
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- getConfigurationKey(this, StandardParametersKey.ConnectionTimeOut)!.value! ??
+ getConfigurationKey(this, StandardParametersKey.ConnectionTimeOut)?.value ??
Constants.DEFAULT_CONNECTION_TIMEOUT
)
}
private getMaximumAmperage (stationInfo?: ChargingStationInfo): number | undefined {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const maximumPower = (stationInfo ?? this.stationInfo).maximumPower!
+ const maximumPower = (stationInfo ?? this.stationInfo!).maximumPower!
switch (this.getCurrentOutType(stationInfo)) {
case CurrentType.AC:
return ACElectricUtils.amperagePerPhaseFromPower(
}
private getCurrentOutType (stationInfo?: ChargingStationInfo): CurrentType {
- return (stationInfo ?? this.stationInfo).currentOutType ?? CurrentType.AC
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ return (stationInfo ?? this.stationInfo!).currentOutType ?? CurrentType.AC
}
private getVoltageOut (stationInfo?: ChargingStationInfo): Voltage {
return (
- (stationInfo ?? this.stationInfo).voltageOut ??
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ (stationInfo ?? this.stationInfo!).voltageOut ??
getDefaultVoltageOut(this.getCurrentOutType(stationInfo), this.logPrefix(), this.templateFile)
)
}
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
- ) / getAmperageLimitationUnitDivider(this.stationInfo)
+ getConfigurationKey(this, this.stationInfo!.amperageLimitationOcppKey!)!.value
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ ) / getAmperageLimitationUnitDivider(this.stationInfo!)
)
}
}
}
}
}
- if (this.stationInfo.firmwareStatus === FirmwareStatus.Installing) {
+ if (this.stationInfo?.firmwareStatus === FirmwareStatus.Installing) {
await this.ocppRequestService.requestHandler<
FirmwareStatusNotificationRequest,
FirmwareStatusNotificationResponse
}
// Start the ATG
- if (this.getAutomaticTransactionGeneratorConfiguration().enable) {
+ if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) {
this.startAutomaticTransactionGenerator()
}
this.flushMessageBuffer()
evseId
)
)
- delete connectorStatus?.status
+ delete connectorStatus.status
}
}
}
}
const errorMsg = 'No supervision url(s) configured'
logger.error(`${this.logPrefix()} ${errorMsg}`)
- throw new BaseError(`${errorMsg}`)
+ throw new BaseError(errorMsg)
}
private stopHeartbeat (): void {
// Stop heartbeat
this.stopHeartbeat()
// Stop the ATG if needed
- if (this.getAutomaticTransactionGeneratorConfiguration().stopOnConnectionFailure) {
+ if (this.getAutomaticTransactionGeneratorConfiguration()?.stopOnConnectionFailure === true) {
this.stopAutomaticTransactionGenerator()
}
if (
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- this.autoReconnectRetryCount < this.stationInfo.autoReconnectMaxRetries! ||
+ this.autoReconnectRetryCount < this.stationInfo!.autoReconnectMaxRetries! ||
this.stationInfo?.autoReconnectMaxRetries === -1
) {
++this.autoReconnectRetryCount
: secondsToMilliseconds(this.getConnectionTimeout())
const reconnectDelayWithdraw = 1000
const reconnectTimeout =
- reconnectDelay != null && reconnectDelay - reconnectDelayWithdraw > 0
- ? reconnectDelay - reconnectDelayWithdraw
- : 0
+ reconnectDelay - reconnectDelayWithdraw > 0 ? reconnectDelay - reconnectDelayWithdraw : 0
logger.error(
`${this.logPrefix()} WebSocket connection retry in ${roundTo(
reconnectDelay,
}
params = { ...{ overwrite: false, save: false }, ...params }
let keyFound = getConfigurationKey(chargingStation, key)
- if (keyFound != null && params?.overwrite === true) {
+ if (keyFound != null && params.overwrite === true) {
deleteConfigurationKey(chargingStation, keyFound.key, {
save: false
})
visible: options.visible,
reboot: options.reboot
})
- params?.save === true && chargingStation.saveOcppConfiguration()
+ params.save === true && chargingStation.saveOcppConfiguration()
} else {
logger.error(
`${chargingStation.logPrefix()} Trying to add an already existing configuration key: %j`,
params?: DeleteConfigurationKeyParams
): ConfigurationKey[] | undefined => {
params = { ...{ save: true, caseInsensitive: false }, ...params }
- const keyFound = getConfigurationKey(chargingStation, key, params?.caseInsensitive)
+ const keyFound = getConfigurationKey(chargingStation, key, params.caseInsensitive)
if (keyFound != null) {
const deletedConfigurationKey = chargingStation.ocppConfiguration?.configurationKey?.splice(
chargingStation.ocppConfiguration.configurationKey.indexOf(keyFound),
1
)
- params?.save === true && chargingStation.saveOcppConfiguration()
+ params.save === true && chargingStation.saveOcppConfiguration()
return deletedConfigurationKey
}
}
}
// In case of multiple instances: add instance index to charging station id
const instanceIndex = env.CF_INSTANCE_INDEX ?? 0
- const idSuffix = stationTemplate?.nameSuffix ?? ''
+ const idSuffix = stationTemplate.nameSuffix ?? ''
const idStr = `000000000${index.toString()}`
- return stationTemplate?.fixedName === true
+ return stationTemplate.fixedName === true
? stationTemplate.baseName
: `${stationTemplate.baseName}-${instanceIndex.toString()}${idStr.substring(
idStr.length - 4
}
}
-export const getMaxNumberOfEvses = (evses: Record<string, EvseTemplate>): number => {
+export const getMaxNumberOfEvses = (evses: Record<string, EvseTemplate> | undefined): number => {
if (evses == null) {
return -1
}
return Object.keys(evses).length
}
-const getMaxNumberOfConnectors = (connectors: Record<string, ConnectorStatus>): number => {
+const getMaxNumberOfConnectors = (
+ connectors: Record<string, ConnectorStatus> | undefined
+): number => {
if (connectors == null) {
return -1
}
): ConnectorStatusEnum => {
let connectorBootStatus: ConnectorStatusEnum
if (
- connectorStatus?.status == null &&
+ connectorStatus.status == null &&
(!chargingStation.isChargingStationAvailable() ||
!chargingStation.isConnectorAvailable(connectorId))
) {
connectorBootStatus = ConnectorStatusEnum.Unavailable
- } else if (connectorStatus?.status == null && connectorStatus?.bootStatus != null) {
+ } else if (connectorStatus.status == null && connectorStatus.bootStatus != null) {
// Set boot status in template at startup
- connectorBootStatus = connectorStatus?.bootStatus
- } else if (connectorStatus?.status != null) {
+ connectorBootStatus = connectorStatus.bootStatus
+ } else if (connectorStatus.status != null) {
// Set previous status at startup
- connectorBootStatus = connectorStatus?.status
+ connectorBootStatus = connectorStatus.status
} else {
// Set default status
connectorBootStatus = ConnectorStatusEnum.Available
}
export const checkTemplate = (
- stationTemplate: ChargingStationTemplate,
+ stationTemplate: ChargingStationTemplate | undefined,
logPrefix: string,
templateFile: string
): void => {
} => {
const configuredMaxConnectors = getConfiguredMaxNumberOfConnectors(stationTemplate)
checkConfiguredMaxConnectors(configuredMaxConnectors, logPrefix, templateFile)
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const templateMaxConnectors = getMaxNumberOfConnectors(stationTemplate.Connectors!)
+ const templateMaxConnectors = getMaxNumberOfConnectors(stationTemplate.Connectors)
checkTemplateMaxConnectors(templateMaxConnectors, logPrefix, templateFile)
const templateMaxAvailableConnectors =
stationTemplate.Connectors?.[0] != null ? templateMaxConnectors - 1 : templateMaxConnectors
if (
configuredMaxConnectors > templateMaxAvailableConnectors &&
- stationTemplate?.randomConnectors !== true
+ stationTemplate.randomConnectors !== true
) {
logger.warn(
`${logPrefix} Number of connectors exceeds the number of connector configurations in template ${templateFile}, forcing random connector configurations affectation`
logPrefix: string,
templateFile: string
): void => {
- if (connectorStatus?.status != null) {
+ if (connectorStatus.status != null) {
logger.warn(
`${logPrefix} Charging station information from template ${templateFile} with connector id ${connectorId} status configuration defined, undefine it`
)
connectorStatus.idTagAuthorized = false
connectorStatus.transactionRemoteStarted = false
connectorStatus.transactionStarted = false
- delete connectorStatus?.transactionStart
- delete connectorStatus?.transactionId
- delete connectorStatus?.localAuthorizeIdTag
- delete connectorStatus?.authorizeIdTag
- delete connectorStatus?.transactionIdTag
+ delete connectorStatus.transactionStart
+ delete connectorStatus.transactionId
+ delete connectorStatus.localAuthorizeIdTag
+ delete connectorStatus.authorizeIdTag
+ delete connectorStatus.transactionIdTag
connectorStatus.transactionEnergyActiveImportRegisterValue = 0
- delete connectorStatus?.transactionBeginMeterValue
+ delete connectorStatus.transactionBeginMeterValue
}
export const createBootNotificationRequest = (
): void => {
params = { ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true }, ...params }
const serialNumberSuffix =
- params?.randomSerialNumber === true
+ params.randomSerialNumber === true
? getRandomSerialNumberSuffix({
upperCase: params.randomSerialNumberUpperCase
})
: ''
- isNotEmptyString(stationTemplate?.chargePointSerialNumberPrefix) &&
+ isNotEmptyString(stationTemplate.chargePointSerialNumberPrefix) &&
(stationInfo.chargePointSerialNumber = `${stationTemplate.chargePointSerialNumberPrefix}${serialNumberSuffix}`)
- isNotEmptyString(stationTemplate?.chargeBoxSerialNumberPrefix) &&
+ isNotEmptyString(stationTemplate.chargeBoxSerialNumberPrefix) &&
(stationInfo.chargeBoxSerialNumber = `${stationTemplate.chargeBoxSerialNumberPrefix}${serialNumberSuffix}`)
- isNotEmptyString(stationTemplate?.meterSerialNumberPrefix) &&
+ isNotEmptyString(stationTemplate.meterSerialNumberPrefix) &&
(stationInfo.meterSerialNumber = `${stationTemplate.meterSerialNumberPrefix}${serialNumberSuffix}`)
}
export const propagateSerialNumber = (
- stationTemplate: ChargingStationTemplate,
- stationInfoSrc: ChargingStationInfo,
+ stationTemplate: ChargingStationTemplate | undefined,
+ stationInfoSrc: ChargingStationInfo | undefined,
stationInfoDst: ChargingStationInfo
): void => {
if (stationInfoSrc == null || stationTemplate == null) {
'Missing charging station template or existing configuration to propagate serial number'
)
}
- stationTemplate?.chargePointSerialNumberPrefix != null &&
- stationInfoSrc?.chargePointSerialNumber != null
+ stationTemplate.chargePointSerialNumberPrefix != null &&
+ stationInfoSrc.chargePointSerialNumber != null
? (stationInfoDst.chargePointSerialNumber = stationInfoSrc.chargePointSerialNumber)
- : stationInfoDst?.chargePointSerialNumber != null &&
+ : stationInfoDst.chargePointSerialNumber != null &&
delete stationInfoDst.chargePointSerialNumber
- stationTemplate?.chargeBoxSerialNumberPrefix != null &&
- stationInfoSrc?.chargeBoxSerialNumber != null
+ stationTemplate.chargeBoxSerialNumberPrefix != null &&
+ stationInfoSrc.chargeBoxSerialNumber != null
? (stationInfoDst.chargeBoxSerialNumber = stationInfoSrc.chargeBoxSerialNumber)
- : stationInfoDst?.chargeBoxSerialNumber != null && delete stationInfoDst.chargeBoxSerialNumber
- stationTemplate?.meterSerialNumberPrefix != null && stationInfoSrc?.meterSerialNumber != null
+ : stationInfoDst.chargeBoxSerialNumber != null && delete stationInfoDst.chargeBoxSerialNumber
+ stationTemplate.meterSerialNumberPrefix != null && stationInfoSrc.meterSerialNumber != null
? (stationInfoDst.meterSerialNumber = stationInfoSrc.meterSerialNumber)
- : stationInfoDst?.meterSerialNumber != null && delete stationInfoDst.meterSerialNumber
+ : stationInfoDst.meterSerialNumber != null && delete stationInfoDst.meterSerialNumber
}
export const hasFeatureProfile = (
chargingStation.logPrefix()
)
if (result != null) {
- limit = result?.limit
- chargingProfile = result?.chargingProfile
+ limit = result.limit
+ chargingProfile = result.chargingProfile
switch (chargingStation.stationInfo?.currentOutType) {
case CurrentType.AC:
limit =
- chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT
+ chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
? limit
: ACElectricUtils.powerTotal(
chargingStation.getNumberOfPhases(),
break
case CurrentType.DC:
limit =
- chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT
+ chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
? limit
: // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit)
}
const connectorMaximumPower =
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- chargingStation.stationInfo.maximumPower! / chargingStation.powerDivider
+ chargingStation.stationInfo!.maximumPower! / chargingStation.powerDivider!
if (limit > connectorMaximumPower) {
logger.error(
- `${chargingStation.logPrefix()} ${moduleName}.getChargingStationConnectorChargingProfilesPowerLimit: Charging profile id ${chargingProfile?.chargingProfileId} limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}: %j`,
+ `${chargingStation.logPrefix()} ${moduleName}.getChargingStationConnectorChargingProfilesPowerLimit: Charging profile id ${
+ chargingProfile.chargingProfileId
+ } limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}: %j`,
result
)
limit = connectorMaximumPower
configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors as number
} else if (stationTemplate.Connectors != null && stationTemplate.Evses == null) {
configuredMaxNumberOfConnectors =
- stationTemplate.Connectors?.[0] != null
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ stationTemplate.Connectors[0] != null
? getMaxNumberOfConnectors(stationTemplate.Connectors) - 1
: getMaxNumberOfConnectors(stationTemplate.Connectors)
} else if (stationTemplate.Evses != null && stationTemplate.Connectors == null) {
templateFile: string,
logMsgToAppend = ''
): void => {
- if (template?.[key as keyof ChargingStationTemplate] !== undefined) {
+ if (template[key as keyof ChargingStationTemplate] !== undefined) {
const logMsg = `Deprecated template key '${key}' usage in file '${templateFile}'${
isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : ''
}`
deprecatedKey: string,
key?: string
): void => {
- if (template?.[deprecatedKey as keyof ChargingStationTemplate] !== undefined) {
+ if (template[deprecatedKey as keyof ChargingStationTemplate] !== undefined) {
if (key !== undefined) {
(template as unknown as Record<string, unknown>)[key] =
template[deprecatedKey as keyof ChargingStationTemplate]
const connectorStatus = chargingStation.getConnectorStatus(connectorId)!
for (const chargingProfile of chargingProfiles) {
const chargingSchedule = chargingProfile.chargingSchedule
- if (chargingSchedule?.startSchedule == null && connectorStatus?.transactionStarted === true) {
+ if (chargingSchedule.startSchedule == null && connectorStatus.transactionStarted === true) {
logger.debug(
`${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined. Trying to set it to the connector current transaction start date`
)
// OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction
- chargingSchedule.startSchedule = connectorStatus?.transactionStart
+ chargingSchedule.startSchedule = connectorStatus.transactionStart
}
- if (chargingSchedule?.startSchedule != null && !isDate(chargingSchedule?.startSchedule)) {
+ if (chargingSchedule.startSchedule != null && !isDate(chargingSchedule.startSchedule)) {
logger.warn(
`${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} startSchedule property is not a Date instance. Trying to convert it to a Date instance`
)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- chargingSchedule.startSchedule = convertToDate(chargingSchedule?.startSchedule)!
+ chargingSchedule.startSchedule = convertToDate(chargingSchedule.startSchedule)!
}
- if (chargingSchedule?.startSchedule != null && chargingSchedule?.duration == null) {
+ if (chargingSchedule.startSchedule != null && chargingSchedule.duration == null) {
logger.debug(
`${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no duration defined and will be set to the maximum time allowed`
)
)
delete chargingProfile.chargingSchedule.startSchedule
}
- if (connectorStatus?.transactionStarted === true) {
- chargingProfile.chargingSchedule.startSchedule = connectorStatus?.transactionStart
+ if (connectorStatus.transactionStarted === true) {
+ chargingProfile.chargingSchedule.startSchedule = connectorStatus.transactionStart
}
// FIXME: Handle relative charging profile duration
break
)
return false
}
- if (
- chargingProfile.chargingSchedule.startSchedule != null &&
- !isValidTime(chargingProfile.chargingSchedule.startSchedule)
- ) {
+ if (!isValidTime(chargingProfile.chargingSchedule.startSchedule)) {
logger.error(
`${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has an invalid startSchedule date defined`
)
return false
}
- if (
- chargingProfile.chargingSchedule.duration != null &&
- !Number.isSafeInteger(chargingProfile.chargingSchedule.duration)
- ) {
+ if (!Number.isSafeInteger(chargingProfile.chargingSchedule.duration)) {
logger.error(
`${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has non integer duration defined`
)
chargingStation: ChargingStation,
connectorId: number
): string {
- const hashId = chargingStation.stationInfo.hashId
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const idTagsFile = getIdTagsFile(chargingStation.stationInfo)!
+ const hashId = chargingStation.stationInfo!.hashId
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ const idTagsFile = getIdTagsFile(chargingStation.stationInfo!)!
switch (distribution) {
case IdTagDistribution.RANDOM:
return this.getRandomIdTag(hashId, idTagsFile)
private getConnectorAffinityIdTag (chargingStation: ChargingStation, connectorId: number): string {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const file = getIdTagsFile(chargingStation.stationInfo)!
+ const file = getIdTagsFile(chargingStation.stationInfo!)!
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const idTags = this.getIdTags(file)!
const addressableKey = this.getIdTagsCacheIndexesAddressableKey(
file,
- chargingStation.stationInfo.hashId
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.hashId
)
this.idTagsCachesAddressableIndexes.set(
addressableKey,
chargingStationConfiguration: ChargingStationConfiguration
): boolean {
return (
- chargingStationConfiguration?.configurationKey != null &&
- chargingStationConfiguration?.stationInfo != null &&
- chargingStationConfiguration?.automaticTransactionGenerator != null &&
- chargingStationConfiguration?.configurationHash != null &&
- isNotEmptyArray(chargingStationConfiguration?.configurationKey) &&
+ chargingStationConfiguration.configurationKey != null &&
+ chargingStationConfiguration.stationInfo != null &&
+ chargingStationConfiguration.automaticTransactionGenerator != null &&
+ chargingStationConfiguration.configurationHash != null &&
+ isNotEmptyArray(chargingStationConfiguration.configurationKey) &&
!isEmptyObject(chargingStationConfiguration.stationInfo) &&
!isEmptyObject(chargingStationConfiguration.automaticTransactionGenerator) &&
- isNotEmptyString(chargingStationConfiguration?.configurationHash)
+ isNotEmptyString(chargingStationConfiguration.configurationHash)
)
}
}
const [uuid, command, requestPayload] = validatedMessageEvent.data as BroadcastChannelRequest
if (
requestPayload.hashIds != null &&
- !requestPayload.hashIds.includes(this.chargingStation.stationInfo.hashId)
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ !requestPayload.hashIds.includes(this.chargingStation.stationInfo!.hashId)
) {
return
}
commandResponse = await this.commandHandler(command, requestPayload)
if (commandResponse == null || isEmptyObject(commandResponse)) {
responsePayload = {
- hashId: this.chargingStation.stationInfo.hashId,
+ hashId: this.chargingStation.stationInfo?.hashId,
status: ResponseStatus.SUCCESS
}
} else {
error
)
responsePayload = {
- hashId: this.chargingStation.stationInfo.hashId,
+ hashId: this.chargingStation.stationInfo?.hashId,
status: ResponseStatus.FAILURE,
command,
requestPayload,
const responseStatus = this.commandResponseToResponseStatus(command, commandResponse)
if (responseStatus === ResponseStatus.SUCCESS) {
return {
- hashId: this.chargingStation.stationInfo.hashId,
+ hashId: this.chargingStation.stationInfo?.hashId,
status: responseStatus
}
}
return {
- hashId: this.chargingStation.stationInfo.hashId,
+ hashId: this.chargingStation.stationInfo?.hashId,
status: responseStatus,
command,
requestPayload,
| StartTransactionResponse
| StopTransactionResponse
| AuthorizeResponse
- )?.idTagInfo?.status === AuthorizationStatus.ACCEPTED
+ ).idTagInfo?.status === AuthorizationStatus.ACCEPTED
) {
return ResponseStatus.SUCCESS
}
return ResponseStatus.FAILURE
case BroadcastChannelProcedureName.BOOT_NOTIFICATION:
- if (commandResponse?.status === RegistrationStatusEnumType.ACCEPTED) {
+ if (commandResponse.status === RegistrationStatusEnumType.ACCEPTED) {
return ResponseStatus.SUCCESS
}
return ResponseStatus.FAILURE
case BroadcastChannelProcedureName.DATA_TRANSFER:
- if (commandResponse?.status === DataTransferStatus.ACCEPTED) {
+ if (commandResponse.status === DataTransferStatus.ACCEPTED) {
return ResponseStatus.SUCCESS
}
return ResponseStatus.FAILURE
responsesFailed: this.responses
.get(uuid)
?.responses.map((response) => {
- if (response != null && response.status === ResponseStatus.FAILURE) {
+ if (response.status === ResponseStatus.FAILURE) {
return response
}
return undefined
>
public constructor () {
- // if (new.target?.name === moduleName) {
- // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`)
+ // if (new.target.name === moduleName) {
+ // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
// }
super(OCPPVersion.VERSION_16)
this.incomingRequestHandlers = new Map<OCPP16IncomingRequestCommand, IncomingRequestHandler>([
logger.info(
`${chargingStation.logPrefix()} ${type} reset command received, simulating it. The station will be back online in ${formatDurationMilliSeconds(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- chargingStation.stationInfo.resetTime!
+ chargingStation.stationInfo!.resetTime!
)}`
)
return OCPP16Constants.OCPP_RESPONSE_ACCEPTED
csChargingProfiles.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE &&
connectorId > 0 &&
connectorStatus?.transactionStarted === true &&
- csChargingProfiles.transactionId !== connectorStatus?.transactionId
+ csChargingProfiles.transactionId !== connectorStatus.transactionId
) {
logger.error(
`${chargingStation.logPrefix()} Trying to set transaction charging profile(s) on connector ${connectorId} with a different transaction id ${
csChargingProfiles.transactionId
- } than the started transaction id ${connectorStatus?.transactionId}`
+ } than the started transaction id ${connectorStatus.transactionId}`
)
return OCPP16Constants.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const connectorStatus = chargingStation.getConnectorStatus(connectorId)!
if (
- isEmptyArray(connectorStatus?.chargingProfiles) &&
+ isEmptyArray(connectorStatus.chargingProfiles) &&
isEmptyArray(chargingStation.getConnectorStatus(0)?.chargingProfiles)
) {
return OCPP16Constants.OCPP_RESPONSE_REJECTED
let compositeSchedule: OCPP16ChargingSchedule | undefined
for (const chargingProfile of chargingProfiles) {
if (
- chargingProfile.chargingSchedule?.startSchedule == null &&
- connectorStatus?.transactionStarted === true
+ chargingProfile.chargingSchedule.startSchedule == null &&
+ connectorStatus.transactionStarted === true
) {
logger.debug(
`${chargingStation.logPrefix()} ${moduleName}.handleRequestGetCompositeSchedule: Charging profile id ${
} has no startSchedule defined. Trying to set it to the connector current transaction start date`
)
// OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction
- chargingProfile.chargingSchedule.startSchedule = connectorStatus?.transactionStart
+ chargingProfile.chargingSchedule.startSchedule = connectorStatus.transactionStart
}
if (
- chargingProfile.chargingSchedule?.startSchedule != null &&
- !isDate(chargingProfile.chargingSchedule?.startSchedule)
+ chargingProfile.chargingSchedule.startSchedule != null &&
+ !isDate(chargingProfile.chargingSchedule.startSchedule)
) {
logger.warn(
`${chargingStation.logPrefix()} ${moduleName}.handleRequestGetCompositeSchedule: Charging profile id ${
)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
chargingProfile.chargingSchedule.startSchedule = convertToDate(
- chargingProfile.chargingSchedule?.startSchedule
+ chargingProfile.chargingSchedule.startSchedule
)!
}
if (
- chargingProfile.chargingSchedule?.startSchedule != null &&
- chargingProfile.chargingSchedule?.duration == null
+ chargingProfile.chargingSchedule.startSchedule != null &&
+ chargingProfile.chargingSchedule.duration == null
) {
logger.debug(
`${chargingStation.logPrefix()} ${moduleName}.handleRequestGetCompositeSchedule: Charging profile id ${
)
}
const remoteStartTransactionLogMsg = `
- ${chargingStation.logPrefix()} Transaction remotely STARTED on ${
- chargingStation.stationInfo.chargingStationId
- }#${transactionConnectorId} for idTag '${idTag}'`
+ ${chargingStation.logPrefix()} Transaction remotely STARTED on ${chargingStation.stationInfo
+ ?.chargingStationId}#${transactionConnectorId} for idTag '${idTag}'`
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
transactionConnectorId,
connectorId: number,
chargingProfile: OCPP16ChargingProfile
): boolean {
- if (chargingProfile?.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE) {
+ if (chargingProfile.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE) {
OCPP16ServiceUtils.setChargingProfile(chargingStation, connectorId, chargingProfile)
logger.debug(
`${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}: %j`,
return OCPP16Constants.OCPP_RESPONSE_EMPTY
}
let { retrieveDate } = commandPayload
- if (
- chargingStation.stationInfo.firmwareStatus != null &&
- chargingStation.stationInfo.firmwareStatus !== OCPP16FirmwareStatus.Installed
- ) {
+ if (chargingStation.stationInfo?.firmwareStatus !== OCPP16FirmwareStatus.Installed) {
logger.warn(
`${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: firmware update is already in progress`
)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
retrieveDate = convertToDate(retrieveDate)!
const now = Date.now()
- if (retrieveDate?.getTime() <= now) {
+ if (retrieveDate.getTime() <= now) {
this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION)
} else {
- setTimeout(
- () => {
- this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION)
- },
- retrieveDate?.getTime() - now
- )
+ setTimeout(() => {
+ this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION)
+ }, retrieveDate.getTime() - now)
}
return OCPP16Constants.OCPP_RESPONSE_EMPTY
}
for (const [evseId, evseStatus] of chargingStation.evses) {
if (evseId > 0) {
for (const [connectorId, connectorStatus] of evseStatus.connectors) {
- if (connectorStatus?.transactionStarted === false) {
+ if (connectorStatus.transactionStarted === false) {
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
connectorId,
>(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
status: OCPP16FirmwareStatus.Downloading
})
- chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloading
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Downloading
if (
chargingStation.stationInfo?.firmwareUpgrade?.failureStatus ===
OCPP16FirmwareStatus.DownloadFailed
OCPP16FirmwareStatusNotificationRequest,
OCPP16FirmwareStatusNotificationResponse
>(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
- status: chargingStation.stationInfo?.firmwareUpgrade?.failureStatus
+ status: chargingStation.stationInfo.firmwareUpgrade.failureStatus
})
chargingStation.stationInfo.firmwareStatus =
- chargingStation.stationInfo?.firmwareUpgrade?.failureStatus
+ chargingStation.stationInfo.firmwareUpgrade.failureStatus
return
}
await sleep(secondsToMilliseconds(getRandomInteger(maxDelay, minDelay)))
>(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
status: OCPP16FirmwareStatus.Downloaded
})
- chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloaded
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Downloaded
let wasTransactionsStarted = false
let transactionsStarted: boolean
do {
for (const [evseId, evseStatus] of chargingStation.evses) {
if (evseId > 0) {
for (const [connectorId, connectorStatus] of evseStatus.connectors) {
- if (connectorStatus?.status !== OCPP16ChargePointStatus.Unavailable) {
+ if (connectorStatus.status !== OCPP16ChargePointStatus.Unavailable) {
await OCPP16ServiceUtils.sendAndSetConnectorStatus(
chargingStation,
connectorId,
>(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
status: OCPP16FirmwareStatus.Installing
})
- chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Installing
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Installing
if (
chargingStation.stationInfo?.firmwareUpgrade?.failureStatus ===
OCPP16FirmwareStatus.InstallationFailed
OCPP16FirmwareStatusNotificationRequest,
OCPP16FirmwareStatusNotificationResponse
>(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
- status: chargingStation.stationInfo?.firmwareUpgrade?.failureStatus
+ status: chargingStation.stationInfo.firmwareUpgrade.failureStatus
})
chargingStation.stationInfo.firmwareStatus =
- chargingStation.stationInfo?.firmwareUpgrade?.failureStatus
+ chargingStation.stationInfo.firmwareUpgrade.failureStatus
return
}
if (chargingStation.stationInfo?.firmwareUpgrade?.reset === true) {
const logFiles = readdirSync(resolve(dirname(fileURLToPath(import.meta.url)), '../'))
.filter((file) => file.endsWith('.log'))
.map((file) => join('./', file))
- const diagnosticsArchive = `${chargingStation.stationInfo.chargingStationId}_logs.tar.gz`
+ const diagnosticsArchive = `${chargingStation.stationInfo?.chargingStationId}_logs.tar.gz`
create({ gzip: true }, logFiles).pipe(createWriteStream(diagnosticsArchive))
ftpClient = new Client()
const accessResponse = await ftpClient.access({
>(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
status: OCPP16DiagnosticsStatus.Uploaded
})
- if (ftpClient != null) {
- ftpClient.close()
- }
+ ftpClient.close()
return { fileName: diagnosticsArchive }
}
throw new OCPPError(
ErrorType.GENERIC_ERROR,
- `Diagnostics transfer failed with error code ${accessResponse.code}${
- uploadResponse?.code != null && `|${uploadResponse?.code}`
- }`,
+ `Diagnostics transfer failed with error code ${accessResponse.code}|${uploadResponse.code}`,
OCPP16IncomingRequestCommand.GET_DIAGNOSTICS
)
}
throw new OCPPError(
ErrorType.GENERIC_ERROR,
- `Diagnostics transfer failed with error code ${accessResponse.code}${
- uploadResponse?.code != null && `|${uploadResponse?.code}`
- }`,
+ `Diagnostics transfer failed with error code ${accessResponse.code}|${uploadResponse?.code}`,
OCPP16IncomingRequestCommand.GET_DIAGNOSTICS
)
} catch (error) {
>(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
status: OCPP16DiagnosticsStatus.UploadFailed
})
- if (ftpClient != null) {
- ftpClient.close()
- }
+ ftpClient?.close()
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return this.handleIncomingRequestError<GetDiagnosticsResponse>(
chargingStation,
protected jsonSchemas: Map<OCPP16RequestCommand, JSONSchemaType<JsonType>>
public constructor (ocppResponseService: OCPPResponseService) {
- // if (new.target?.name === moduleName) {
- // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`)
+ // if (new.target.name === moduleName) {
+ // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
// }
super(OCPPVersion.VERSION_16, ocppResponseService)
this.jsonSchemas = new Map<OCPP16RequestCommand, JSONSchemaType<JsonType>>([
return {
idTag: Constants.DEFAULT_IDTAG,
meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId(
- commandParams?.connectorId as number,
+ commandParams.connectorId as number,
true
),
timestamp: new Date(),
...(OCPP16ServiceUtils.hasReservation(
chargingStation,
- commandParams?.connectorId as number,
- commandParams?.idTag as string
+ commandParams.connectorId as number,
+ commandParams.idTag as string
) && {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
reservationId: chargingStation.getReservationBy(
'connectorId',
chargingStation.getConnectorStatus(0)?.status === OCPP16ChargePointStatus.Reserved
? 0
- : (commandParams?.connectorId as number)
+ : (commandParams.connectorId as number)
)!.reservationId
}),
...commandParams
chargingStation.stationInfo?.transactionDataMeterValues === true &&
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(connectorId = chargingStation.getConnectorIdByTransactionId(
- commandParams?.transactionId as number
+ commandParams.transactionId as number
)!)
energyActiveImportRegister = chargingStation.getEnergyActiveImportRegisterByTransactionId(
- commandParams?.transactionId as number,
+ commandParams.transactionId as number,
true
)
return {
- idTag: chargingStation.getTransactionIdTag(commandParams?.transactionId as number),
+ idTag: chargingStation.getTransactionIdTag(commandParams.transactionId as number),
meterStop: energyActiveImportRegister,
timestamp: new Date(),
...(chargingStation.stationInfo?.transactionDataMeterValues === true && {
private readonly jsonSchemas: Map<OCPP16RequestCommand, JSONSchemaType<JsonType>>
public constructor () {
- // if (new.target?.name === moduleName) {
- // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`)
+ // if (new.target.name === moduleName) {
+ // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
// }
super(OCPPVersion.VERSION_16)
this.responseHandlers = new Map<OCPP16RequestCommand, ResponseHandler>([
for (const [evseId, evseStatus] of chargingStation.evses) {
if (evseId > 0) {
for (const [connectorId, connectorStatus] of evseStatus.connectors) {
- if (connectorStatus?.authorizeIdTag === requestPayload.idTag) {
+ if (connectorStatus.authorizeIdTag === requestPayload.idTag) {
authorizeConnectorId = connectorId
break
}
chargingStation.getAuthorizeRemoteTxRequests() &&
chargingStation.getLocalAuthListEnabled() &&
chargingStation.hasIdTags() &&
- connectorStatus?.idTagLocalAuthorized === false
+ connectorStatus.idTagLocalAuthorized === false
) {
logger.error(
- `${chargingStation.logPrefix()} Trying to start a transaction with a not local authorized idTag ${connectorStatus?.localAuthorizeIdTag} on connector id ${connectorId}`
+ `${chargingStation.logPrefix()} Trying to start a transaction with a not local authorized idTag ${
+ connectorStatus.localAuthorizeIdTag
+ } on connector id ${connectorId}`
)
await this.resetConnectorOnStartTransactionError(chargingStation, connectorId)
return
connectorStatus?.transactionRemoteStarted === true &&
chargingStation.getAuthorizeRemoteTxRequests() &&
chargingStation.stationInfo?.remoteAuthorization === true &&
- connectorStatus?.idTagLocalAuthorized === false &&
- connectorStatus?.idTagAuthorized === false
+ connectorStatus.idTagLocalAuthorized === false &&
+ connectorStatus.idTagAuthorized === false
) {
logger.error(
- `${chargingStation.logPrefix()} Trying to start a transaction with a not authorized idTag ${connectorStatus?.authorizeIdTag} on connector id ${connectorId}`
+ `${chargingStation.logPrefix()} Trying to start a transaction with a not authorized idTag ${
+ connectorStatus.authorizeIdTag
+ } on connector id ${connectorId}`
)
await this.resetConnectorOnStartTransactionError(chargingStation, connectorId)
return
}
if (
connectorStatus?.idTagAuthorized === true &&
- connectorStatus?.authorizeIdTag !== requestPayload.idTag
+ connectorStatus.authorizeIdTag !== requestPayload.idTag
) {
logger.error(
`${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${
requestPayload.idTag
- } different from the authorize request one ${connectorStatus?.authorizeIdTag} on connector id ${connectorId}`
+ } different from the authorize request one ${
+ connectorStatus.authorizeIdTag
+ } on connector id ${connectorId}`
)
await this.resetConnectorOnStartTransactionError(chargingStation, connectorId)
return
}
if (
connectorStatus?.idTagLocalAuthorized === true &&
- connectorStatus?.localAuthorizeIdTag !== requestPayload.idTag
+ connectorStatus.localAuthorizeIdTag !== requestPayload.idTag
) {
logger.error(
`${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${
requestPayload.idTag
- } different from the local authorized one ${connectorStatus?.localAuthorizeIdTag} on connector id ${connectorId}`
+ } different from the local authorized one ${
+ connectorStatus.localAuthorizeIdTag
+ } on connector id ${connectorId}`
)
await this.resetConnectorOnStartTransactionError(chargingStation, connectorId)
return
}
if (connectorStatus?.transactionStarted === true) {
logger.error(
- `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${connectorId} by idTag ${connectorStatus?.transactionIdTag}`
+ `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${connectorId} by idTag ${
+ connectorStatus.transactionIdTag
+ }`
)
return
}
for (const [evseId, evseStatus] of chargingStation.evses) {
if (evseStatus.connectors.size > 1) {
for (const [id, status] of evseStatus.connectors) {
- if (id !== connectorId && status?.transactionStarted === true) {
+ if (id !== connectorId && status.transactionStarted === true) {
logger.error(
- `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId} by connector id ${id} with idTag ${status?.transactionIdTag}`
+ `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId} by connector id ${id} with idTag ${
+ status.transactionIdTag
+ }`
)
await this.resetConnectorOnStartTransactionError(chargingStation, connectorId)
return
payload.transactionId = convertToInt(payload.transactionId)
}
- if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
+ if (payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) {
connectorStatus.transactionStarted = true
connectorStatus.transactionStart = requestPayload.timestamp
connectorStatus.transactionId = payload.transactionId
OCPP16ChargePointStatus.Charging
)
logger.info(
- `${chargingStation.logPrefix()} Transaction with id ${payload.transactionId} STARTED on ${
- chargingStation.stationInfo.chargingStationId
- }#${connectorId} for idTag '${requestPayload.idTag}'`
+ `${chargingStation.logPrefix()} Transaction with id ${
+ payload.transactionId
+ } STARTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${
+ requestPayload.idTag
+ }'`
)
- if (chargingStation.stationInfo.powerSharedByConnectors === true) {
- ++chargingStation.powerDivider
+ if (chargingStation.stationInfo?.powerSharedByConnectors === true) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ ++chargingStation.powerDivider!
}
const configuredMeterValueSampleInterval = getConfigurationKey(
chargingStation,
logger.warn(
`${chargingStation.logPrefix()} Starting transaction with id ${
payload.transactionId
- } REJECTED on ${
- chargingStation.stationInfo.chargingStationId
- }#${connectorId} with status '${payload.idTagInfo?.status}', idTag '${
+ } REJECTED on ${chargingStation.stationInfo
+ ?.chargingStationId}#${connectorId} with status '${payload.idTagInfo.status}', idTag '${
requestPayload.idTag
}'${
OCPP16ServiceUtils.hasReservation(chargingStation, connectorId, requestPayload.idTag)
return
}
chargingStation.stationInfo?.beginEndMeterValues === true &&
- chargingStation.stationInfo?.ocppStrictCompliance === false &&
- chargingStation.stationInfo?.outOfOrderEndMeterValues === true &&
+ chargingStation.stationInfo.ocppStrictCompliance === false &&
+ chargingStation.stationInfo.outOfOrderEndMeterValues === true &&
(await chargingStation.ocppRequestService.requestHandler<
OCPP16MeterValuesRequest,
OCPP16MeterValuesResponse
OCPP16ChargePointStatus.Available
)
}
- if (chargingStation.stationInfo.powerSharedByConnectors === true) {
- chargingStation.powerDivider--
+ if (chargingStation.stationInfo?.powerSharedByConnectors === true) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.powerDivider!--
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
resetConnectorStatus(chargingStation.getConnectorStatus(transactionConnectorId)!)
chargingStation.stopMeterValues(transactionConnectorId)
const logMsg = `${chargingStation.logPrefix()} Transaction with id ${
requestPayload.transactionId
- } STOPPED on ${
- chargingStation.stationInfo.chargingStationId
- }#${transactionConnectorId} with status '${payload.idTagInfo?.status}'`
+ } STOPPED on ${chargingStation.stationInfo
+ ?.chargingStationId}#${transactionConnectorId} with status '${payload.idTagInfo?.status}'`
if (
payload.idTagInfo == null ||
- payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED
+ payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED
) {
logger.info(logMsg)
} else {
public static buildTransactionBeginMeterValue (
chargingStation: ChargingStation,
connectorId: number,
- meterStart: number
+ meterStart: number | undefined
): OCPP16MeterValue {
const meterValue: OCPP16MeterValue = {
timestamp: new Date(),
OCPP16Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const connectorStatus = chargingStation.getConnectorStatus(connectorId)!
- if (connectorStatus?.transactionStarted === true) {
+ if (connectorStatus.transactionStarted === true) {
response = OCPP16Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED
}
connectorStatus.availability = availabilityType
}
let cpReplaced = false
if (isNotEmptyArray(chargingStation.getConnectorStatus(connectorId)?.chargingProfiles)) {
- chargingStation
+ for (const [index, chargingProfile] of chargingStation
.getConnectorStatus(connectorId)
- ?.chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => {
- if (
- chargingProfile.chargingProfileId === cp.chargingProfileId ||
- (chargingProfile.stackLevel === cp.stackLevel &&
- chargingProfile.chargingProfilePurpose === cp.chargingProfilePurpose)
- ) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- chargingStation.getConnectorStatus(connectorId)!.chargingProfiles![index] = cp
- cpReplaced = true
- }
- })
+ ?.chargingProfiles?.entries() ?? []) {
+ if (
+ chargingProfile.chargingProfileId === cp.chargingProfileId ||
+ (chargingProfile.stackLevel === cp.stackLevel &&
+ chargingProfile.chargingProfilePurpose === cp.chargingProfilePurpose)
+ ) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.getConnectorStatus(connectorId)!.chargingProfiles![index] = cp
+ cpReplaced = true
+ }
+ }
}
!cpReplaced && chargingStation.getConnectorStatus(connectorId)?.chargingProfiles?.push(cp)
}
OCPP16ChargePointStatus.Reserved &&
connectorReservation != null &&
!hasReservationExpired(connectorReservation) &&
- connectorReservation?.idTag === idTag) ||
+ connectorReservation.idTag === idTag) ||
(chargingStation.getConnectorStatus(0)?.status === OCPP16ChargePointStatus.Reserved &&
chargingStationReservation != null &&
!hasReservationExpired(chargingStationReservation) &&
- chargingStationReservation?.idTag === idTag)
+ chargingStationReservation.idTag === idTag)
) {
logger.debug(
`${chargingStation.logPrefix()} Connector id ${connectorId} has a valid reservation for idTag ${idTag}: %j`,
>
public constructor () {
- // if (new.target?.name === moduleName) {
- // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`)
+ // if (new.target.name === moduleName) {
+ // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
// }
super(OCPPVersion.VERSION_20)
this.incomingRequestHandlers = new Map<OCPP20IncomingRequestCommand, IncomingRequestHandler>([
protected jsonSchemas: Map<OCPP20RequestCommand, JSONSchemaType<JsonType>>
public constructor (ocppResponseService: OCPPResponseService) {
- // if (new.target?.name === moduleName) {
- // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`)
+ // if (new.target.name === moduleName) {
+ // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
// }
super(OCPPVersion.VERSION_20, ocppResponseService)
this.jsonSchemas = new Map<OCPP20RequestCommand, JSONSchemaType<JsonType>>([
private readonly jsonSchemas: Map<OCPP20RequestCommand, JSONSchemaType<JsonType>>
public constructor () {
- // if (new.target?.name === moduleName) {
- // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`)
+ // if (new.target.name === moduleName) {
+ // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
// }
super(OCPPVersion.VERSION_20)
this.responseHandlers = new Map<OCPP20RequestCommand, ResponseHandler>([
`${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
error
)
- if (params?.throwError === false && params?.errorResponse != null) {
- return params?.errorResponse
+ if (params.throwError === false && params.errorResponse != null) {
+ return params.errorResponse
}
- if (params?.throwError === true && params?.errorResponse == null) {
+ if (params.throwError === true && params.errorResponse == null) {
throw error
}
- if (params?.throwError === true && params?.errorResponse != null) {
- return params?.errorResponse
+ if (params.throwError === true && params.errorResponse != null) {
+ return params.errorResponse
}
}
protected handleRequestClearCache (chargingStation: ChargingStation): ClearCacheResponse {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- if (chargingStation.idTagsCache.deleteIdTags(getIdTagsFile(chargingStation.stationInfo)!)) {
+ if (chargingStation.idTagsCache.deleteIdTags(getIdTagsFile(chargingStation.stationInfo!)!)) {
return OCPPConstants.OCPP_RESPONSE_ACCEPTED
}
return OCPPConstants.OCPP_RESPONSE_REJECTED
// Resolve response
resolve(messagePayload)
}
- } else if (error != null) {
+ } else {
handleSendError(
new OCPPError(
ErrorType.GENERIC_ERROR,
}
throw new OCPPError(
ErrorType.SECURITY_ERROR,
- `Cannot send command ${commandName} PDU when the charging station is in ${chargingStation?.bootNotificationResponse?.status} state on the central server`,
+ `Cannot send command ${commandName} PDU when the charging station is in ${chargingStation.bootNotificationResponse?.status} state on the central server`,
commandName
)
}
isNotEmptyString(
chargingStation.idTagsCache
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- .getIdTags(getIdTagsFile(chargingStation.stationInfo)!)
+ .getIdTags(getIdTagsFile(chargingStation.stationInfo!)!)
?.find((tag) => tag === idTag)
)
)
idTag
}
)
- )?.idTagInfo?.status === AuthorizationStatus.ACCEPTED
+ ).idTagInfo.status === AuthorizationStatus.ACCEPTED
)
}
}
if (!transitionAllowed) {
logger.warn(
- `${chargingStation.logPrefix()} OCPP ${chargingStation.stationInfo
- ?.ocppVersion} connector id ${connectorId} status transition from '${
+ `${chargingStation.logPrefix()} OCPP ${
+ chargingStation.stationInfo.ocppVersion
+ } connector id ${connectorId} status transition from '${
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
chargingStation.getConnectorStatus(connectorId)!.status
}' to '${status}' is not allowed`
if (
chargingStation.getNumberOfPhases() !== 3 ||
(chargingStation.getNumberOfPhases() === 3 &&
- chargingStation.stationInfo?.mainVoltageMeterValues === true)
+ chargingStation.stationInfo.mainVoltageMeterValues === true)
) {
meterValue.sampledValue.push(
buildSampledValue(voltageSampledValueTemplate, voltageMeasurandValue)
phaseLineToNeutralValue as MeterValuePhase
)
)
- if (chargingStation.stationInfo?.phaseLineToLineVoltageMeterValues === true) {
+ if (chargingStation.stationInfo.phaseLineToLineVoltageMeterValues === true) {
const phaseLineToLineValue = `L${phase}-L${
(phase + 1) % chargingStation.getNumberOfPhases() !== 0
? (phase + 1) % chargingStation.getNumberOfPhases()
}
if (powerSampledValueTemplate != null) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- checkMeasurandPowerDivider(chargingStation, powerSampledValueTemplate.measurand!)
+ checkMeasurandPowerDivider(chargingStation, powerSampledValueTemplate.measurand)
const errMsg = `MeterValues measurand ${
powerSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: Unknown ${chargingStation.stationInfo?.currentOutType} currentOutType in template file ${
+ }: Unknown ${chargingStation.stationInfo.currentOutType} currentOutType in template file ${
chargingStation.templateFile
}, cannot calculate ${
powerSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
} measurand value`
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const powerMeasurandValues: MeasurandValues = {} as MeasurandValues
- const unitDivider = powerSampledValueTemplate?.unit === MeterValueUnit.KILO_WATT ? 1000 : 1
+ const unitDivider = powerSampledValueTemplate.unit === MeterValueUnit.KILO_WATT ? 1000 : 1
const connectorMaximumAvailablePower =
chargingStation.getConnectorMaximumAvailablePower(connectorId)
const connectorMaximumPower = Math.round(connectorMaximumAvailablePower)
const connectorMinimumPowerPerPhase = Math.round(
connectorMinimumPower / chargingStation.getNumberOfPhases()
)
- switch (chargingStation.stationInfo?.currentOutType) {
+ switch (chargingStation.stationInfo.currentOutType) {
case CurrentType.AC:
if (chargingStation.getNumberOfPhases() === 3) {
const defaultFluctuatedPowerPerPhase = isNotEmptyString(
connectorMinimumPower / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPower / unitDivider
}
) / chargingStation.getNumberOfPhases(),
connectorMinimumPowerPerPhase / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPowerPerPhase / unitDivider
}
),
connectorMinimumPowerPerPhase / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPowerPerPhase / unitDivider
}
),
connectorMinimumPowerPerPhase / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPowerPerPhase / unitDivider
}
),
connectorMinimumPower / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPower / unitDivider
}
),
connectorMinimumPower / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPower / unitDivider
}
),
}
if (currentSampledValueTemplate != null) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- checkMeasurandPowerDivider(chargingStation, currentSampledValueTemplate.measurand!)
+ checkMeasurandPowerDivider(chargingStation, currentSampledValueTemplate.measurand)
const errMsg = `MeterValues measurand ${
currentSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: Unknown ${chargingStation.stationInfo?.currentOutType} currentOutType in template file ${
+ }: Unknown ${chargingStation.stationInfo.currentOutType} currentOutType in template file ${
chargingStation.templateFile
}, cannot calculate ${
currentSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
chargingStation.getConnectorMaximumAvailablePower(connectorId)
const connectorMinimumAmperage = currentSampledValueTemplate.minimumValue ?? 0
let connectorMaximumAmperage: number
- switch (chargingStation.stationInfo?.currentOutType) {
+ switch (chargingStation.stationInfo.currentOutType) {
case CurrentType.AC:
connectorMaximumAmperage = ACElectricUtils.amperagePerPhaseFromPower(
chargingStation.getNumberOfPhases(),
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
energySampledValueTemplate = getSampledValueTemplate(chargingStation, connectorId)
if (energySampledValueTemplate != null) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- checkMeasurandPowerDivider(chargingStation, energySampledValueTemplate.measurand!)
+ checkMeasurandPowerDivider(chargingStation, energySampledValueTemplate.measurand)
const unitDivider =
- energySampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1
+ energySampledValueTemplate.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1
const connectorMaximumAvailablePower =
chargingStation.getConnectorMaximumAvailablePower(connectorId)
const connectorMaximumEnergyRounded = roundTo(
connectorMaximumEnergyRounded,
connectorMinimumEnergyRounded,
{
- limitationEnabled: chargingStation.stationInfo?.customValueLimitationMeterValues,
+ limitationEnabled: chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumEnergyRounded,
unitMultiplier: unitDivider
}
export const buildTransactionEndMeterValue = (
chargingStation: ChargingStation,
connectorId: number,
- meterStop: number
+ meterStop: number | undefined
): MeterValue => {
let meterValue: MeterValue
let sampledValueTemplate: SampledValueTemplate | undefined
const checkMeasurandPowerDivider = (
chargingStation: ChargingStation,
- measurandType: MeterValueMeasurand
+ measurandType: MeterValueMeasurand | undefined
): void => {
if (chargingStation.powerDivider == null) {
const errMsg = `MeterValues measurand ${
}: powerDivider is undefined`
logger.error(`${chargingStation.logPrefix()} ${errMsg}`)
throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, RequestCommand.METER_VALUES)
- } else if (chargingStation?.powerDivider <= 0) {
+ } else if (chargingStation.powerDivider <= 0) {
const errMsg = `MeterValues measurand ${
measurandType ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
}: powerDivider have zero or below value ${chargingStation.powerDivider}`
...options
}
const parsedValue = parseInt(value ?? '')
- if (options?.limitationEnabled === true) {
+ if (options.limitationEnabled === true) {
return max(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
min((!isNaN(parsedValue) ? parsedValue : Infinity) * options.unitMultiplier!, maxLimit),
context?: MeterValueContext,
phase?: MeterValuePhase
): SampledValue => {
- const sampledValueContext = context ?? sampledValueTemplate?.context
+ const sampledValueContext = context ?? sampledValueTemplate.context
const sampledValueLocation =
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- sampledValueTemplate?.location ?? getMeasurandDefaultLocation(sampledValueTemplate.measurand!)
- const sampledValuePhase = phase ?? sampledValueTemplate?.phase
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
+ sampledValueTemplate.location ?? getMeasurandDefaultLocation(sampledValueTemplate.measurand!)
+ const sampledValuePhase = phase ?? sampledValueTemplate.phase
return {
...(sampledValueTemplate.unit != null && {
unit: sampledValueTemplate.unit
measurand: sampledValueTemplate.measurand
}),
...(sampledValueLocation != null && { location: sampledValueLocation }),
- ...(value != null && { value: value.toString() }),
+ ...{ value: value.toString() },
...(sampledValuePhase != null && { phase: sampledValuePhase })
- } as SampledValue
+ } satisfies SampledValue
}
const getMeasurandDefaultLocation = (
isRequestCommand &&
chargingStation.stationInfo?.commandsSupport?.outgoingCommands?.[command] != null
) {
- return chargingStation.stationInfo?.commandsSupport?.outgoingCommands[command]
+ return chargingStation.stationInfo.commandsSupport.outgoingCommands[command]
}
logger.error(`${chargingStation.logPrefix()} Unknown outgoing OCPP command '${command}'`)
return false
return true
} else if (
isIncomingRequestCommand &&
- chargingStation.stationInfo?.commandsSupport?.incomingCommands?.[command] != null
+ chargingStation.stationInfo?.commandsSupport?.incomingCommands[command] != null
) {
- return chargingStation.stationInfo?.commandsSupport?.incomingCommands[command]
+ return chargingStation.stationInfo.commandsSupport.incomingCommands[command]
}
logger.error(`${chargingStation.logPrefix()} Unknown incoming OCPP command '${command}'`)
return false
isMessageTrigger &&
chargingStation.stationInfo?.messageTriggerSupport?.[messageTrigger] != null
) {
- return chargingStation.stationInfo?.messageTriggerSupport[messageTrigger]
+ return chargingStation.stationInfo.messageTriggerSupport[messageTrigger]
}
logger.error(
`${chargingStation.logPrefix()} Unknown incoming OCPP message trigger '${messageTrigger}'`
if (isDate(obj![key])) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
(obj![key] as string) = (obj![key] as Date).toISOString()
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
- } else if (obj![key] !== null && typeof obj![key] === 'object') {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-condition
+ } else if (typeof obj![key] === 'object' && obj![key] !== null) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
OCPPServiceUtils.convertDateToISOString<T>(obj![key] as T)
}
private isBasicAuthEnabled (): boolean {
return (
this.uiServerConfiguration.authentication?.enabled === true &&
- this.uiServerConfiguration.authentication?.type === AuthenticationType.BASIC_AUTH
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ this.uiServerConfiguration.authentication.type === AuthenticationType.BASIC_AUTH
)
}
const body = JSON.parse(Buffer.concat(bodyBuffer).toString()) as RequestPayload
this.uiServices
.get(version)
- ?.requestHandler(
- this.buildProtocolRequest(
- uuid,
- procedureName,
- body ?? Constants.EMPTY_FROZEN_OBJECT
- )
- )
+ ?.requestHandler(this.buildProtocolRequest(uuid, procedureName, body))
.then((protocolResponse?: ProtocolResponse) => {
if (protocolResponse != null) {
this.sendResponse(protocolResponse)
})
})
this.httpServer.on('connect', (req: IncomingMessage, socket: Duplex, _head: Buffer) => {
- if (req.headers?.connection !== 'Upgrade' || req.headers?.upgrade !== 'websocket') {
+ if (req.headers.connection !== 'Upgrade' || req.headers.upgrade !== 'websocket') {
socket.write(`HTTP/1.1 ${StatusCodes.BAD_REQUEST} Bad Request\r\n\r\n`)
socket.destroy()
}
}
public sendResponse (response: ProtocolResponse): void {
- const responseId = response?.[0]
+ const responseId = response[0]
try {
if (this.hasResponseHandler(responseId)) {
const ws = this.responseHandlers.get(responseId) as WebSocket
- if (ws?.readyState === WebSocket.OPEN) {
+ if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(response))
} else {
logger.error(
`${this.logPrefix(
moduleName,
'sendResponse'
- )} Error at sending response id '${responseId}', WebSocket is not open: ${ws?.readyState}`
+ )} Error at sending response id '${responseId}', WebSocket is not open: ${
+ ws.readyState
+ }`
)
}
} else {
private broadcastToClients (message: string): void {
for (const client of this.webSocketServer.clients) {
- if (client?.readyState === WebSocket.OPEN) {
+ if (client.readyState === WebSocket.OPEN) {
client.send(message)
}
}
return false
}
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (request.length !== 3) {
logger.error(
`${this.logPrefix(moduleName, 'validateRawDataRequest')} UI protocol request is malformed:`,
return false
}
- if (!validateUUID(request?.[0])) {
+ if (!validateUUID(request[0])) {
logger.error(
`${this.logPrefix(
moduleName,
if (isNotEmptyArray(payload.hashIds)) {
payload.hashIds = payload.hashIds
?.map((hashId) => {
- if (hashId != null && this.uiServer.chargingStations.has(hashId)) {
+ if (this.uiServer.chargingStations.has(hashId)) {
return hashId
}
logger.warn(
PerformanceStatistics
>()
- private readonly objId: string
- private readonly objName: string
+ private readonly objId: string | undefined
+ private readonly objName: string | undefined
private performanceObserver!: PerformanceObserver
private readonly statistics: Statistics
private displayInterval?: NodeJS.Timeout
- private constructor (objId: string, objName: string, uri: URL) {
- this.objId = objId
- this.objName = objName
+ private constructor (objId: string | undefined, objName: string | undefined, uri: URL) {
+ this.objId = objId ?? 'Object id not specified'
+ this.objName = objName ?? 'Object name not specified'
this.initializePerformanceObserver()
this.statistics = {
- id: this.objId ?? 'Object id not specified',
- name: this.objName ?? 'Object name not specified',
+ id: this.objId,
+ name: this.objName,
uri: uri.toString(),
createdAt: new Date(),
statisticsData: new Map()
this.stopLogStatisticsInterval()
performance.clearMarks()
performance.clearMeasures()
- this.performanceObserver?.disconnect()
+ this.performanceObserver.disconnect()
}
public restart (): void {
}
private logStatistics (): void {
- logger.info(`${this.logPrefix()}`, {
+ logger.info(this.logPrefix(), {
...this.statistics,
statisticsData: JSONStringifyWithMapSupport(this.statistics.statisticsData)
})
public open (): void {
JsonFileStorage.performanceRecords = new Map<string, Statistics>()
try {
- if (this?.fd == null) {
+ if (this.fd == null) {
if (!existsSync(dirname(this.dbName))) {
mkdirSync(dirname(this.dbName), { recursive: true })
}
public close (): void {
JsonFileStorage.performanceRecords.clear()
try {
- if (this?.fd != null) {
+ if (this.fd != null) {
closeSync(this.fd)
- delete this?.fd
+ delete this.fd
}
} catch (error) {
handleFileException(
}
private checkPerformanceRecordsFile (): void {
- if (this?.fd == null) {
+ if (this.fd == null) {
throw new BaseError(
`${this.logPrefix} Performance records '${this.dbName}' file descriptor not found`
)
// Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
-import {
- type Configuration,
- type Connection,
- type IDatabaseDriver,
- MikroORM,
- type Options
-} from '@mikro-orm/core'
+import { type Configuration, MikroORM, type Options } from '@mikro-orm/core'
import { TsMorphMetadataProvider } from '@mikro-orm/reflection'
import { Storage } from './Storage.js'
public async open (): Promise<void> {
try {
- if (this?.orm == null) {
+ if (this.orm == null) {
this.orm = await MikroORM.init(this.getOptions(), true)
}
} catch (error) {
public async close (): Promise<void> {
try {
- if (this?.orm != null) {
+ if (this.orm != null) {
await this.orm.close()
- delete this?.orm
+ delete this.orm
}
} catch (error) {
this.handleDBError(this.storageType, error as Error)
if (this.storageType === StorageType.SQLITE) {
return `${Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME}.db`
}
- return (
- this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '') ??
- Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME
- )
+ return this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '')
}
- private getOptions ():
- | Configuration<IDatabaseDriver<Connection>>
- | Options<IDatabaseDriver<Connection>> {
+ private getOptions (): Configuration | Options {
return {
metadataProvider: TsMorphMetadataProvider,
entities: [PerformanceRecord, PerformanceData],
super(storageUri, logPrefix)
this.client = new MongoClient(this.storageUri.toString())
this.connected = false
- this.dbName =
- this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '') ??
- Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME
+ this.dbName = this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '')
}
public async storePerformanceStatistics (performanceStatistics: Statistics): Promise<void> {
public async open (): Promise<void> {
try {
- if (!this.connected && this?.client != null) {
+ if (!this.connected && this.client != null) {
await this.client.connect()
this.connected = true
}
public async close (): Promise<void> {
try {
- if (this.connected && this?.client != null) {
+ if (this.connected && this.client != null) {
await this.client.close()
this.connected = false
}
}
private checkDBConnection (): void {
- if (this?.client == null) {
+ if (this.client == null) {
throw new BaseError(
`${this.logPrefix} ${this.getDBNameFromStorageType(
StorageType.MONGO_DB
}'${inTableOrCollectionStr}:`,
error
)
- if (params?.throwError === true) {
+ if (params.throwError === true) {
throw error
}
}
export interface BroadcastChannelResponsePayload
extends Omit<ResponsePayload, 'hashIdsSucceeded' | 'hashIdsFailed' | 'responsesFailed'> {
- hashId: string
+ hashId: string | undefined
}
export interface MessageEvent {
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class Configuration {
- public static configurationChangeCallback: () => Promise<void>
+ public static configurationChangeCallback?: () => Promise<void>
private static readonly configurationFile = join(
dirname(fileURLToPath(import.meta.url)),
] as StationTemplateUrl[])
Configuration.getConfigurationData()?.stationTemplateUrls.forEach(
(stationTemplateUrl: StationTemplateUrl) => {
- if (stationTemplateUrl?.['numberOfStation' as keyof StationTemplateUrl] !== undefined) {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ if (stationTemplateUrl['numberOfStation' as keyof StationTemplateUrl] !== undefined) {
console.error(
`${chalk.green(logPrefix())} ${chalk.red(
`Deprecated configuration key 'numberOfStation' usage for template file '${stationTemplateUrl.file}' in 'stationTemplateUrls'. Use 'numberOfStations' instead`
string,
unknown
>
- )?.[key] !== undefined
+ )[key] !== undefined
) {
console.error(
`${chalk.green(logPrefix())} ${chalk.red(
default:
logMsg = `${fileType} file ${file} error:`
}
- if (params?.consoleOut === true) {
+ if (params.consoleOut === true) {
logMsg = `${logMsg} `
- if (params?.throwError === true) {
+ if (params.throwError === true) {
console.error(`${chalk.green(prefix)}${chalk.red(logMsg)}`, error)
} else {
console.warn(`${chalk.green(prefix)}${chalk.yellow(logMsg)}`, error)
}
- } else if (params?.consoleOut === false) {
- if (params?.throwError === true) {
+ } else if (params.consoleOut === false) {
+ if (params.throwError === true) {
logger.error(`${prefix}${logMsg}`, error)
} else {
logger.warn(`${prefix}${logMsg}`, error)
}
}
- if (params?.throwError === true) {
+ if (params.throwError === true) {
throw error
}
}
): void => {
setDefaultErrorParams(params, { throwError: false, consoleOut: false })
logger.error(`${chargingStation.logPrefix()} Request command '${commandName}' error:`, error)
- if (params?.throwError === true) {
+ if (params.throwError === true) {
throw error
}
}
const buildChargingStationDataPayload = (chargingStation: ChargingStation): ChargingStationData => {
return {
started: chargingStation.started,
- stationInfo: chargingStation.stationInfo,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ stationInfo: chargingStation.stationInfo!,
connectors: buildConnectorsStatus(chargingStation),
evses: buildEvsesStatus(chargingStation, OutputFormat.worker),
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
ocppConfiguration: chargingStation.ocppConfiguration!,
- wsState: chargingStation?.wsConnection?.readyState,
+ wsState: chargingStation.wsConnection?.readyState,
bootNotificationResponse: chargingStation.bootNotificationResponse,
...(chargingStation.automaticTransactionGenerator != null && {
automaticTransactionGenerator:
}
const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1)
const percentileIndexInteger = Math.floor(percentileIndexBase)
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (sortedDataSet[percentileIndexInteger + 1] != null) {
return (
sortedDataSet[percentileIndexInteger] +
export const getRandomInteger = (max = Constants.MAX_RANDOM_INTEGER, min = 0): number => {
max = Math.floor(max)
- if (min != null && min !== 0) {
+ if (min !== 0) {
min = Math.ceil(min)
return Math.floor(randomInt(min, max + 1))
}
}
export const getRandomFloatRounded = (max = Number.MAX_VALUE, min = 0, scale = 2): number => {
- if (min != null && min !== 0) {
+ if (min !== 0) {
return roundTo(getRandomFloat(max, min), scale)
}
return roundTo(getRandomFloat(max), scale)
}
export const isEmptyObject = (obj: object): boolean => {
- if (obj?.constructor !== Object) {
+ if (obj.constructor !== Object) {
return false
}
// Iterates over the keys of an object, if
}
}
if (
- WebSocketCloseEventStatusString[code as keyof typeof WebSocketCloseEventStatusString] !==
- undefined
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ WebSocketCloseEventStatusString[code as keyof typeof WebSocketCloseEventStatusString] != null
) {
return WebSocketCloseEventStatusString[code as keyof typeof WebSocketCloseEventStatusString]
}
): ((...args: A) => R) => {
let result: R
return (...args: A) => {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (fn != null) {
result = fn.apply<T, A, R>(context, args)
;(fn as unknown as undefined) = (context as unknown as undefined) = undefined
* @param workerScript -
* @param workerOptions -
*/
- constructor (workerScript: string, workerOptions: WorkerOptions) {
+ constructor (workerScript: string | undefined, workerOptions: WorkerOptions) {
if (workerScript == null) {
throw new TypeError('Worker script is not defined')
}
}
get emitter (): EventEmitterAsyncResource | undefined {
- return this.pool?.emitter
+ return this.pool.emitter
}
/** @inheritDoc */
}
get emitter (): EventEmitterAsyncResource | undefined {
- return this.pool?.emitter
+ return this.pool.emitter
}
/** @inheritDoc */
if (!this.started) {
throw new Error('Cannot add a WorkerSet element: not started')
}
- if (this.workerSet == null) {
- throw new Error("Cannot add a WorkerSet element: 'workerSet' property does not exist")
- }
const workerSetElement = await this.getWorkerSetElement()
workerSetElement.worker.postMessage({
event: WorkerMessageEvents.startWorkerElement,