import { OCPPError } from '../../../exception/index.js'
import {
- type ComponentType,
+ ConnectorEnumType,
ErrorType,
- type EVSEType,
GenericDeviceModelStatusEnumType,
type IncomingRequestHandler,
type JsonType,
type OCPP20ClearCacheRequest,
+ OCPP20ComponentName,
type OCPP20GetBaseReportRequest,
type OCPP20GetBaseReportResponse,
OCPP20IncomingRequestCommand,
OCPPVersion,
ReportBaseEnumType,
type ReportDataType,
- type VariableAttributeType,
- type VariableCharacteristicsType,
- type VariableType,
} from '../../../types/index.js'
import { isAsyncFunction, logger } from '../../../utils/index.js'
import { OCPPIncomingRequestService } from '../OCPPIncomingRequestService.js'
-import { OCPP20Constants } from './OCPP20Constants.js'
import { OCPP20ServiceUtils } from './OCPP20ServiceUtils.js'
const moduleName = 'OCPP20IncomingRequestService'
// }
super(OCPPVersion.VERSION_201)
this.incomingRequestHandlers = new Map<OCPP20IncomingRequestCommand, IncomingRequestHandler>([
- [OCPP20IncomingRequestCommand.CLEAR_CACHE, this.handleRequestClearCache.bind(this)],
+ [OCPP20IncomingRequestCommand.CLEAR_CACHE, super.handleRequestClearCache.bind(this)],
[OCPP20IncomingRequestCommand.GET_BASE_REPORT, this.handleRequestGetBaseReport.bind(this)],
])
this.payloadValidateFunctions = new Map<
response: OCPP20GetBaseReportResponse
) => {
if (response.status === GenericDeviceModelStatusEnumType.Accepted) {
- const { requestId, reportBase } = request
+ const { reportBase, requestId } = request
const reportData = this.buildReportData(chargingStation, reportBase)
chargingStation.ocppRequestService
.requestHandler<OCPP20NotifyReportRequest, OCPP20NotifyReportResponse>(
chargingStation,
OCPP20RequestCommand.NOTIFY_REPORT,
{
+ generatedAt: new Date(),
reportData,
requestId,
seqNo: 0,
}
)
.then(() => {
- logger.info(
+ logger.debug(
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`${chargingStation.logPrefix()} ${moduleName}.constructor: NotifyReport sent for requestId ${requestId} with ${reportData.length} report items`
)
+ return undefined
})
.catch((error: unknown) => {
logger.error(
this.emit(commandName, chargingStation, commandPayload, response)
}
- private handleRequestGetBaseReport (
- chargingStation: ChargingStation,
- commandPayload: OCPP20GetBaseReportRequest
- ): OCPP20GetBaseReportResponse {
- logger.info(
- `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetBaseReport: GetBaseReport request received with requestId ${commandPayload.requestId} and reportBase ${commandPayload.reportBase}`
- )
- // Build report data to check if any data is available
- const reportData = this.buildReportData(chargingStation, commandPayload.reportBase)
- if (reportData.length === 0) {
- logger.info(
- `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetBaseReport: No data available for reportBase ${commandPayload.reportBase}`
- )
- return {
- status: GenericDeviceModelStatusEnumType.EmptyResultSet,
- }
- }
- return {
- status: GenericDeviceModelStatusEnumType.Accepted,
- }
- }
-
private buildReportData (
chargingStation: ChargingStation,
- reportBase: string
+ reportBase: ReportBaseEnumType
): ReportDataType[] {
// Validate reportBase parameter
- if (!Object.values(ReportBaseEnumType).includes(reportBase as ReportBaseEnumType)) {
+ if (!Object.values(ReportBaseEnumType).includes(reportBase)) {
logger.warn(
`${chargingStation.logPrefix()} ${moduleName}.buildReportData: Invalid reportBase '${reportBase}'`
)
for (const configKey of chargingStation.ocppConfiguration.configurationKey) {
reportData.push({
component: {
- name: OCPP20Constants.ComponentName.OCPP_COMM_CTRLR,
+ name: OCPP20ComponentName.OCPPCommCtrlr,
},
variable: {
name: configKey.key,
const stationInfo = chargingStation.stationInfo
if (stationInfo.chargePointModel) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.CHARGING_STATION },
+ component: { name: OCPP20ComponentName.DeviceDataCtrlr },
variable: { name: 'Model' },
variableAttribute: [{ type: 'Actual', value: stationInfo.chargePointModel }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
}
if (stationInfo.chargePointVendor) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.CHARGING_STATION },
+ component: { name: OCPP20ComponentName.DeviceDataCtrlr },
variable: { name: 'VendorName' },
variableAttribute: [{ type: 'Actual', value: stationInfo.chargePointVendor }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
}
if (stationInfo.chargePointSerialNumber) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.CHARGING_STATION },
+ component: { name: OCPP20ComponentName.DeviceDataCtrlr },
variable: { name: 'SerialNumber' },
variableAttribute: [{ type: 'Actual', value: stationInfo.chargePointSerialNumber }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
}
if (stationInfo.firmwareVersion) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.CHARGING_STATION },
+ component: { name: OCPP20ComponentName.DeviceDataCtrlr },
variable: { name: 'FirmwareVersion' },
variableAttribute: [{ type: 'Actual', value: stationInfo.firmwareVersion }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
if (chargingStation.ocppConfiguration?.configurationKey) {
for (const configKey of chargingStation.ocppConfiguration.configurationKey) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.OCPP_COMM_CTRLR },
+ component: { name: OCPP20ComponentName.OCPPCommCtrlr },
variable: { name: configKey.key },
variableAttribute: [{ type: 'Actual', value: configKey.value }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
reportData.push({
component: {
evse: { id: evseId },
- name: 'EVSE',
+ name: OCPP20ComponentName.DeviceDataCtrlr,
},
variable: { name: 'AvailabilityState' },
variableAttribute: [{ type: 'Actual', value: evse.availability }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: true },
})
- if (evse.connectors) {
+ if (evse.connectors.size > 0) {
for (const [connectorId, connector] of evse.connectors) {
reportData.push({
component: {
- evse: { connectorId, id: evseId },
- name: 'Connector',
+ evse: { connectorId: connectorId.toString(), id: evseId },
+ name: OCPP20ComponentName.DeviceDataCtrlr,
},
variable: { name: 'ConnectorType' },
variableAttribute: [
- { type: 'Actual', value: String(connector.connectorType) },
+ { type: 'Actual', value: connector.type ?? ConnectorEnumType.Unknown },
],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
})
if (connectorId > 0) {
reportData.push({
component: {
- evse: { connectorId, id: 1 },
+ evse: { connectorId: connectorId.toString(), id: 1 },
name: 'Connector',
},
variable: { name: 'ConnectorType' },
- variableAttribute: [{ type: 'Actual', value: String(connector.connectorType) }],
+ variableAttribute: [
+ { type: 'Actual', value: connector.type ?? ConnectorEnumType.Unknown },
+ ],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
})
}
const stationInfo = chargingStation.stationInfo
if (stationInfo.chargePointModel) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.CHARGING_STATION },
+ component: { name: 'ChargingStation' },
variable: { name: 'Model' },
variableAttribute: [{ type: 'Actual', value: stationInfo.chargePointModel }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
}
if (stationInfo.chargePointVendor) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.CHARGING_STATION },
+ component: { name: 'ChargingStation' },
variable: { name: 'VendorName' },
variableAttribute: [{ type: 'Actual', value: stationInfo.chargePointVendor }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
}
if (stationInfo.firmwareVersion) {
reportData.push({
- component: { name: OCPP20Constants.ComponentName.CHARGING_STATION },
+ component: { name: 'ChargingStation' },
variable: { name: 'FirmwareVersion' },
variableAttribute: [{ type: 'Actual', value: stationInfo.firmwareVersion }],
variableCharacteristics: { dataType: 'string', supportsMonitoring: false },
default:
logger.warn(
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`${chargingStation.logPrefix()} ${moduleName}.buildReportData: Unknown reportBase '${reportBase}'`
)
}
return reportData
}
+ private handleRequestGetBaseReport (
+ chargingStation: ChargingStation,
+ commandPayload: OCPP20GetBaseReportRequest
+ ): OCPP20GetBaseReportResponse {
+ logger.debug(
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetBaseReport: GetBaseReport request received with requestId ${commandPayload.requestId} and reportBase ${commandPayload.reportBase}`
+ )
+ // Build report data to check if any data is available
+ const reportData = this.buildReportData(chargingStation, commandPayload.reportBase)
+ if (reportData.length === 0) {
+ logger.info(
+ `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetBaseReport: No data available for reportBase ${commandPayload.reportBase}`
+ )
+ return {
+ status: GenericDeviceModelStatusEnumType.EmptyResultSet,
+ }
+ }
+ return {
+ status: GenericDeviceModelStatusEnumType.Accepted,
+ }
+ }
+
private validatePayload (
chargingStation: ChargingStation,
commandName: OCPP20IncomingRequestCommand,
import type { JsonObject } from '../../JsonType.js'
import type { EVSEType, StatusInfoType } from './Common.js'
+export enum OCPP20ComponentName {
+ AlignedDataCtrlr = 'AlignedDataCtrlr',
+ AuthCacheCtrlr = 'AuthCacheCtrlr',
+ AuthCtrlr = 'AuthCtrlr',
+ CHAdeMOCtrlr = 'CHAdeMOCtrlr',
+ ClockCtrlr = 'ClockCtrlr',
+ CustomizationCtrlr = 'CustomizationCtrlr',
+ DeviceDataCtrlr = 'DeviceDataCtrlr',
+ DisplayMessageCtrlr = 'DisplayMessageCtrlr',
+ ISO15118Ctrlr = 'ISO15118Ctrlr',
+ LocalAuthListCtrlr = 'LocalAuthListCtrlr',
+ MonitoringCtrlr = 'MonitoringCtrlr',
+ OCPPCommCtrlr = 'OCPPCommCtrlr',
+ ReservationCtrlr = 'ReservationCtrlr',
+ SampledDataCtrlr = 'SampledDataCtrlr',
+ SecurityCtrlr = 'SecurityCtrlr',
+ SmartChargingCtrlr = 'SmartChargingCtrlr',
+ TariffCostCtrlr = 'TariffCostCtrlr',
+ TxCtrlr = 'TxCtrlr',
+}
+
export enum OCPP20OptionalVariableName {
HeartbeatInterval = 'HeartbeatInterval',
WebSocketPingInterval = 'WebSocketPingInterval',
Target = 'Target',
}
-enum OCPP20ComponentName {
- AlignedDataCtrlr = 'AlignedDataCtrlr',
- AuthCacheCtrlr = 'AuthCacheCtrlr',
- AuthCtrlr = 'AuthCtrlr',
- CHAdeMOCtrlr = 'CHAdeMOCtrlr',
- ClockCtrlr = 'ClockCtrlr',
- CustomizationCtrlr = 'CustomizationCtrlr',
- DeviceDataCtrlr = 'DeviceDataCtrlr',
- DisplayMessageCtrlr = 'DisplayMessageCtrlr',
- ISO15118Ctrlr = 'ISO15118Ctrlr',
- LocalAuthListCtrlr = 'LocalAuthListCtrlr',
- MonitoringCtrlr = 'MonitoringCtrlr',
- OCPPCommCtrlr = 'OCPPCommCtrlr',
- ReservationCtrlr = 'ReservationCtrlr',
- SampledDataCtrlr = 'SampledDataCtrlr',
- SecurityCtrlr = 'SecurityCtrlr',
- SmartChargingCtrlr = 'SmartChargingCtrlr',
- TariffCostCtrlr = 'TariffCostCtrlr',
- TxCtrlr = 'TxCtrlr',
-}
-
enum SetVariableStatusEnumType {
Accepted = 'Accepted',
NotSupportedAttributeType = 'NotSupportedAttributeType',
UnknownVariable = 'UnknownVariable',
}
+export interface ChargingStationType extends JsonObject {
+ firmwareVersion?: string
+ model: string
+ modem?: ModemType
+ serialNumber?: string
+ vendorName: string
+}
+
+export interface ComponentType extends JsonObject {
+ evse?: EVSEType
+ instance?: string
+ name: OCPP20ComponentName | string
+}
+
export interface OCPP20ComponentVariableType extends JsonObject {
component: ComponentType
variable?: VariableType
variable: VariableType
}
-interface ComponentType extends JsonObject {
- evse?: EVSEType
+export interface VariableType extends JsonObject {
instance?: string
- name: OCPP20ComponentName | string
+ name: VariableName
+}
+
+interface ModemType extends JsonObject {
+ iccid?: string
+ imsi?: string
}
type VariableName =
| OCPP20RequiredVariableName
| OCPP20VendorVariableName
| string
-
-interface VariableType extends JsonObject {
- instance?: string
- name: VariableName
-}