OCPP WS IO

Type Safety & Validation

Using strict mode validation and generated TypeScript types.

Type Safety

ocpp-ws-io includes auto-generated TypeScript types for all OCPP methods across 1.6, 2.0.1, and 2.1.

Typed Protocols

The protocols field accepts only valid OCPP protocol strings, giving you autocomplete and compile-time safety:

const client = new OCPPClient({
  endpoint: "ws://localhost:3000",
  identity: "CP001",
  protocols: ["ocpp1.6", "ocpp2.0.1"], // ✅ Autocomplete: "ocpp1.6" | "ocpp2.0.1" | "ocpp2.1"
});

// ❌ TypeScript error — "invalid" is not a valid protocol
const bad = new OCPPClient({
  protocols: ["invalid"],
});

Same for the server:

const server = new OCPPServer({
  protocols: ["ocpp1.6", "ocpp2.0.1"], // ✅ Typed
});

Version-Aware handle() and call()

When you call handle() or call() with a known method name, both request params and response types are inferred automatically.

// ✅ Version-aware handle — params typed per version
client.handle("ocpp1.6", "BootNotification", ({ params }) => {
  params.chargePointVendor; // ✅ string (OCPP 1.6 shape)
  return { status: "Accepted", currentTime: "...", interval: 300 };
});

client.handle("ocpp2.0.1", "BootNotification", ({ params }) => {
  params.chargingStation; // ✅ { model, vendorName } (OCPP 2.0.1 shape)
  return { status: "Accepted", currentTime: "...", interval: 300 };
});

// ✅ Version-aware call — params and response typed per version
const res16 = await client.call("ocpp1.6", "BootNotification", {
  chargePointVendor: "VendorX",
  chargePointModel: "ModelY",
});
res16.status; // typed: "Accepted" | "Pending" | "Rejected"

Type Utilities

You can import generated types directly for use in your application:

import type {
  OCPPProtocol, // "ocpp1.6" | "ocpp2.0.1" | "ocpp2.1"
  OCPPProtocolKey, // keyof OCPPMethodMap — extensible
  OCPPMethodMap, // Full method map interface
  AllMethodNames, // All method names for a given protocol
  OCPPRequestType, // Request type for a method
  OCPPResponseType, // Response type for a method
} from "ocpp-ws-io";

// Example: Get request params type for BootNotification in OCPP 1.6
type BootReq = OCPPRequestType<"ocpp1.6", "BootNotification">;
// Result: { chargePointVendor: string; chargePointModel: string; ... }

Extending with Custom Protocols

OCPPMethodMap is a TypeScript interface, which means you can extend it via module augmentation to add typed support for custom/vendor-specific protocols:

// 1. Define your method types
interface MyVendorMethods {
  VendorAction: {
    request: { data: string };
    response: { status: "Accepted" | "Rejected" };
  };
}

// 2. Augment the module
declare module "ocpp-ws-io" {
  interface OCPPMethodMap {
    "vendor-proto": MyVendorMethods;
  }
}

// 3. Now everything is typed:
client.handle("vendor-proto", "VendorAction", ({ params }) => {
  params.data; // ✅ string
  return { status: "Accepted" }; // ✅ typed
});

const res = await client.call("vendor-proto", "VendorAction", {
  data: "hello",
});
res.status; // ✅ "Accepted" | "Rejected"

See the Type Generation page for a full step-by-step guide.

Strict Mode (Schema Validation)

Enable strict mode to validate all inbound and outbound messages against the official OCPP JSON schemas.

const client = new OCPPClient({
  endpoint: "ws://localhost:3000",
  identity: "CP001",
  protocols: ["ocpp1.6"],
  strictMode: true, // validates all calls against built-in schemas
});

// If validation fails, an RPCError is thrown automatically.
// You can also listen for validation failures:
client.on("strictValidationFailure", ({ message, error }) => {
  console.error("Validation failed:", error.message);
});

Partial Strict Mode

You can restrict strict mode to specific subprotocols if you support multiple versions but only want validation for some:

const client = new OCPPClient({
  protocols: ["ocpp1.6", "ocpp2.0.1"],
  strictMode: ["ocpp2.0.1"], // only validate OCPP 2.0.1 messages
});

Custom Validators

You can supply your own validators for custom protocols or modified schemas. These are add-ons to the built-in validators — they don't replace them:

import { createValidator } from "ocpp-ws-io";
import myCustomSchemas from "./my-schemas.json";

const myValidator = createValidator("vendor-proto", myCustomSchemas);

const client = new OCPPClient({
  protocols: ["ocpp1.6", "vendor-proto"],
  strictMode: true,
  strictModeValidators: [myValidator], // adds to built-in validators
});

Tip: Combine custom validators with module augmentation to get both runtime validation and compile-time type safety for your custom protocols.

On this page