type ChargingSchedulePeriod,
type ChargingStationConfiguration,
type ChargingStationInfo,
+ type ChargingStationOptions,
type ChargingStationTemplate,
type ChargingStationWorkerMessageEvents,
ConnectorPhaseRotation,
ACElectricUtils,
Constants,
DCElectricUtils,
- cloneObject,
+ clone,
convertToDate,
convertToInt,
isArraySorted,
isEmptyString,
isNotEmptyArray,
isNotEmptyString,
- isValidTime,
+ isValidDate,
logger,
secureRandom
} from '../utils/index.js'
const chargingStationInfo = {
chargePointModel: stationTemplate.chargePointModel,
chargePointVendor: stationTemplate.chargePointVendor,
- ...(stationTemplate.chargeBoxSerialNumberPrefix !== undefined && {
+ ...(stationTemplate.chargeBoxSerialNumberPrefix != null && {
chargeBoxSerialNumber: stationTemplate.chargeBoxSerialNumberPrefix
}),
- ...(stationTemplate.chargePointSerialNumberPrefix !== undefined && {
+ ...(stationTemplate.chargePointSerialNumberPrefix != null && {
chargePointSerialNumber: stationTemplate.chargePointSerialNumberPrefix
}),
- ...(stationTemplate.meterSerialNumberPrefix !== undefined && {
+ ...(stationTemplate.meterSerialNumberPrefix != null && {
meterSerialNumber: stationTemplate.meterSerialNumberPrefix
}),
- ...(stationTemplate.meterType !== undefined && {
+ ...(stationTemplate.meterType != null && {
meterType: stationTemplate.meterType
})
}
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`
const connectorStatus = connectors[connector]
const connectorId = convertToInt(connector)
checkStationInfoConnectorStatus(connectorId, connectorStatus, logPrefix, templateFile)
- connectorsMap.set(connectorId, cloneObject<ConnectorStatus>(connectorStatus))
+ connectorsMap.set(connectorId, clone<ConnectorStatus>(connectorStatus))
}
} else {
logger.warn(
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<number, ConnectorStatus>,
logPrefix: string
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) {
}
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
return {
chargePointModel: stationInfo.chargePointModel,
chargePointVendor: stationInfo.chargePointVendor,
- ...(stationInfo.chargeBoxSerialNumber !== undefined && {
+ ...(stationInfo.chargeBoxSerialNumber != null && {
chargeBoxSerialNumber: stationInfo.chargeBoxSerialNumber
}),
- ...(stationInfo.chargePointSerialNumber !== undefined && {
+ ...(stationInfo.chargePointSerialNumber != null && {
chargePointSerialNumber: stationInfo.chargePointSerialNumber
}),
- ...(stationInfo.firmwareVersion !== undefined && {
+ ...(stationInfo.firmwareVersion != null && {
firmwareVersion: stationInfo.firmwareVersion
}),
- ...(stationInfo.iccid !== undefined && { iccid: stationInfo.iccid }),
- ...(stationInfo.imsi !== undefined && { imsi: stationInfo.imsi }),
- ...(stationInfo.meterSerialNumber !== undefined && {
+ ...(stationInfo.iccid != null && { iccid: stationInfo.iccid }),
+ ...(stationInfo.imsi != null && { imsi: stationInfo.imsi }),
+ ...(stationInfo.meterSerialNumber != null && {
meterSerialNumber: stationInfo.meterSerialNumber
}),
- ...(stationInfo.meterType !== undefined && {
+ ...(stationInfo.meterType != null && {
meterType: stationInfo.meterType
})
} satisfies OCPP16BootNotificationRequest
chargingStation: {
model: stationInfo.chargePointModel,
vendorName: stationInfo.chargePointVendor,
- ...(stationInfo.firmwareVersion !== undefined && {
+ ...(stationInfo.firmwareVersion != null && {
firmwareVersion: stationInfo.firmwareVersion
}),
- ...(stationInfo.chargeBoxSerialNumber !== undefined && {
+ ...(stationInfo.chargeBoxSerialNumber != null && {
serialNumber: stationInfo.chargeBoxSerialNumber
}),
- ...((stationInfo.iccid !== undefined || stationInfo.imsi !== undefined) && {
+ ...((stationInfo.iccid != null || stationInfo.imsi != null) && {
modem: {
- ...(stationInfo.iccid !== undefined && { iccid: stationInfo.iccid }),
- ...(stationInfo.imsi !== undefined && { imsi: stationInfo.imsi })
+ ...(stationInfo.iccid != null && { iccid: stationInfo.iccid }),
+ ...(stationInfo.imsi != null && { imsi: stationInfo.imsi })
}
})
}
templateKey.deprecatedKey,
logPrefix,
templateFile,
- templateKey.key !== undefined ? `Use '${templateKey.key}' instead` : undefined
+ templateKey.key != null ? `Use '${templateKey.key}' instead` : undefined
)
convertDeprecatedTemplateKey(stationTemplate, templateKey.deprecatedKey, templateKey.key)
}
export const stationTemplateToStationInfo = (
stationTemplate: ChargingStationTemplate
): ChargingStationInfo => {
- stationTemplate = cloneObject<ChargingStationTemplate>(stationTemplate)
+ stationTemplate = clone<ChargingStationTemplate>(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
chargingStation: ChargingStation,
connectorId: number
): ChargingProfile[] => {
- return cloneObject<ChargingProfile[]>(
+ return clone<ChargingProfile[]>(
(chargingStation.getConnectorStatus(connectorId)?.chargingProfiles ?? [])
.sort((a, b) => b.stackLevel - a.stackLevel)
.concat(
event: ChargingStationWorkerMessageEvents,
eventsToWait: number
): Promise<number> => {
- return await new Promise<number>((resolve) => {
+ return await new Promise<number>(resolve => {
let events = 0
if (eventsToWait === 0) {
resolve(events)
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 (stationTemplate.numberOfConnectors != null) {
- configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors as number
+ configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors
} else if (stationTemplate.Connectors != null && stationTemplate.Evses == null) {
configuredMaxNumberOfConnectors =
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
templateFile: string,
logMsgToAppend = ''
): void => {
- if (template[key as keyof ChargingStationTemplate] !== undefined) {
+ if (template[key as keyof ChargingStationTemplate] != null) {
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 (key !== undefined) {
+ if (template[deprecatedKey as keyof ChargingStationTemplate] != null) {
+ if (key != null) {
(template as unknown as Record<string, unknown>)[key] =
template[deprecatedKey as keyof ChargingStationTemplate]
}
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 instanceof Date ? currentDate.toISOString() : currentDate
+ isDate(currentDate) ? currentDate.toISOString() : currentDate
}`
)
return false
)
return false
}
- if (!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`
)
): boolean => {
const chargingSchedule = chargingProfile.chargingSchedule
let recurringIntervalTranslated = false
- let recurringInterval: Interval
+ let recurringInterval: Interval | undefined
switch (chargingProfile.recurrencyKind) {
case RecurrencyKindType.DAILY:
recurringInterval = {
`${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
+ recurringInterval?.end as Date
).toISOString()}] has not been properly translated to current date ${
- currentDate instanceof Date ? currentDate.toISOString() : currentDate
+ isDate(currentDate) ? currentDate.toISOString() : currentDate
} `
)
}