- :white_check_mark: ChangeAvailability
- :white_check_mark: ChangeConfiguration
- :white_check_mark: ClearCache
-- :x: DataTransfer
+- :white_check_mark: DataTransfer
- :white_check_mark: GetConfiguration
- :white_check_mark: Heartbeat
- :white_check_mark: MeterValues
`chargingStations`: ChargingStationData[]
}
-###### Start Transaction
-
-- Request:
- `ProcedureName`: 'startTransaction'
- `PDU`: {
- `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
- `connectorId`: connector id integer,
- `idTag`: RFID tag string
- }
-
-- Response:
- `PDU`: {
- `status`: 'success' | 'failure',
- `hashIdsSucceeded`: charging station unique identifier strings array,
- `hashIdsFailed`: charging station unique identifier strings array (optional),
- `responsesFailed`: failed responses payload array (optional)
- }
-
-###### Stop Transaction
-
-- Request:
- `ProcedureName`: 'stopTransaction'
- `PDU`: {
- `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
- `transactionId`: transaction id integer
- }
-
-- Response:
- `PDU`: {
- `status`: 'success' | 'failure',
- `hashIdsSucceeded`: charging station unique identifier strings array,
- `hashIdsFailed`: charging station unique identifier strings array (optional),
- `responsesFailed`: failed responses payload array (optional)
- }
-
###### Start Charging Station
- Request:
`responsesFailed`: failed responses payload array (optional)
}
-###### Status Notification
+###### OCPP commands trigger
-- Request:
- `ProcedureName`: 'StatusNotification'
- `PDU`: {
- `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
- `connectorId`: connector id integer,
- `errorCode`: connector error code,
- `status`: connector status
- }
+The request PDU is the same as the OCPP command payload with some optional fields added to target the simulated charging stations:
-- Response:
- `PDU`: {
- `status`: 'success' | 'failure',
- `hashIdsSucceeded`: charging station unique identifier strings array,
- `hashIdsFailed`: charging station unique identifier strings array (optional),
- `responsesFailed`: failed responses payload array (optional)
- }
+`PDU`: {
+ `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
+ ...`payload`
+ }
-###### Heartbeat
+Examples:
-- Request:
- `ProcedureName`: 'Heartbeat'
- `PDU`: {
- `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
- }
+- **Start Transaction**
-- Response:
- `PDU`: {
- `status`: 'success' | 'failure',
- `hashIdsSucceeded`: charging station unique identifier strings array,
- `hashIdsFailed`: charging station unique identifier strings array (optional),
- `responsesFailed`: failed responses payload array (optional)
- }
+ - Request:
+ `ProcedureName`: 'startTransaction'
+ `PDU`: {
+ `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
+ `connectorId`: connector id integer,
+ `idTag`: RFID tag string
+ }
+
+ - Response:
+ `PDU`: {
+ `status`: 'success' | 'failure',
+ `hashIdsSucceeded`: charging station unique identifier strings array,
+ `hashIdsFailed`: charging station unique identifier strings array (optional),
+ `responsesFailed`: failed responses payload array (optional)
+ }
+
+- **Stop Transaction**
+
+ - Request:
+ `ProcedureName`: 'stopTransaction'
+ `PDU`: {
+ `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
+ `transactionId`: transaction id integer
+ }
+
+ - Response:
+ `PDU`: {
+ `status`: 'success' | 'failure',
+ `hashIdsSucceeded`: charging station unique identifier strings array,
+ `hashIdsFailed`: charging station unique identifier strings array (optional),
+ `responsesFailed`: failed responses payload array (optional)
+ }
+
+- **Status Notification**
+
+ - Request:
+ `ProcedureName`: 'StatusNotification'
+ `PDU`: {
+ `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
+ `connectorId`: connector id integer,
+ `errorCode`: connector error code,
+ `status`: connector status
+ }
+
+ - Response:
+ `PDU`: {
+ `status`: 'success' | 'failure',
+ `hashIdsSucceeded`: charging station unique identifier strings array,
+ `hashIdsFailed`: charging station unique identifier strings array (optional),
+ `responsesFailed`: failed responses payload array (optional)
+ }
+
+- **Heartbeat**
+
+ - Request:
+ `ProcedureName`: 'Heartbeat'
+ `PDU`: {
+ `hashIds`: charging station unique identifier strings array (optional, default: all charging stations),
+ }
+
+ - Response:
+ `PDU`: {
+ `status`: 'success' | 'failure',
+ `hashIdsSucceeded`: charging station unique identifier strings array,
+ `hashIdsFailed`: charging station unique identifier strings array (optional),
+ `responsesFailed`: failed responses payload array (optional)
+ }
## Support, Feedback, Contributing
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:DataTransferRequest",
+ "title": "DataTransferRequest",
+ "type": "object",
+ "properties": {
+ "vendorId": {
+ "type": "string",
+ "maxLength": 255
+ },
+ "messageId": {
+ "type": "string",
+ "maxLength": 50
+ },
+ "data": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["vendorId"]
+}
--- /dev/null
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "urn:OCPP:1.6:2019:12:DataTransferResponse",
+ "title": "DataTransferResponse",
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "additionalProperties": false,
+ "enum": ["Accepted", "Rejected", "UnknownMessageId", "UnknownVendorId"]
+ },
+ "data": {
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["status"]
+}
import { StandardParametersKey } from '../types/ocpp/Configuration';
import {
type BootNotificationRequest,
+ type DataTransferRequest,
type HeartbeatRequest,
type MeterValuesRequest,
RequestCommand,
} from '../types/ocpp/Requests';
import {
type BootNotificationResponse,
+ type DataTransferResponse,
+ DataTransferStatus,
type HeartbeatResponse,
type MeterValuesResponse,
RegistrationStatus,
| BootNotificationResponse
| StatusNotificationResponse
| HeartbeatResponse
- | MeterValuesResponse;
+ | MeterValuesResponse
+ | DataTransferResponse;
type CommandHandler = (
requestPayload?: BroadcastChannelRequestPayload
});
},
],
+ [
+ BroadcastChannelProcedureName.DATA_TRANSFER,
+ async (requestPayload?: BroadcastChannelRequestPayload) =>
+ this.chargingStation.ocppRequestService.requestHandler<
+ DataTransferRequest,
+ DataTransferResponse
+ >(this.chargingStation, RequestCommand.DATA_TRANSFER, requestPayload),
+ ],
]);
this.chargingStation = chargingStation;
this.onmessage = this.requestHandler.bind(this) as (message: MessageEvent) => void;
return ResponseStatus.SUCCESS;
}
return ResponseStatus.FAILURE;
+ case BroadcastChannelProcedureName.DATA_TRANSFER:
+ if (commandResponse?.status === DataTransferStatus.ACCEPTED) {
+ return ResponseStatus.SUCCESS;
+ }
+ return ResponseStatus.FAILURE;
case BroadcastChannelProcedureName.STATUS_NOTIFICATION:
case BroadcastChannelProcedureName.METER_VALUES:
if (Utils.isEmptyObject(commandResponse) === true) {
import {
DiagnosticsStatusNotificationRequest,
OCPP16BootNotificationRequest,
+ OCPP16DataTransferRequest,
OCPP16HeartbeatRequest,
OCPP16RequestCommand,
OCPP16StatusNotificationRequest,
)
) as JSONSchemaType<OCPP16StopTransactionRequest>,
],
+ [
+ OCPP16RequestCommand.DATA_TRANSFER,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16DataTransferRequest>,
+ ],
]);
this.buildRequestPayload.bind(this);
this.validatePayload.bind(this);
),
}),
} as unknown as Request;
+ case OCPP16RequestCommand.DATA_TRANSFER:
+ return commandParams as unknown as Request;
default:
// OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
throw new OCPPError(
import {
DiagnosticsStatusNotificationResponse,
OCPP16BootNotificationResponse,
+ OCPP16DataTransferResponse,
OCPP16HeartbeatResponse,
OCPP16RegistrationStatus,
OCPP16StatusNotificationResponse,
[OCPP16RequestCommand.STATUS_NOTIFICATION, this.emptyResponseHandler.bind(this)],
[OCPP16RequestCommand.METER_VALUES, this.emptyResponseHandler.bind(this)],
[OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, this.emptyResponseHandler.bind(this)],
+ [OCPP16RequestCommand.DATA_TRANSFER, this.emptyResponseHandler.bind(this)],
]);
this.jsonSchemas = new Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>([
[
)
) as JSONSchemaType<DiagnosticsStatusNotificationResponse>,
],
+ [
+ OCPP16RequestCommand.DATA_TRANSFER,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/DataTransferResponse.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16DataTransferResponse>,
+ ],
]);
this.validatePayload.bind(this);
}
[ProcedureName.STATUS_NOTIFICATION]: BroadcastChannelProcedureName.STATUS_NOTIFICATION,
[ProcedureName.HEARTBEAT]: BroadcastChannelProcedureName.HEARTBEAT,
[ProcedureName.METER_VALUES]: BroadcastChannelProcedureName.METER_VALUES,
+ [ProcedureName.DATA_TRANSFER]: BroadcastChannelProcedureName.DATA_TRANSFER,
};
protected readonly requestHandlers: Map<ProcedureName, ProtocolRequestHandler>;
STATUS_NOTIFICATION = 'statusNotification',
HEARTBEAT = 'heartbeat',
METER_VALUES = 'meterValues',
+ DATA_TRANSFER = 'dataTransfer',
}
export interface RequestPayload extends JsonObject {
STATUS_NOTIFICATION = 'statusNotification',
HEARTBEAT = 'heartbeat',
METER_VALUES = 'meterValues',
+ DATA_TRANSFER = 'dataTransfer',
}
export interface BroadcastChannelRequestPayload extends RequestPayload {
STOP_TRANSACTION = 'StopTransaction',
METER_VALUES = 'MeterValues',
DIAGNOSTICS_STATUS_NOTIFICATION = 'DiagnosticsStatusNotification',
+ DATA_TRANSFER = 'DataTransfer',
}
export type OCPP16HeartbeatRequest = EmptyObject;
requestedMessage: OCPP16MessageTrigger;
connectorId?: number;
}
+
+export interface OCPP16DataTransferRequest extends JsonObject {
+ vendorId: string;
+ messageId?: string;
+ data?: string;
+}
export interface OCPP16TriggerMessageResponse extends JsonObject {
status: OCPP16TriggerMessageStatus;
}
+
+export enum OCPP16DataTransferStatus {
+ ACCEPTED = 'Accepted',
+ REJECTED = 'Rejected',
+ UNKNOWN_MESSAGE_ID = 'UnknownMessageId',
+ UNKNOWN_VENDOR_ID = 'UnknownVendorId',
+}
+
+export interface OCPP16DataTransferResponse extends JsonObject {
+ status: OCPP16DataTransferStatus;
+ data?: string;
+}
import {
OCPP16AvailabilityType,
OCPP16BootNotificationRequest,
+ OCPP16DataTransferRequest,
OCPP16HeartbeatRequest,
OCPP16IncomingRequestCommand,
OCPP16MessageTrigger,
export type MeterValuesRequest = OCPP16MeterValuesRequest;
+export type DataTransferRequest = OCPP16DataTransferRequest;
+
export type IncomingRequestHandler = (
chargingStation: ChargingStation,
commandPayload: JsonType
OCPP16ChargingProfileStatus,
OCPP16ClearChargingProfileStatus,
OCPP16ConfigurationStatus,
+ OCPP16DataTransferResponse,
+ OCPP16DataTransferStatus,
OCPP16HeartbeatResponse,
OCPP16RegistrationStatus,
OCPP16StatusNotificationResponse,
export type MeterValuesResponse = OCPP16MeterValuesResponse;
+export type DataTransferResponse = OCPP16DataTransferResponse;
+
export enum DefaultStatus {
ACCEPTED = 'Accepted',
REJECTED = 'Rejected',
export const TriggerMessageStatus = {
...OCPP16TriggerMessageStatus,
};
+
+export type DataTransferStatus = OCPP16DataTransferStatus;
+
+export const DataTransferStatus = {
+ ...OCPP16DataTransferStatus,
+};