+import { randomInt } from 'node:crypto'
import { readFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import type { DefinedError, ErrorObject, JSONSchemaType } from 'ajv'
import { isDate } from 'date-fns'
-import { OCPP16Constants } from './1.6/OCPP16Constants.js'
-import { OCPP20Constants } from './2.0/OCPP20Constants.js'
-import { OCPPConstants } from './OCPPConstants.js'
import {
type ChargingStation,
getConfigurationKey,
ChargePointErrorCode,
ChargingStationEvents,
type ConnectorStatus,
- type ConnectorStatusEnum,
+ ConnectorStatusEnum,
CurrentType,
ErrorType,
FileType,
MeterValueMeasurand,
MeterValuePhase,
MeterValueUnit,
+ type OCPP16ChargePointStatus,
type OCPP16StatusNotificationRequest,
+ type OCPP20ConnectorStatusEnumType,
type OCPP20StatusNotificationRequest,
OCPPVersion,
RequestCommand,
import {
ACElectricUtils,
Constants,
- DCElectricUtils,
convertToFloat,
convertToInt,
+ DCElectricUtils,
getRandomFloatFluctuatedRounded,
getRandomFloatRounded,
- getRandomInteger,
handleFileException,
isNotEmptyArray,
isNotEmptyString,
- isNullOrUndefined,
- isUndefined,
- logPrefix,
logger,
+ logPrefix,
max,
min,
roundTo
} from '../../utils/index.js'
+import { OCPP16Constants } from './1.6/OCPP16Constants.js'
+import { OCPP20Constants } from './2.0/OCPP20Constants.js'
+import { OCPPConstants } from './OCPPConstants.js'
-export const getMessageTypeString = (messageType: MessageType): string => {
+export const getMessageTypeString = (messageType: MessageType | undefined): string => {
switch (messageType) {
case MessageType.CALL_MESSAGE:
return 'request'
}
}
-export const buildStatusNotificationRequest = (
+const buildStatusNotificationRequest = (
chargingStation: ChargingStation,
connectorId: number,
status: ConnectorStatusEnum,
case OCPPVersion.VERSION_16:
return {
connectorId,
- status,
+ status: status as OCPP16ChargePointStatus,
errorCode: ChargePointErrorCode.NO_ERROR
} satisfies OCPP16StatusNotificationRequest
case OCPPVersion.VERSION_20:
case OCPPVersion.VERSION_201:
return {
timestamp: new Date(),
- connectorStatus: status,
+ connectorStatus: status as OCPP20ConnectorStatusEnumType,
connectorId,
- evseId
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ evseId: evseId!
} satisfies OCPP20StatusNotificationRequest
default:
throw new BaseError('Cannot build status notification payload: OCPP version not supported')
`${chargingStation.logPrefix()} The charging station expects to authorize RFID tags but nor local authorization nor remote authorization are enabled. Misbehavior may occur`
)
}
- if (chargingStation.getLocalAuthListEnabled() && isIdTagLocalAuthorized(chargingStation, idTag)) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const connectorStatus: ConnectorStatus = chargingStation.getConnectorStatus(connectorId)!
+ const connectorStatus = chargingStation.getConnectorStatus(connectorId)
+ if (
+ connectorStatus != null &&
+ chargingStation.getLocalAuthListEnabled() &&
+ isIdTagLocalAuthorized(chargingStation, idTag)
+ ) {
connectorStatus.localAuthorizeIdTag = idTag
connectorStatus.idTagLocalAuthorized = true
return true
isNotEmptyString(
chargingStation.idTagsCache
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- .getIdTags(getIdTagsFile(chargingStation.stationInfo)!)
- ?.find((tag) => tag === idTag)
+ .getIdTags(getIdTagsFile(chargingStation.stationInfo!)!)
+ ?.find(tag => tag === idTag)
)
)
}
idTag
}
)
- )?.idTagInfo?.status === AuthorizationStatus.ACCEPTED
+ ).idTagInfo.status === AuthorizationStatus.ACCEPTED
)
}
})
}
+export const restoreConnectorStatus = async (
+ chargingStation: ChargingStation,
+ connectorId: number,
+ connectorStatus: ConnectorStatus | undefined
+): Promise<void> => {
+ if (connectorStatus?.reservation != null) {
+ await sendAndSetConnectorStatus(chargingStation, connectorId, ConnectorStatusEnum.Reserved)
+ } else if (connectorStatus?.status !== ConnectorStatusEnum.Available) {
+ await sendAndSetConnectorStatus(chargingStation, connectorId, ConnectorStatusEnum.Available)
+ }
+}
+
const checkConnectorStatusTransition = (
chargingStation: ChargingStation,
connectorId: number,
status: ConnectorStatusEnum
): boolean => {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const fromStatus = chargingStation.getConnectorStatus(connectorId)!.status
+ const fromStatus = chargingStation.getConnectorStatus(connectorId)?.status
let transitionAllowed = false
switch (chargingStation.stationInfo?.ocppVersion) {
case OCPPVersion.VERSION_16:
if (
(connectorId === 0 &&
OCPP16Constants.ChargePointStatusChargingStationTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
+ transition => transition.from === fromStatus && transition.to === status
) !== -1) ||
(connectorId > 0 &&
OCPP16Constants.ChargePointStatusConnectorTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
+ transition => transition.from === fromStatus && transition.to === status
) !== -1)
) {
transitionAllowed = true
if (
(connectorId === 0 &&
OCPP20Constants.ChargingStationStatusTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
+ transition => transition.from === fromStatus && transition.to === status
) !== -1) ||
(connectorId > 0 &&
OCPP20Constants.ConnectorStatusTransitions.findIndex(
- (transition) => transition.from === fromStatus && transition.to === status
+ transition => transition.from === fromStatus && transition.to === status
) !== -1)
) {
transitionAllowed = true
}
if (!transitionAllowed) {
logger.warn(
- `${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
+ `${chargingStation.logPrefix()} OCPP ${
+ chargingStation.stationInfo.ocppVersion
+ } connector id ${connectorId} status transition from '${
+ chargingStation.getConnectorStatus(connectorId)?.status
}' to '${status}' is not allowed`
)
}
parseInt(socSampledValueTemplate.value),
socSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT
)
- : getRandomInteger(socMaximumValue, socMinimumValue)
+ : randomInt(socMinimumValue, socMaximumValue)
meterValue.sampledValue.push(
buildSampledValue(socSampledValueTemplate, socSampledValueTemplateValue)
)
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(),
)
? getRandomFloatFluctuatedRounded(
getLimitFromSampledValueTemplateCustomValue(
- powerPerPhaseSampledValueTemplates.L1?.value,
+ powerPerPhaseSampledValueTemplates.L1.value,
connectorMaximumPowerPerPhase / unitDivider,
connectorMinimumPowerPerPhase / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPowerPerPhase / unitDivider
}
),
- powerPerPhaseSampledValueTemplates.L1?.fluctuationPercent ??
+ powerPerPhaseSampledValueTemplates.L1.fluctuationPercent ??
Constants.DEFAULT_FLUCTUATION_PERCENT
)
: undefined
)
? getRandomFloatFluctuatedRounded(
getLimitFromSampledValueTemplateCustomValue(
- powerPerPhaseSampledValueTemplates.L2?.value,
+ powerPerPhaseSampledValueTemplates.L2.value,
connectorMaximumPowerPerPhase / unitDivider,
connectorMinimumPowerPerPhase / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPowerPerPhase / unitDivider
}
),
- powerPerPhaseSampledValueTemplates.L2?.fluctuationPercent ??
+ powerPerPhaseSampledValueTemplates.L2.fluctuationPercent ??
Constants.DEFAULT_FLUCTUATION_PERCENT
)
: undefined
)
? getRandomFloatFluctuatedRounded(
getLimitFromSampledValueTemplateCustomValue(
- powerPerPhaseSampledValueTemplates.L3?.value,
+ powerPerPhaseSampledValueTemplates.L3.value,
connectorMaximumPowerPerPhase / unitDivider,
connectorMinimumPowerPerPhase / unitDivider,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumPowerPerPhase / unitDivider
}
),
- powerPerPhaseSampledValueTemplates.L3?.fluctuationPercent ??
+ powerPerPhaseSampledValueTemplates.L3.fluctuationPercent ??
Constants.DEFAULT_FLUCTUATION_PERCENT
)
: undefined
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
}
),
)
? getRandomFloatFluctuatedRounded(
getLimitFromSampledValueTemplateCustomValue(
- currentPerPhaseSampledValueTemplates.L1?.value,
+ currentPerPhaseSampledValueTemplates.L1.value,
connectorMaximumAmperage,
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
- currentPerPhaseSampledValueTemplates.L1?.fluctuationPercent ??
+ currentPerPhaseSampledValueTemplates.L1.fluctuationPercent ??
Constants.DEFAULT_FLUCTUATION_PERCENT
)
: undefined
)
? getRandomFloatFluctuatedRounded(
getLimitFromSampledValueTemplateCustomValue(
- currentPerPhaseSampledValueTemplates.L2?.value,
+ currentPerPhaseSampledValueTemplates.L2.value,
connectorMaximumAmperage,
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
- currentPerPhaseSampledValueTemplates.L2?.fluctuationPercent ??
+ currentPerPhaseSampledValueTemplates.L2.fluctuationPercent ??
Constants.DEFAULT_FLUCTUATION_PERCENT
)
: undefined
)
? getRandomFloatFluctuatedRounded(
getLimitFromSampledValueTemplateCustomValue(
- currentPerPhaseSampledValueTemplates.L3?.value,
+ currentPerPhaseSampledValueTemplates.L3.value,
connectorMaximumAmperage,
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
- currentPerPhaseSampledValueTemplates.L3?.fluctuationPercent ??
+ currentPerPhaseSampledValueTemplates.L3.fluctuationPercent ??
Constants.DEFAULT_FLUCTUATION_PERCENT
)
: undefined
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
connectorMinimumAmperage,
{
limitationEnabled:
- chargingStation.stationInfo?.customValueLimitationMeterValues,
+ chargingStation.stationInfo.customValueLimitationMeterValues,
fallbackValue: connectorMinimumAmperage
}
),
// Energy.Active.Import.Register measurand (default)
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
}
// Persist previous value on connector
if (connector != null) {
if (
- !isNullOrUndefined(connector.energyActiveImportRegisterValue) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- connector.energyActiveImportRegisterValue! >= 0 &&
- !isNullOrUndefined(connector.transactionEnergyActiveImportRegisterValue) &&
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- connector.transactionEnergyActiveImportRegisterValue! >= 0
+ connector.energyActiveImportRegisterValue != null &&
+ connector.energyActiveImportRegisterValue >= 0 &&
+ connector.transactionEnergyActiveImportRegisterValue != null &&
+ connector.transactionEnergyActiveImportRegisterValue >= 0
) {
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- connector.energyActiveImportRegisterValue! += energyValueRounded
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- connector.transactionEnergyActiveImportRegisterValue! += energyValueRounded
+ connector.energyActiveImportRegisterValue += energyValueRounded
+ connector.transactionEnergyActiveImportRegisterValue += energyValueRounded
} else {
connector.energyActiveImportRegisterValue = 0
connector.transactionEnergyActiveImportRegisterValue = 0
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 (isUndefined(chargingStation.powerDivider)) {
+ if (chargingStation.powerDivider == null) {
const errMsg = `MeterValues measurand ${
measurandType ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
}: 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),
)
return
}
- const sampledValueTemplates: SampledValueTemplate[] =
+ const sampledValueTemplates =
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
chargingStation.getConnectorStatus(connectorId)!.MeterValues
for (
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 {
- ...(!isNullOrUndefined(sampledValueTemplate.unit) && {
+ ...(sampledValueTemplate.unit != null && {
unit: sampledValueTemplate.unit
}),
- ...(!isNullOrUndefined(sampledValueContext) && { context: sampledValueContext }),
- ...(!isNullOrUndefined(sampledValueTemplate.measurand) && {
+ ...(sampledValueContext != null && { context: sampledValueContext }),
+ ...(sampledValueTemplate.measurand != null && {
measurand: sampledValueTemplate.measurand
}),
- ...(!isNullOrUndefined(sampledValueLocation) && { location: sampledValueLocation }),
- ...(!isNullOrUndefined(value) && { value: value.toString() }),
- ...(!isNullOrUndefined(sampledValuePhase) && { phase: sampledValuePhase })
- } as SampledValue
+ ...(sampledValueLocation != null && { location: sampledValueLocation }),
+ ...{ value: value.toString() },
+ ...(sampledValuePhase != null && { phase: sampledValuePhase })
+ } satisfies SampledValue
}
const getMeasurandDefaultLocation = (
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
export class OCPPServiceUtils {
- public static getMessageTypeString = getMessageTypeString
- public static sendAndSetConnectorStatus = sendAndSetConnectorStatus
- public static isIdTagAuthorized = isIdTagAuthorized
- public static buildTransactionEndMeterValue = buildTransactionEndMeterValue
+ public static readonly getMessageTypeString = getMessageTypeString
+ public static readonly sendAndSetConnectorStatus = sendAndSetConnectorStatus
+ public static readonly restoreConnectorStatus = restoreConnectorStatus
+ public static readonly isIdTagAuthorized = isIdTagAuthorized
+ public static readonly buildTransactionEndMeterValue = buildTransactionEndMeterValue
protected static getSampledValueTemplate = getSampledValueTemplate
protected static buildSampledValue = buildSampledValue
// This is intentional
}
- public static ajvErrorsToErrorType (errors: ErrorObject[] | null | undefined): ErrorType {
+ public static ajvErrorsToErrorType (errors: ErrorObject[] | undefined | null): ErrorType {
if (isNotEmptyArray(errors)) {
for (const error of errors as DefinedError[]) {
switch (error.keyword) {
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}'`
return true
}
- public static convertDateToISOString<T extends JsonType>(obj: T): void {
- for (const key in obj) {
+ public static convertDateToISOString<T extends JsonType>(object: T): void {
+ for (const key in object) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
- 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()
+ if (isDate(object![key])) {
// 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') {
+ (object![key] as string) = (object![key] as Date).toISOString()
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-condition
+ } else if (typeof object![key] === 'object' && object![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)
+ OCPPServiceUtils.convertDateToISOString<T>(object![key] as T)
}
}
}
public static startHeartbeatInterval (chargingStation: ChargingStation, interval: number): void {
- if (chargingStation.heartbeatSetInterval === undefined) {
+ if (chargingStation.heartbeatSetInterval == null) {
chargingStation.startHeartbeat()
} else if (chargingStation.getHeartbeatInterval() !== interval) {
chargingStation.restartHeartbeat()