ocpp-ws-io 소개: Node.js용 타입 안전 OCPP 생태계 ⚡
Source: Dev.to

개요
EV(전기차) 충전 산업을 위한 소프트웨어를 만든 적이 있다면, Open Charge Point Protocol (OCPP) 가 충전소와 중앙 시스템(CSMS) 간 통신을 위한 확고한 표준이라는 것을 알 것입니다.
하지만 확장 가능하고 신뢰성 있으며 보안이 보장된 OCPP‑호환 시스템을 구축하는 것은 악명 높게 어렵습니다. 개발자들은 종종 페이로드 형태를 추측하고, JSON 스키마를 수동으로 검증하며, 복잡한 WebSocket 프레이밍을 구현하고, 연결 끊김을 처리하는 데 어려움을 겪습니다.
그래서 저는 ocpp-ws-io 를 만들었습니다 — TypeScript로 처음부터 구축한 타입 안전하고 프로덕션 준비된 OCPP WebSocket RPC 클라이언트 및 서버 생태계로, Node.js용입니다.
🚀 왜 또 다른 OCPP 라이브러리가 필요할까요?
- 🎯 End‑to‑End Type Safety: OCPP 1.6, 2.0.1, 2.1 모든 메서드를 포괄하는 완전 자동 생성 TypeScript 타입을 제공합니다.
BootNotification페이로드가 어떻게 생겼는지 추측할 필요가 없습니다. - 📐 Strict Schema Validation: 비즈니스 로직이 메시지를 처리하기 전에 내장된 JSON‑schema 검증을 수행하는 선택적 엄격 모드.
- 🛜 Router Built‑In: 모듈화되고 깔끔한 코드를 위한 Express/Hono 스타일 라우터를 제공하여 관리가 용이합니다.
- 🔒 Comprehensive Security: OCA Security Profiles 0–3 (Plain WS, Basic Auth, TLS + Basic Auth, Mutual TLS)을 바로 사용할 수 있습니다.
- 🚦 DDoS Protection & Rate Limiting: 스테이션 및 메서드별 소켓 레이어 토큰 버킷 레이트 리밋을 제공합니다.
- 🔁 Resilience: 지수 백오프 자동 재연결, Redis 상태 동기화, 그리고 Idempotency Keys를 통해 재시도 시 정확히 한 번만 메시지가 전달되도록 보장합니다.
- 🧩 Framework‑Agnostic: 독립적으로 사용하거나 Express, Fastify, NestJS, 혹은 커스텀 HTTP 서버에 손쉽게 연결할 수 있습니다.
- 📡 Built for Scale: 멀티 인스턴스 배포를 위한 Redis 어댑터와 Streams를 이용한 내구성 있는 메시지 전달을 지원합니다.
💻 코드가 말보다 크게 말한다
서버 (CSMS)
import { OCPPServer } from "ocpp-ws-io";
const server = new OCPPServer({
protocols: ["ocpp1.6", "ocpp2.0.1"],
logging: { prettify: true, exchangeLog: true, level: "info" }, // Powered by voltlog-io!
});
// Authenticate incoming connections
server.auth((ctx) => {
console.log(`Connection attempt from ${ctx.handshake.identity}`);
ctx.accept({ session: { authorized: true } });
});
server.on("client", (client) => {
console.log(`${client.identity} connected via ${client.protocol}`);
// Type‑safe RPC handler
client.handle("ocpp1.6", "BootNotification", ({ params }) => ({
status: "Accepted",
currentTime: new Date().toISOString(),
interval: 300,
}));
});
await server.listen(3000);
console.log("⚡ OCPP Server running on port 3000");
클라이언트 (충전소 시뮬레이터)
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,
});
// Handle commands from the central system
client.handle("Reset", ({ params }) => {
console.log("CSMS requested a Reset of type:", params.type);
return { status: "Accepted" };
});
await client.connect();
// Send an RPC request and await the result!
const response = await client.call("ocpp1.6", "BootNotification", {
chargePointVendor: "VendorX",
chargePointModel: "ModelY",
});
console.log("Central System response status:", response.status); // Type‑checked!
🛜 Express‑Style 라우팅 및 미들웨어
ocpp-ws-io의 눈에 띄는 기능 중 하나는 강력한 라우팅 및 미들웨어 시스템으로, Express나 Hono와 똑같은 느낌을 주도록 설계되었습니다. 이를 통해 모듈식이고 깔끔하며 관리가 쉬운 CSMS 아키텍처를 구축할 수 있습니다.
HTTP Upgrade 요청(연결 단계)과 들어오고 나가는 OCPP RPC 메시지(메시지 단계)를 가로챌 수 있습니다.
import { OCPPServer, defineMiddleware } from "ocpp-ws-io";
const server = new OCPPServer({ protocols: ["ocpp1.6"] });
// 1️⃣ Connection middleware: block bad IPs or rate‑limit before WebSockets even open!
const rateLimiter = defineMiddleware(async (ctx, next) => {
if (isRateLimited(ctx.handshake.remoteAddress)) {
ctx.reject(429, "Too Many Requests"); // Instantly drops the connection
} else {
await next();
}
});
server.use(rateLimiter);
// 2️⃣ Create dynamic routes with wildcard parameter extraction
const chargerRoute = server.route("/api/v1/chargers/:id");
chargerRoute.on("client", (client) => {
console.log(`Charger connected at endpoint: ${client.handshake.pathname}`);
// 3️⃣ Message middleware: log processing times for every single RPC call
client.use(async (ctx, next) => {
const start = Date.now();
await next();
console.log(`[${ctx.action}] took ${Date.now() - start}ms`);
});
client.handle("BootNotification", ({ params }) => ({
status: "Accepted",
currentTime: new Date().toISOString(),
interval: 300,
}));
});
await server.listen(3000);
보다 고급 라우팅 시나리오에 대해서는 문서를 참고하세요: https://ocpp-ws-io.rohittiwari.me/docs/routing
🪵 일류 구조화 로깅 (voltlog-io)
고성능 WebSocket 환경은 표준 console.log으로 디버깅하기가 악몽과 같습니다. 그래서 ocpp-ws-io는 voltlog‑io 로 구동되는 내장 구조화 JSON 로깅을 포함합니다.
단일 설정 토글만으로 다음을 얻을 수 있습니다:
- 프로덕션용으로 매우 빠른 JSON 로깅.
- 로컬 개발을 위한 지연 시간 메트릭이 포함된 아름답고 색상으로 구분된 출력 (
prettify: true).
Exchange Logs (exchangeLog: true)는 모든 인바운드 ([IN]) 및 아웃바운드 ([OUT]) OCPP 명령을 완벽하게 추적합니다.
⚡ CP-101 → BootNotification [OUT]
✅ CP-101 ← BootNotification [IN] { latencyMs: 45 }
🌐 브라우저 클라이언트
충전기나 프록시와 직접 통신하는 웹 UI, CSMS 대시보드, 혹은 테스트 인터페이스를 구축해야 하나요? 우리는 또한 Browser Client (ocpp-ws-io/browser)를 제공하는데, 이는 의존성이 전혀 없으며 vanilla JS, React, Vue, Svelte 어디서든 완벽히 실행됩니다. 서버에서 제공하는 엄격한 타입 안전성이 브라우저에서도 그대로 사용 가능합니다!
🛠️ ocpp-ws-cli 생태계
훌륭한 개발자 도구가 없는 라이브러리는 전쟁의 절반에 불과합니다. 핵심 ocpp-ws-io 패키지와 함께 ocpp-ws-cli 를 출시했으며, 이는 OCPP 개발자를 위한 궁극적인 CLI입니다.
npx ocpp-ws-cli 로 즉시 사용할 수 있는 이 툴킷은 백엔드를 구축하고 테스트하는 방식을 완전히 바꿔줍니다:
- 🎮
ocpp simulate– 가상 충전소와 인터랙티브 터미널 UI (부팅 시퀀스, 하트비트, 실시간 전압/전류/전력, 플러그인, RFID, 오류 상태). - 📡
ocpp mock– 프런트엔드 개발을 위한 더미MeterValues,StatusNotification,Heartbeat데이터를 스트리밍하는 SSE 모크 서버. - 🚄
ocpp bench– 백분위수 메트릭과 실시간 대시보드를 제공하는 처리량 및 지연 시간 벤치마크 엔진. - 💣
ocpp load-test– 수천 개의 동시 충전소 연결을 시뮬레이션하는 분산 부하 엔진. - 👾
ocpp fuzz– 잘못된 JSON 페이로드를 CSMS에 대량 전송하여 strict‑mode 처리를 테스트하는 프로토콜 혼돈 엔진. - 🔐
ocpp certs– OCA Profile 2 & 3 테스트를 위한 4096‑비트 루트 CA와 서명된 서버/클라이언트.pem인증서를 자동 생성. - 🗂️
ocpp audit– 자동화된 테스트를 실행하고 마크다운 로드맵(audit‑report.md)을 생성하는 보안 마법사. - 📝
ocpp generate– 맞춤형.json스키마를.d.ts선언 라이브러리로 변환하여 100 % 타입 안전성을 제공. - 🧪
ocpp test– 모듈화된 OCTT 준수 테스트 스위트를 서버에 직접 실행.
🌟 참여하기
전기차 인프라 생태계가 빠르게 성장하고 있으며, 견고한 오픈‑소스 도구가 그 성장의 핵심이 될 것입니다. 다음 큰 CSMS 플랫폼을 구축하든, 전기차 충전 앱을 만들든, 혹은 단순히 업계에 대해 배우고 있든, ocpp-ws-io 를 한 번 사용해 보세요!
우리는 피드백, 이슈, 풀 리퀘스트를 적극적으로 기다리고 있습니다. 아래 댓글에 여러분의 의견을 알려 주세요. 즐거운 충전 되세요! ⚡🚗
