X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FHelpers.ts;h=22ed5041e0515cc6b0769b3acb85df2d54525287;hb=d990f4bc8ad5366a200fd3d89be76c084fd71cea;hp=38988d05dff7e9d161b403a2ebe7f4f8118ec010;hpb=be9f397bd55b221c24bacb110a64c21f012f36ab;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/Helpers.ts b/src/charging-station/Helpers.ts index 38988d05..22ed5041 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,8 +66,7 @@ import { isEmptyString, isNotEmptyArray, isNotEmptyString, - isUndefined, - isValidTime, + isValidDate, logger, secureRandom } from '../utils/index.js' @@ -82,9 +82,9 @@ export const getChargingStationId = ( } // 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 @@ -146,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 }) } @@ -192,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 } @@ -213,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 @@ -232,7 +234,7 @@ export const getBootConnectorStatus = ( } export const checkTemplate = ( - stationTemplate: ChargingStationTemplate, + stationTemplate: ChargingStationTemplate | undefined, logPrefix: string, templateFile: string ): void => { @@ -246,14 +248,6 @@ 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 (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` @@ -289,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` @@ -312,7 +305,7 @@ export const checkStationInfoConnectorStatus = ( 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` ) @@ -331,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( @@ -341,6 +334,37 @@ export const buildConnectorsMap = ( return connectorsMap } +export const setChargingStationOptions = ( + stationInfo: ChargingStationInfo, + options?: ChargingStationOptions +): ChargingStationInfo => { + if (options?.supervisionUrls != null) { + stationInfo.supervisionUrls = options.supervisionUrls + } + 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 @@ -348,15 +372,15 @@ 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 = [] } @@ -367,52 +391,54 @@ export const initializeConnectorsMapStatus = ( } } -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 @@ -423,16 +449,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 }) } }) } @@ -457,7 +483,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) } @@ -466,13 +492,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 @@ -489,22 +516,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) { @@ -512,18 +539,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 = ( @@ -564,7 +591,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( @@ -590,12 +617,12 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = ( 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(), @@ -606,17 +633,19 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = ( 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 @@ -658,7 +687,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) @@ -676,14 +705,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) { @@ -735,7 +765,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 = [] } } @@ -747,7 +777,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}` : '' }` @@ -761,10 +791,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 @@ -794,25 +823,24 @@ 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 (chargingSchedule?.startSchedule == null && 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 (chargingSchedule?.startSchedule != null && !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 (chargingSchedule?.startSchedule != null && chargingSchedule?.duration == null) { + 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` ) @@ -828,10 +856,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)) { @@ -875,8 +901,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 ) ) { @@ -897,14 +922,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, @@ -920,9 +942,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) { @@ -940,7 +962,7 @@ export const prepareChargingProfileKind = ( 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 @@ -950,19 +972,19 @@ 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 } @@ -975,19 +997,13 @@ export const canProceedChargingProfile = ( ) return false } - if ( - chargingProfile.chargingSchedule.startSchedule != null && - !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 ( - 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` ) @@ -1030,12 +1046,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 = { @@ -1094,12 +1110,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