Core WebSocket RPC
Quick Start
Get started with simple Client and Server examples.
Client (Charging Station Simulator)
import { OCPPClient, SecurityProfile } from "ocpp-ws-io";
const client = new OCPPClient({
endpoint: "ws://localhost:3000/api/v1/chargers",
identity: "CP001",
protocols: ["ocpp1.6"],
securityProfile: SecurityProfile.NONE,
logging: { prettify: true, exchangeLog: true }, // 🌈 Logs formatted IN/OUT traffic directly
});
// Register a handler — params are auto-typed for OCPP 1.6 Reset
client.handle("Reset", ({ params, protocol }) => {
console.log(`Reset requested (${protocol}):`, params.type);
return { status: "Accepted" };
});
// Connect and send a BootNotification — version-aware, fully typed
await client.connect();
const response = await client.call("ocpp1.6", "BootNotification", {
chargePointVendor: "VendorX",
chargePointModel: "ModelY",
});
console.log("Status:", response.status); // typed: "Accepted" | "Pending" | "Rejected"
// Send a fire-and-forget message safely (won't throw if station disconnects)
const { success } = await client.safeCall("ocpp1.6", "Heartbeat", {});
if (success) client.logger.info("Heartbeat sent successfully!");Server (Central System)
import { OCPPServer } from "ocpp-ws-io";
const server = new OCPPServer({
protocols: ["ocpp1.6", "ocpp2.0.1"],
});
// Optional: Add authentication mapped to a specific endpoint path
server.auth((ctx) => {
// Access connection info
const { query, headers } = ctx.handshake;
const token = query.token;
if (token === "valid-secret") {
// Determine which OCPP protocol to use
// and grant the connection
ctx.accept({ protocol: "ocpp1.6" });
} else {
// Reject unauthorized connections
ctx.reject(401, "Invalid token");
}
});
// Handle new client connections
server.on("client", async (client) => {
console.log(`${client.identity} connected (protocol: ${client.protocol})`);
// Version-aware handlers — params typed per OCPP version
client.handle("ocpp1.6", "BootNotification", ({ params }) => {
console.log("OCPP 1.6 Boot:", params.chargePointVendor);
return {
status: "Accepted",
currentTime: new Date().toISOString(),
interval: 300,
};
});
client.handle("ocpp2.0.1", "BootNotification", ({ params }) => {
console.log("OCPP 2.0.1 Boot:", params.chargingStation.vendorName);
return {
status: "Accepted",
currentTime: new Date().toISOString(),
interval: 300,
};
});
// Version-aware call from server to client
const config = await client.call("ocpp1.6", "GetConfiguration", {
key: ["HeartbeatInterval"],
});
console.log("Config:", config.configurationKey);
client.on("close", () => {
console.log(`${client.identity} disconnected`);
});
});
await server.listen(3000);
console.log("OCPP Server listening on port 3000");Next Steps
For larger CSMS projects, writing all logic inside a single server.on('client') handler isn't scalable. Check out Connection Routing to learn how to compartmentalize distinct domains using the Express-like OCPPRouter!