X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FHelpers.ts;h=2b3e1c7eae58408f212fd79940db666ae1c37cac;hb=53a9f111b7e3a26ccbb68ce2d31ddca209d3a5f2;hp=cc630d332c49b8533c417412949ae23ca268e0c2;hpb=66a7748ddeda8c94d7562a1ce58d440319654a4c;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/Helpers.ts b/src/charging-station/Helpers.ts index cc630d33..2b3e1c7e 100644 --- a/src/charging-station/Helpers.ts +++ b/src/charging-station/Helpers.ts @@ -36,6 +36,7 @@ import { type ChargingSchedulePeriod, type ChargingStationConfiguration, type ChargingStationInfo, + type ChargingStationOptions, type ChargingStationTemplate, type ChargingStationWorkerMessageEvents, ConnectorPhaseRotation, @@ -57,7 +58,7 @@ import { ACElectricUtils, Constants, DCElectricUtils, - cloneObject, + clone, convertToDate, convertToInt, isArraySorted, @@ -65,9 +66,7 @@ import { isEmptyString, isNotEmptyArray, isNotEmptyString, - isNullOrUndefined, - isUndefined, - isValidTime, + isValidDate, logger, secureRandom } from '../utils/index.js' @@ -78,14 +77,14 @@ export const getChargingStationId = ( index: number, stationTemplate: ChargingStationTemplate | undefined ): string => { - if (stationTemplate === undefined) { + if (stationTemplate == null) { return "Unknown 'chargingStationId'" } // 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 != null + return stationTemplate.fixedName === true ? stationTemplate.baseName : `${stationTemplate.baseName}-${instanceIndex.toString()}${idStr.substring( idStr.length - 4 @@ -147,16 +146,16 @@ export const getHashId = (index: number, stationTemplate: ChargingStationTemplat const chargingStationInfo = { chargePointModel: stationTemplate.chargePointModel, chargePointVendor: stationTemplate.chargePointVendor, - ...(!isUndefined(stationTemplate.chargeBoxSerialNumberPrefix) && { + ...(stationTemplate.chargeBoxSerialNumberPrefix != null && { chargeBoxSerialNumber: stationTemplate.chargeBoxSerialNumberPrefix }), - ...(!isUndefined(stationTemplate.chargePointSerialNumberPrefix) && { + ...(stationTemplate.chargePointSerialNumberPrefix != null && { chargePointSerialNumber: stationTemplate.chargePointSerialNumberPrefix }), - ...(!isUndefined(stationTemplate.meterSerialNumberPrefix) && { + ...(stationTemplate.meterSerialNumberPrefix != null && { meterSerialNumber: stationTemplate.meterSerialNumberPrefix }), - ...(!isUndefined(stationTemplate.meterType) && { + ...(stationTemplate.meterType != null && { meterType: stationTemplate.meterType }) } @@ -193,14 +192,16 @@ export const getPhaseRotationValue = ( } } -export const getMaxNumberOfEvses = (evses: Record): number => { +export const getMaxNumberOfEvses = (evses: Record | undefined): number => { if (evses == null) { return -1 } return Object.keys(evses).length } -const getMaxNumberOfConnectors = (connectors: Record): number => { +const getMaxNumberOfConnectors = ( + connectors: Record | undefined +): number => { if (connectors == null) { return -1 } @@ -214,17 +215,17 @@ export const getBootConnectorStatus = ( ): 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 @@ -233,7 +234,7 @@ export const getBootConnectorStatus = ( } export const checkTemplate = ( - stationTemplate: ChargingStationTemplate, + stationTemplate: ChargingStationTemplate | undefined, logPrefix: string, templateFile: string ): void => { @@ -247,15 +248,7 @@ export const checkTemplate = ( logger.error(`${logPrefix} ${errorMsg}`) throw new BaseError(errorMsg) } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (isEmptyObject(stationTemplate.AutomaticTransactionGenerator!)) { - stationTemplate.AutomaticTransactionGenerator = Constants.DEFAULT_ATG_CONFIGURATION - logger.warn( - `${logPrefix} Empty automatic transaction generator configuration from template file ${templateFile}, set to default: %j`, - Constants.DEFAULT_ATG_CONFIGURATION - ) - } - if (isNullOrUndefined(stationTemplate.idTagsFile) || isEmptyString(stationTemplate.idTagsFile)) { + if (stationTemplate.idTagsFile == null || isEmptyString(stationTemplate.idTagsFile)) { logger.warn( `${logPrefix} Missing id tags file in template file ${templateFile}. That can lead to issues with the Automatic Transaction Generator` ) @@ -267,13 +260,12 @@ export const checkConfiguration = ( logPrefix: string, configurationFile: string ): void => { - if (isNullOrUndefined(stationConfiguration)) { + if (stationConfiguration == null) { const errorMsg = `Failed to read charging station configuration file ${configurationFile}` logger.error(`${logPrefix} ${errorMsg}`) throw new BaseError(errorMsg) } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (isEmptyObject(stationConfiguration!)) { + if (isEmptyObject(stationConfiguration)) { const errorMsg = `Empty charging station configuration from file ${configurationFile}` logger.error(`${logPrefix} ${errorMsg}`) throw new BaseError(errorMsg) @@ -291,14 +283,13 @@ export const checkConnectorsConfiguration = ( } => { 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 === false + stationTemplate.randomConnectors !== true ) { logger.warn( `${logPrefix} Number of connectors exceeds the number of connector configurations in template ${templateFile}, forcing random connector configurations affectation` @@ -314,7 +305,7 @@ export const checkStationInfoConnectorStatus = ( logPrefix: string, templateFile: string ): void => { - if (!isNullOrUndefined(connectorStatus?.status)) { + if (connectorStatus.status != null) { logger.warn( `${logPrefix} Charging station information from template ${templateFile} with connector id ${connectorId} status configuration defined, undefine it` ) @@ -333,7 +324,7 @@ export const buildConnectorsMap = ( const connectorStatus = connectors[connector] const connectorId = convertToInt(connector) checkStationInfoConnectorStatus(connectorId, connectorStatus, logPrefix, templateFile) - connectorsMap.set(connectorId, cloneObject(connectorStatus)) + connectorsMap.set(connectorId, clone(connectorStatus)) } } else { logger.warn( @@ -343,6 +334,38 @@ export const buildConnectorsMap = ( return connectorsMap } +export const setChargingStationOptions = ( + chargingStation: ChargingStation, + stationInfo: ChargingStationInfo, + options?: ChargingStationOptions +): ChargingStationInfo => { + if (options?.supervisionUrls != null) { + chargingStation.setSupervisionUrls(options.supervisionUrls, false) + } + if (options?.persistentConfiguration != null) { + stationInfo.stationInfoPersistentConfiguration = options.persistentConfiguration + stationInfo.ocppPersistentConfiguration = options.persistentConfiguration + stationInfo.automaticTransactionGeneratorPersistentConfiguration = + options.persistentConfiguration + } + if (options?.autoStart != null) { + stationInfo.autoStart = options.autoStart + } + if (options?.autoRegister != null) { + stationInfo.autoRegister = options.autoRegister + } + if (options?.enableStatistics != null) { + stationInfo.enableStatistics = options.enableStatistics + } + if (options?.ocppStrictCompliance != null) { + stationInfo.ocppStrictCompliance = options.ocppStrictCompliance + } + if (options?.stopTransactionsOnStopped != null) { + stationInfo.stopTransactionsOnStopped = options.stopTransactionsOnStopped + } + return stationInfo +} + export const initializeConnectorsMapStatus = ( connectors: Map, logPrefix: string @@ -350,74 +373,73 @@ export const initializeConnectorsMapStatus = ( for (const connectorId of connectors.keys()) { if (connectorId > 0 && connectors.get(connectorId)?.transactionStarted === true) { logger.warn( - `${logPrefix} Connector id ${connectorId} at initialization has a transaction started with id ${connectors.get( - connectorId - )?.transactionId}` + `${logPrefix} Connector id ${connectorId} at initialization has a transaction started with id ${ + connectors.get(connectorId)?.transactionId + }` ) } if (connectorId === 0) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion connectors.get(connectorId)!.availability = AvailabilityType.Operative - if (isUndefined(connectors.get(connectorId)?.chargingProfiles)) { + if (connectors.get(connectorId)?.chargingProfiles == null) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion connectors.get(connectorId)!.chargingProfiles = [] } - } else if ( - connectorId > 0 && - isNullOrUndefined(connectors.get(connectorId)?.transactionStarted) - ) { + } else if (connectorId > 0 && connectors.get(connectorId)?.transactionStarted == null) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion initializeConnectorStatus(connectors.get(connectorId)!) } } } -export const resetConnectorStatus = (connectorStatus: ConnectorStatus): void => { +export const resetConnectorStatus = (connectorStatus: ConnectorStatus | undefined): void => { + if (connectorStatus == null) { + return + } connectorStatus.chargingProfiles = connectorStatus.transactionId != null && isNotEmptyArray(connectorStatus.chargingProfiles) - ? connectorStatus.chargingProfiles?.filter( - (chargingProfile) => chargingProfile.transactionId !== connectorStatus.transactionId + ? connectorStatus.chargingProfiles.filter( + chargingProfile => chargingProfile.transactionId !== connectorStatus.transactionId ) : [] connectorStatus.idTagLocalAuthorized = false 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 = ( stationInfo: ChargingStationInfo, bootReason: BootReasonEnumType = BootReasonEnumType.PowerUp -): BootNotificationRequest => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const ocppVersion = stationInfo.ocppVersion! +): BootNotificationRequest | undefined => { + const ocppVersion = stationInfo.ocppVersion switch (ocppVersion) { case OCPPVersion.VERSION_16: return { chargePointModel: stationInfo.chargePointModel, chargePointVendor: stationInfo.chargePointVendor, - ...(!isUndefined(stationInfo.chargeBoxSerialNumber) && { + ...(stationInfo.chargeBoxSerialNumber != null && { chargeBoxSerialNumber: stationInfo.chargeBoxSerialNumber }), - ...(!isUndefined(stationInfo.chargePointSerialNumber) && { + ...(stationInfo.chargePointSerialNumber != null && { chargePointSerialNumber: stationInfo.chargePointSerialNumber }), - ...(!isUndefined(stationInfo.firmwareVersion) && { + ...(stationInfo.firmwareVersion != null && { firmwareVersion: stationInfo.firmwareVersion }), - ...(!isUndefined(stationInfo.iccid) && { iccid: stationInfo.iccid }), - ...(!isUndefined(stationInfo.imsi) && { imsi: stationInfo.imsi }), - ...(!isUndefined(stationInfo.meterSerialNumber) && { + ...(stationInfo.iccid != null && { iccid: stationInfo.iccid }), + ...(stationInfo.imsi != null && { imsi: stationInfo.imsi }), + ...(stationInfo.meterSerialNumber != null && { meterSerialNumber: stationInfo.meterSerialNumber }), - ...(!isUndefined(stationInfo.meterType) && { + ...(stationInfo.meterType != null && { meterType: stationInfo.meterType }) } satisfies OCPP16BootNotificationRequest @@ -428,16 +450,16 @@ export const createBootNotificationRequest = ( chargingStation: { model: stationInfo.chargePointModel, vendorName: stationInfo.chargePointVendor, - ...(!isUndefined(stationInfo.firmwareVersion) && { + ...(stationInfo.firmwareVersion != null && { firmwareVersion: stationInfo.firmwareVersion }), - ...(!isUndefined(stationInfo.chargeBoxSerialNumber) && { + ...(stationInfo.chargeBoxSerialNumber != null && { serialNumber: stationInfo.chargeBoxSerialNumber }), - ...((!isUndefined(stationInfo.iccid) || !isUndefined(stationInfo.imsi)) && { + ...((stationInfo.iccid != null || stationInfo.imsi != null) && { modem: { - ...(!isUndefined(stationInfo.iccid) && { iccid: stationInfo.iccid }), - ...(!isUndefined(stationInfo.imsi) && { imsi: stationInfo.imsi }) + ...(stationInfo.iccid != null && { iccid: stationInfo.iccid }), + ...(stationInfo.imsi != null && { imsi: stationInfo.imsi }) } }) } @@ -462,7 +484,7 @@ export const warnTemplateKeysDeprecation = ( templateKey.deprecatedKey, logPrefix, templateFile, - !isUndefined(templateKey.key) ? `Use '${templateKey.key}' instead` : undefined + templateKey.key != null ? `Use '${templateKey.key}' instead` : undefined ) convertDeprecatedTemplateKey(stationTemplate, templateKey.deprecatedKey, templateKey.key) } @@ -471,13 +493,14 @@ export const warnTemplateKeysDeprecation = ( export const stationTemplateToStationInfo = ( stationTemplate: ChargingStationTemplate ): ChargingStationInfo => { - stationTemplate = cloneObject(stationTemplate) + stationTemplate = clone(stationTemplate) delete stationTemplate.power delete stationTemplate.powerUnit delete stationTemplate.Connectors delete stationTemplate.Evses delete stationTemplate.Configuration delete stationTemplate.AutomaticTransactionGenerator + delete stationTemplate.numberOfConnectors delete stationTemplate.chargeBoxSerialNumberPrefix delete stationTemplate.chargePointSerialNumberPrefix delete stationTemplate.meterSerialNumberPrefix @@ -494,22 +517,22 @@ export const createSerialNumber = ( ): 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) { @@ -517,18 +540,18 @@ export const propagateSerialNumber = ( '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 = ( @@ -569,7 +592,7 @@ export const getConnectorChargingProfiles = ( chargingStation: ChargingStation, connectorId: number ): ChargingProfile[] => { - return cloneObject( + return clone( (chargingStation.getConnectorStatus(connectorId)?.chargingProfiles ?? []) .sort((a, b) => b.stackLevel - a.stackLevel) .concat( @@ -594,36 +617,36 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = ( chargingProfiles, chargingStation.logPrefix() ) - if (!isNullOrUndefined(result)) { - limit = result?.limit - chargingProfile = result?.chargingProfile + if (result != null) { + 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(), // eslint-disable-next-line @typescript-eslint/no-non-null-assertion chargingStation.stationInfo.voltageOut!, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - limit! + limit ) 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!) + DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit) } const connectorMaximumPower = // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingStation.stationInfo.maximumPower! / chargingStation.powerDivider - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (limit! > connectorMaximumPower) { + 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 @@ -665,7 +688,7 @@ export const waitChargingStationEvents = async ( event: ChargingStationWorkerMessageEvents, eventsToWait: number ): Promise => { - return await new Promise((resolve) => { + return await new Promise(resolve => { let events = 0 if (eventsToWait === 0) { resolve(events) @@ -683,14 +706,15 @@ export const waitChargingStationEvents = async ( const getConfiguredMaxNumberOfConnectors = (stationTemplate: ChargingStationTemplate): number => { let configuredMaxNumberOfConnectors = 0 if (isNotEmptyArray(stationTemplate.numberOfConnectors)) { - const numberOfConnectors = stationTemplate.numberOfConnectors as number[] + const numberOfConnectors = stationTemplate.numberOfConnectors configuredMaxNumberOfConnectors = numberOfConnectors[Math.floor(secureRandom() * numberOfConnectors.length)] - } else if (!isUndefined(stationTemplate.numberOfConnectors)) { - configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors as number + } else if (stationTemplate.numberOfConnectors != null) { + configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors } 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) { @@ -742,7 +766,7 @@ const initializeConnectorStatus = (connectorStatus: ConnectorStatus): void => { connectorStatus.transactionStarted = false connectorStatus.energyActiveImportRegisterValue = 0 connectorStatus.transactionEnergyActiveImportRegisterValue = 0 - if (isUndefined(connectorStatus.chargingProfiles)) { + if (connectorStatus.chargingProfiles == null) { connectorStatus.chargingProfiles = [] } } @@ -754,7 +778,7 @@ const warnDeprecatedTemplateKey = ( templateFile: string, logMsgToAppend = '' ): void => { - if (!isUndefined(template?.[key as keyof ChargingStationTemplate])) { + if (template[key as keyof ChargingStationTemplate] != null) { const logMsg = `Deprecated template key '${key}' usage in file '${templateFile}'${ isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : '' }` @@ -768,10 +792,9 @@ const convertDeprecatedTemplateKey = ( deprecatedKey: string, key?: string ): void => { - if (!isUndefined(template?.[deprecatedKey as keyof ChargingStationTemplate])) { - if (!isUndefined(key)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - (template as unknown as Record)[key!] = + if (template[deprecatedKey as keyof ChargingStationTemplate] != null) { + if (key != null) { + (template as unknown as Record)[key] = template[deprecatedKey as keyof ChargingStationTemplate] } // eslint-disable-next-line @typescript-eslint/no-dynamic-delete @@ -801,40 +824,29 @@ const getLimitFromChargingProfiles = ( ): ChargingProfilesLimit | undefined => { const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j` const currentDate = new Date() - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const connectorStatus = chargingStation.getConnectorStatus(connectorId)! + const connectorStatus = chargingStation.getConnectorStatus(connectorId) for (const chargingProfile of chargingProfiles) { const chargingSchedule = chargingProfile.chargingSchedule - if ( - isNullOrUndefined(chargingSchedule?.startSchedule) && - connectorStatus?.transactionStarted === true - ) { + if (chargingSchedule.startSchedule == null) { 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 } - if ( - !isNullOrUndefined(chargingSchedule?.startSchedule) && - !isDate(chargingSchedule?.startSchedule) - ) { + if (!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 ( - !isNullOrUndefined(chargingSchedule?.startSchedule) && - isNullOrUndefined(chargingSchedule?.duration) - ) { + if (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` ) // OCPP specifies that if duration is not defined, it should be infinite - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingSchedule.duration = differenceInSeconds(maxTime, chargingSchedule.startSchedule!) + chargingSchedule.duration = differenceInSeconds(maxTime, chargingSchedule.startSchedule) } if (!prepareChargingProfileKind(connectorStatus, chargingProfile, currentDate, logPrefix)) { continue @@ -845,10 +857,8 @@ const getLimitFromChargingProfiles = ( // Check if the charging profile is active if ( isWithinInterval(currentDate, { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - start: chargingSchedule.startSchedule!, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - end: addSeconds(chargingSchedule.startSchedule!, chargingSchedule.duration!) + start: chargingSchedule.startSchedule, + end: addSeconds(chargingSchedule.startSchedule, chargingSchedule.duration) }) ) { if (isNotEmptyArray(chargingSchedule.chargingSchedulePeriod)) { @@ -892,8 +902,7 @@ const getLimitFromChargingProfiles = ( // Find the right schedule period if ( isAfter( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - addSeconds(chargingSchedule.startSchedule!, chargingSchedulePeriod.startPeriod), + addSeconds(chargingSchedule.startSchedule, chargingSchedulePeriod.startPeriod), currentDate ) ) { @@ -914,14 +923,11 @@ const getLimitFromChargingProfiles = ( (index < chargingSchedule.chargingSchedulePeriod.length - 1 && differenceInSeconds( addSeconds( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingSchedule.startSchedule!, + chargingSchedule.startSchedule, chargingSchedule.chargingSchedulePeriod[index + 1].startPeriod ), - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingSchedule.startSchedule! - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - ) > chargingSchedule.duration!) + chargingSchedule.startSchedule + ) > chargingSchedule.duration) ) { const result: ChargingProfilesLimit = { limit: previousChargingSchedulePeriod.limit, @@ -937,9 +943,9 @@ const getLimitFromChargingProfiles = ( } export const prepareChargingProfileKind = ( - connectorStatus: ConnectorStatus, + connectorStatus: ConnectorStatus | undefined, chargingProfile: ChargingProfile, - currentDate: Date, + currentDate: string | number | Date, logPrefix: string ): boolean => { switch (chargingProfile.chargingProfileKind) { @@ -950,14 +956,14 @@ export const prepareChargingProfileKind = ( prepareRecurringChargingProfile(chargingProfile, currentDate, logPrefix) break case ChargingProfileKindType.RELATIVE: - if (!isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule)) { + if (chargingProfile.chargingSchedule.startSchedule != null) { logger.warn( `${logPrefix} ${moduleName}.prepareChargingProfileKind: Relative charging profile id ${chargingProfile.chargingProfileId} has a startSchedule property defined. It will be ignored or used if the connector has a transaction started` ) delete chargingProfile.chargingSchedule.startSchedule } if (connectorStatus?.transactionStarted === true) { - chargingProfile.chargingSchedule.startSchedule = connectorStatus?.transactionStart + chargingProfile.chargingSchedule.startSchedule = connectorStatus.transactionStart } // FIXME: Handle relative charging profile duration break @@ -967,44 +973,38 @@ export const prepareChargingProfileKind = ( export const canProceedChargingProfile = ( chargingProfile: ChargingProfile, - currentDate: Date, + currentDate: string | number | Date, logPrefix: string ): boolean => { if ( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - (isValidTime(chargingProfile.validFrom) && isBefore(currentDate, chargingProfile.validFrom!)) || - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - (isValidTime(chargingProfile.validTo) && isAfter(currentDate, chargingProfile.validTo!)) + (isValidDate(chargingProfile.validFrom) && isBefore(currentDate, chargingProfile.validFrom)) || + (isValidDate(chargingProfile.validTo) && isAfter(currentDate, chargingProfile.validTo)) ) { logger.debug( `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${ chargingProfile.chargingProfileId - } is not valid for the current date ${currentDate.toISOString()}` + } is not valid for the current date ${ + isDate(currentDate) ? currentDate.toISOString() : currentDate + }` ) return false } if ( - isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule) || - isNullOrUndefined(chargingProfile.chargingSchedule.duration) + chargingProfile.chargingSchedule.startSchedule == null || + chargingProfile.chargingSchedule.duration == null ) { logger.error( `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule or duration defined` ) return false } - if ( - !isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule) && - !isValidTime(chargingProfile.chargingSchedule.startSchedule) - ) { + if (!isValidDate(chargingProfile.chargingSchedule.startSchedule)) { logger.error( `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has an invalid startSchedule date defined` ) return false } - if ( - !isNullOrUndefined(chargingProfile.chargingSchedule.duration) && - !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` ) @@ -1019,7 +1019,7 @@ const canProceedRecurringChargingProfile = ( ): boolean => { if ( chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING && - isNullOrUndefined(chargingProfile.recurrencyKind) + chargingProfile.recurrencyKind == null ) { logger.error( `${logPrefix} ${moduleName}.canProceedRecurringChargingProfile: Recurring charging profile id ${chargingProfile.chargingProfileId} has no recurrencyKind defined` @@ -1028,7 +1028,7 @@ const canProceedRecurringChargingProfile = ( } if ( chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING && - isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule) + chargingProfile.chargingSchedule.startSchedule == null ) { logger.error( `${logPrefix} ${moduleName}.canProceedRecurringChargingProfile: Recurring charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined` @@ -1047,12 +1047,12 @@ const canProceedRecurringChargingProfile = ( */ const prepareRecurringChargingProfile = ( chargingProfile: ChargingProfile, - currentDate: Date, + currentDate: string | number | Date, logPrefix: string ): boolean => { const chargingSchedule = chargingProfile.chargingSchedule let recurringIntervalTranslated = false - let recurringInterval: Interval + let recurringInterval: Interval | undefined switch (chargingProfile.recurrencyKind) { case RecurrencyKindType.DAILY: recurringInterval = { @@ -1111,12 +1111,12 @@ const prepareRecurringChargingProfile = ( `${logPrefix} ${moduleName}.prepareRecurringChargingProfile: Recurring ${ chargingProfile.recurrencyKind } charging profile id ${chargingProfile.chargingProfileId} recurrency time interval [${toDate( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - recurringInterval!.start + recurringInterval?.start as Date ).toISOString()}, ${toDate( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - recurringInterval!.end - ).toISOString()}] has not been properly translated to current date ${currentDate.toISOString()} ` + recurringInterval?.end as Date + ).toISOString()}] has not been properly translated to current date ${ + isDate(currentDate) ? currentDate.toISOString() : currentDate + } ` ) } return recurringIntervalTranslated @@ -1127,7 +1127,7 @@ const checkRecurringChargingProfileDuration = ( interval: Interval, logPrefix: string ): void => { - if (isNullOrUndefined(chargingProfile.chargingSchedule.duration)) { + if (chargingProfile.chargingSchedule.duration == null) { logger.warn( `${logPrefix} ${moduleName}.checkRecurringChargingProfileDuration: Recurring ${ chargingProfile.chargingProfileKind @@ -1140,8 +1140,7 @@ const checkRecurringChargingProfileDuration = ( ) chargingProfile.chargingSchedule.duration = differenceInSeconds(interval.end, interval.start) } else if ( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingProfile.chargingSchedule.duration! > differenceInSeconds(interval.end, interval.start) + chargingProfile.chargingSchedule.duration > differenceInSeconds(interval.end, interval.start) ) { logger.warn( `${logPrefix} ${moduleName}.checkRecurringChargingProfileDuration: Recurring ${