AOS Simulator

CSMS + Charger Simulator + Test Automation Platform
Autocrypt · Last Updated: 2026-04-01 · v2.0.1

1. Architecture Overview

AOS Simulator는 충전 인프라 테스트를 위한 통합 플랫폼입니다. CSMS(Charging Station Management System), 충전기 시뮬레이터, 테스트 자동화 엔진이 하나의 서버에 통합되어 있습니다. AOS Simulator is an integrated platform for EV charging infrastructure testing. It combines a CSMS (Charging Station Management System), charger simulator, and test automation engine into a single server.

┌─────────────────────────────────────────────────────────┐ │ AOS Simulator │ │ │ │ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ Web UI │ │ REST API │ │ SSE Events │ │ │ │ (SPA) │ │ Express.js │ │ Real-time Push │ │ │ └────┬─────┘ └──────┬───────┘ └────────┬─────────┘ │ │ │ │ │ │ │ ┌────┴───────────────┴────────────────────┴─────────┐ │ │ │ Core Engine │ │ │ │ ┌─────────┐ ┌───────────┐ ┌──────────────────┐ │ │ │ │ │ CSMS │ │ Test │ │ Charger │ │ │ │ │ │ Server │ │ Runner │ │ Client (Sim) │ │ │ │ │ └────┬────┘ └─────┬─────┘ └────────┬─────────┘ │ │ │ └───────┤─────────────┤────────────────┤────────────┘ │ │ │ │ │ │ └──────────┤─────────────┤────────────────┤────────────────┘ │ │ │ ┌──────┴──────┐ ┌───┴────┐ ┌──────┴──────┐ │ Charger/AOS│ │ Redis │ │ CSMS │ │ (WebSocket) │ │ │ │ (Upstream) │ └─────────────┘ └────────┘ └─────────────┘

Core Components

ComponentFile DescriptionDescription
CSMS Serverserver/csms-server.jsWebSocket 서버. 충전기 연결 수신, 프록시 모드, 메시지 전송WebSocket server. Accepts charger connections, proxy mode, message dispatch
OCPP Handlerserver/ocpp-handler.js메시지 처리, 상태 관리, 이벤트 시스템Message processing, state management, event system
Test Runnerserver/test-runner.js테스트 시나리오 실행 엔진, 배치 처리Test scenario execution engine, batch processing
Charger Clientserver/charger-client.js스마트 충전기 시뮬레이터 (CS 역할)Smart charger simulator (acts as CS)
Backend Clientserver/csms-backend-client.jsCSMS 백엔드 API 연동CSMS backend API integration
OCPP Schemasserver/ocpp-schemas.jsOCPP 2.0.1 메시지 템플릿 (29+11 actions)OCPP 2.0.1 message templates (29+11 actions)

2. Operating Modes

시뮬레이터는 3가지 모드로 동작합니다: The simulator operates in 3 modes:

Test용 CSMS API Server

시뮬레이터가 CSMS 역할. 충전기가 직접 연결하여 메시지를 처리.Simulator acts as CSMS. Chargers connect directly and messages are processed locally.

Proxy (AOS)

AOS와 CSMS 사이에 투명 프록시로 동작. 트래픽을 관찰하면서 CSMS 명령 주입(역제어) 가능. 환경변수 또는 Web UI에서 동적으로 Upstream URL을 설정/해제할 수 있습니다.Transparent proxy between AOS and CSMS. Observes traffic while injecting CSMS commands (remote control). Upstream URL can be set/cleared dynamically via environment variable or Web UI.

Standalone CS

시뮬레이터가 충전기(CS) 역할로 CSMS에 직접 연결. AOS 없이 독립 테스트 가능.Simulator connects to CSMS as a charger (CS). Independent testing without AOS.

Mode Comparison

FeatureLocalProxy (AOS)Standalone
AOS 필요Requires AOSNoYesNo
CSMS 필요Requires CSMSNoYesYes
시뮬레이터 역할Simulator RoleCSMSProxy + ObserverCS (Charger)
활성화 조건ActivationProxy OFFProxy OFFUPSTREAM_CSMS_URL 또는 UI에서 Proxy URL 설정or set Proxy URL via UIconnectMode: "standalone"
역제어 (Remote Control)Remote Control가능Yes가능Yes불가 (CS 역할)No (CS role)
Test Step Typessend, waitsend, waitcs_send, wait

Proxy Mode Flow

AOS (Charger) <──WebSocket──> Simulator Proxy <──WebSocket──> CSMS │ Observe & Log Inject CSMS Commands SSE → Web UI

Standalone Mode Flow

Simulator (acting as CS) ──WebSocket──→ CSMS │ cs_send steps: BootNotification → Accepted StatusNotification → {} Heartbeat → currentTime Authorize → idTokenInfo TransactionEvent → ...

OCPP Protocol Versions (1.6 / 2.0.1 Dual Support)

시뮬레이터의 모든 모드(LOCAL/Proxy/Standalone)가 OCPP 1.6 과 2.0.1 을 듀얼 지원합니다. SIM connect 시 protocol 옵션으로 선택 (default 2.0.1). All modes (LOCAL/Proxy/Standalone) support both OCPP 1.6 and 2.0.1. Select via the protocol option when connecting (default 2.0.1).

Action / 항목OCPP 1.6OCPP 2.0.1
Subprotocolocpp1.6ocpp2.0.1
BootNotificationchargePointVendor / chargePointModel / chargePointSerialNumber (flat)chargingStation.{vendorName, model, serialNumber} (nested)
StatusNotificationconnectorId, errorCode, status · 9종 enum (Available/Preparing/Charging/SuspendedEV/SuspendedEVSE/Finishing/Reserved/Unavailable/Faulted)evse{id,connectorId}, connectorStatus · 5종 enum
AuthorizeidTag (string)idToken{idToken,type}
Transaction 시작/종료StartTransaction / StopTransaction (transactionId 정수, CSMS 발급)TransactionEvent (Started/Updated/Ended) (transactionId 문자열, CS 발급)
MeterValues sampledValue{value, measurand, unit} 평탄{value, measurand, unitOfMeasure:{unit}} 중첩
TriggerMessage 가능 액션6종 (Boot/Diag/Firmware/Heartbeat/Meter/Status)14종+
UI 선택 위치Charger Simulator 페이지 → OCPP Version 셀렉트 (선택값은 localStorage 보존)
API 옵션POST /api/sim/connect { ..., protocol: "1.6" | "2.0.1" }
Test scenario 메타"ocppVersion": "1.6" | "2.0.1" (시나리오 JSON 의 top-level 키). v16/ 디렉토리는 default 1.6.
PROXY upstream path 자동 추가: Proxy default URL 또는 per-charger route 의 base URL 에 path 가 비어있으면 subprotocol 별 default 가 자동 추가 (1.6 → /ocpp, 2.0.1 → /ocpp201). path 가 이미 있으면 그대로 + chargerId 만 append. PROXY upstream path auto-append: If proxy upstream URL has no path, default is auto-added per subprotocol (1.6 → /ocpp, 2.0.1 → /ocpp201). If a path is present, it is used as-is + /{chargerId}.

3. Quick Start

Local Development

# Install dependencies
npm install

# Run in local CSMS mode
node server.js

# Run in proxy mode (upstream CSMS required)
UPSTREAM_CSMS_URL=ws://cpos-websocket:8080 node server.js

서버가 시작되면 http://localhost:3000에서 Web UI에 접속할 수 있습니다. Once the server starts, access the Web UI at http://localhost:3000.

테스트 시나리오 실행Run a Test Scenario

# Run a single test scenario
curl -X POST 'http://localhost:3000/api/test/run' \
  -H 'Content-Type: application/json' \
  -d '{"scenarioId":"TC_B_01","chargerId":"CP001"}'

# Response: {"runId":"run-...","status":"passed"}

4. Configuration

Environment Variables

VariableDefaultDescription
PORT3000HTTP/WebSocket 서버 포트HTTP/WebSocket server port
UPSTREAM_CSMS_URL(empty)Upstream CSMS WebSocket URL. 설정 시 Proxy 모드 활성화. Web UI(Chargers 페이지) 또는 POST /api/csms/proxy로 런타임 변경 가능Upstream CSMS WebSocket URL. Enables Proxy mode when set. Can be changed at runtime via Web UI (Chargers page) or POST /api/csms/proxy
UPSTREAM_REDIS_URL(empty)Upstream Redis URL (stale connection 정리용)Upstream Redis URL (for stale connection cleanup)
UPSTREAM_REDIS_KEY_PREFIXcpos:conn:Redis 연결 키 prefixRedis connection key prefix
PENDING_MSG_KEY_PREFIXocpp:message:pending:test:TD:Redis 펜딩 메시지 키 prefixRedis pending message key prefix
BACKEND_RELAY_TIMEOUT8000Backend relay 응답 대기 (ms)Backend relay response timeout (ms)
CSMS_BACKEND_URL(empty)csms-backend REST API URLcsms-backend REST API URL
BASE_PATH/Web UI base path (reverse proxy 환경)Web UI base path (for reverse proxy)

5. Web UI Guide

AOS의 Web UI는 3개 섹션으로 구성됩니다: AOS Web UI consists of 3 sections:

CSMS Section

OCPP 2.0.1 표준 기능을 제공하는 기본 제품 영역입니다. Core product area providing OCPP 2.0.1 standard features.

AOS Testing Section

충전기 시뮬레이션 및 테스트 자동화 도구입니다. Charger simulation and test automation tools.

AOS Demo Section

데모 시연 및 시각화 도구입니다. Demo and visualization tools.

6. Standalone CS Mode

Standalone 모드란? 시뮬레이터가 충전기(CS) 역할로 CSMS에 직접 WebSocket 연결하여, AOS 없이 독립적으로 CSMS를 테스트하는 모드입니다. What is Standalone mode? The simulator connects directly to CSMS as a charger (CS) via WebSocket, enabling independent CSMS testing without AOS.

How It Works

  1. Test Runner가 connectMode: "standalone"으로 시나리오 시작Test Runner starts a scenario with connectMode: "standalone"
  2. 시뮬레이터가 ws://cpos-websocket:8080/ocpp201/{chargerId}에 WebSocket 클라이언트로 연결Simulator connects as WebSocket client to ws://cpos-websocket:8080/ocpp201/{chargerId}
  3. Basic Auth 헤더 자동 첨부 (사전 설정된 비밀번호 사용)Basic Auth header automatically attached (using pre-configured password)
  4. cs_send 스텝으로 CS→CSMS 메시지 전송 (BootNotification, StatusNotification 등)cs_send steps send CS→CSMS messages (BootNotification, StatusNotification, etc.)
  5. CSMS 응답 수신 및 검증Receive and validate CSMS responses
  6. CSMS에서 보내는 명령 (TriggerMessage 등)에 자동 응답Auto-respond to CSMS commands (TriggerMessage, etc.)
  7. 시나리오 완료 후 자동 연결 해제Automatic disconnection after scenario completion

cs_send Step Type

cs_send는 충전기(CS)가 CSMS에 보내는 메시지를 시뮬레이션합니다. cs_send simulates messages sent from charger (CS) to CSMS.

{
  "type": "cs_send",
  "description": "Send BootNotification to CSMS",
  "action": "BootNotification",
  "params": {
    "model": "OCPP-Simulator",
    "vendorName": "Autocrypt",
    "serialNumber": "SIM-001",
    "firmwareVersion": "1.0.0"
  },
  "validate": { "status": "Accepted" },
  "storeAs": "bootResult"
}

Supported CS→CSMS Actions

ActionKey ParamsExpected Response
BootNotificationmodel, vendorName, serialNumber, firmwareVersionstatus, interval, currentTime
Heartbeat(none)currentTime
StatusNotificationstatus, evseId, connectorId{}
AuthorizeidToken, typeidTokenInfo.status
TransactionEventeventType, triggerReason, evseId, idTokenidTokenInfo
MeterValuesevseId, meterValue{}
NotifyReportreportData{}
FirmwareStatusNotificationstatus{}
LogStatusNotificationstatus{}

Standalone Scenario Example

Standalone 시나리오는 connectMode: "standalone"을 지정하고 cs_send 스텝으로 CS→CSMS 메시지를 전송합니다. Standalone scenarios specify connectMode: "standalone" and use cs_send steps to send CS→CSMS messages.

{
  "id": "TC_CUSTOM_01",
  "name": "Custom Standalone Test",
  "category": "Custom",
  "connectMode": "standalone",
  "steps": [
    {
      "type": "cs_send",
      "action": "BootNotification",
      "params": { "model": "Simulator", "vendorName": "Autocrypt" },
      "validate": { "status": "Accepted" }
    },
    {
      "type": "cs_send",
      "action": "StatusNotification",
      "params": { "status": "Available", "evseId": 1 }
    }
  ]
}

7. API Reference - CSMS

GET /api/csms/chargers

연결된 충전기 목록 조회List connected chargers

POST /api/csms/send/:chargerId

CSMS→CS 명령 전송Send CSMS→CS command

// Request Body
{ "action": "TriggerMessage", "params": { "requestedMessage": "BootNotification" } }

// Response
{ "success": true, "response": { "status": "Accepted" } }

POST /api/csms/auth/password/:chargerId

충전기 Basic Auth 비밀번호 설정Set charger Basic Auth password

{ "password": "your-secret" }

POST /api/csms/disconnect/:chargerId

충전기 연결 강제 해제Force disconnect charger

GET /api/csms/proxy

현재 프록시 모드 상태 조회 (default upstream + per-charger routes 포함)Get current proxy mode status (includes default upstream and per-charger routes)

// Response
{
  "proxyMode": true,
  "upstreamUrl": "wss://default-csms-host",
  "routes": [
    { "chargerId": "CP001", "upstreamUrl": "wss://customer-a-csms" },
    { "chargerId": "CP002", "upstreamUrl": "wss://customer-b-csms" }
  ]
}

POST /api/csms/proxy

Default upstream CSMS URL 동적 설정/해제. 매핑되지 않은 충전기는 이 URL로 fallback.Set/clear the default upstream CSMS URL. Unmapped chargers fall back to this URL.

// Set default upstream
{ "upstreamUrl": "wss://default-csms-host" }

// Clear default (mapped chargers still proxy via their routes)
{ "upstreamUrl": "" }

GET /api/csms/proxy/routes

충전기별 라우팅 매핑 전체 조회List all per-charger upstream routes

// Response
{ "routes": [
  { "chargerId": "CP001", "upstreamUrl": "wss://customer-a-csms" }
] }

POST /api/csms/proxy/routes

충전기별 라우팅 추가/갱신. 해당 chargerId가 접속하면 default 대신 이 URL로 forward됨.Add or update a per-charger route. The given chargerId will be forwarded to this URL instead of the default upstream.

// Request
{ "chargerId": "CP001", "upstreamUrl": "wss://customer-a-csms" }

// Response
{ "success": true, "chargerId": "CP001", "upstreamUrl": "wss://customer-a-csms" }

DELETE /api/csms/proxy/routes/:chargerId

특정 chargerId 라우팅 매핑 제거. 이후 default upstream으로 fallback.Remove a per-charger route. The chargerId will fall back to the default upstream.

// Response
{ "success": true, "chargerId": "CP001", "deleted": true }
라우팅 우선순위: 충전기 접속 시 ① per-charger route 매핑이 있으면 그쪽으로 forward → ② 없으면 default upstreamUrl로 fallback → ③ 둘 다 없으면 LOCAL 모드(시뮬레이터 자체 CSMS)로 동작. 변경은 이후 새로 connect하는 충전기에만 적용됩니다 (기존 연결 유지). Routing priority: ① per-charger route → ② default upstreamUrl fallback → ③ LOCAL (simulator's own CSMS) if neither is set. Changes apply only to new connections (existing sessions stay routed as-is).
역제어(Remote Control): 프록시 모드가 켜지면, 이후 연결되는 충전기는 외부 CSMS를 경유하면서 시뮬레이터의 Remote Control 페이지에서 역제어(RequestStartTransaction, Reset 등)가 가능합니다. Standalone(SIM) 모드에서는 충전기 역할이므로 역제어가 불가합니다. Remote Control: When proxy mode is enabled, chargers connecting afterwards are proxied through the external CSMS while remaining controllable from the simulator's Remote Control page (RequestStartTransaction, Reset, etc.). In Standalone (SIM) mode, the simulator acts as a charger so remote control is not available.

8. API Reference - Test Runner

GET /api/test/scenarios

전체 시나리오 목록 조회 (카테고리별 그룹)List all scenarios (grouped by category)

POST /api/test/run

단일 시나리오 실행Run a single scenario

{
  "scenarioId": "TC_B_01",
  "chargerId": "CP001",
  "connectMode": "proxy"  // "proxy" (default) or "standalone"
}

// Response
{ "runId": "run-1770886031263", "status": "passed" }

GET /api/test/run

현재 실행 중인 테스트 상태 조회 (스텝별 결과 포함)Get current test execution status (includes per-step results)

POST /api/test/run/abort

실행 중인 테스트 중단Abort running test

GET /api/test/history

최근 50건 테스트 실행 이력Last 50 test execution history

9. API Reference - Standalone

POST /api/csms/standalone/connect

수동으로 upstream CSMS에 충전기로 연결Manually connect as charger to upstream CSMS

{
  "chargerId": "CP001",
  "password": "your-password",  // optional (uses saved password if not provided)
  "upstreamUrl": "ws://cpos-websocket:8080"  // optional (uses UPSTREAM_CSMS_URL)
}

POST /api/csms/standalone/disconnect

standalone 연결 해제Disconnect standalone connection

{ "chargerId": "CP001" }

POST /api/csms/standalone/send

수동으로 CS→CSMS 메시지 전송Manually send CS→CSMS message

{
  "chargerId": "CP001",
  "action": "BootNotification",
  "params": { "model": "Test", "vendorName": "Autocrypt" }
}

// Response
{ "success": true, "response": { "status": "Accepted", "interval": 300 } }

10. API Reference - Batch

POST /api/test/batch

여러 시나리오 순차 실행 (배치)Run multiple scenarios sequentially (batch)

{
  "scenarioIds": ["TC_B_01", "TC_B_02", "TC_B_03"],
  "chargerId": "CP001",
  "options": {
    "connectMode": "proxy",
    "stopOnFail": false,
    "resetBetween": true
  }
}
Batch Options: resetBetween: true로 설정하면 각 시나리오 사이에 Smart Charger 상태를 초기화합니다. stopOnFail: true로 설정하면 첫 실패 시 배치가 중단됩니다. Batch Options: Set resetBetween: true to reset Smart Charger state between scenarios. Set stopOnFail: true to abort the batch on first failure.

GET /api/test/batch

현재 배치 실행 상태 (시나리오별 결과, 진행률)Current batch execution status (per-scenario results, progress)

POST /api/test/batch/abort

배치 실행 중단Abort batch execution

11. Scenario Format

테스트 시나리오는 test-scenarios/ 디렉토리에 JSON 파일로 저장됩니다. Test scenarios are stored as JSON files in the test-scenarios/ directory.

{
  "id": "TC_X_01",            // Unique ID (filename without .json)
  "name": "Test Case Name",    // Display name
  "category": "X",              // Category letter (A-P)
  "categoryName": "Category",   // Category display name
  "description": "...",         // Description
  "connectMode": "standalone",  // Optional: "proxy" (default) or "standalone"
  "steps": [ ... ]              // Array of step objects
}

12. Step Types

send - CSMS→CS Command

CSMS에서 충전기로 명령 전송. Proxy/Local 모드에서 사용. Send command from CSMS to charger. Used in Proxy/Local modes.

{
  "type": "send",
  "action": "RequestStartTransaction",
  "params": { "idToken": "AABBCCDD", "evseId": 1 },
  "validate": { "status": "Accepted" },
  "viaBackend": true,  // Optional: route through csms-backend API
  "storeAs": "startResult"
}

cs_send - CS→CSMS Message

충전기에서 CSMS로 메시지 전송. Standalone 모드 전용. Send message from charger to CSMS. Standalone mode only.

{
  "type": "cs_send",
  "action": "BootNotification",
  "params": { "model": "Sim", "vendorName": "Test" },
  "validate": { "status": "Accepted" },
  "storeAs": "bootResult"
}

wait - Wait for Message

특정 메시지 수신 대기. 양쪽 모드 모두 사용 가능. Wait for a specific message. Available in all modes.

{
  "type": "wait",
  "match": {
    "action": "StatusNotification",
    "payload": { "connectorStatus": "Available" }  // partial match
  },
  "timeout": 30000,
  "triggerMessage": "StatusNotification",  // Optional: send TriggerMessage to prompt CS
  "triggerDelay": 10000,  // Optional: delay before TriggerMessage (default: 10s proxy, 0s local)
  "storeAs": "statusAvailable"
}

triggerMessage Mechanism

triggerMessage가 설정되면, 먼저 wait 리스너를 등록한 후 TriggerMessage 명령을 CSMS→CS로 발송하여 충전기가 해당 메시지를 보내도록 유도합니다. When triggerMessage is set, a wait listener is registered first, then a TriggerMessage command is sent CSMS→CS to prompt the charger to send the expected message.

  1. wait 리스너 등록 (레이스 컨디션 방지를 위해 먼저 등록)Register wait listener first (to prevent race conditions)
  2. triggerDelay 만큼 대기 (프록시 모드 기본 10초 — 자연 발생 기회 부여)Wait for triggerDelay (default 10s in proxy mode — allows natural occurrence)
  3. TriggerMessage(requestedMessage) CSMS→CS 전송Send TriggerMessage(requestedMessage) CSMS→CS
  4. CS가 해당 메시지 발송 → wait 매칭 → 스텝 성공CS sends the message → wait matches → step passes
배치 테스트 호환: Cold Boot 시나리오(TC_B_02, B_03, B_11~B_13, E_19, E_20)는 triggerMessage: "BootNotification"을 사용합니다. 배치 모드에서 이미 부팅된 충전기도 TriggerMessage를 통해 BootNotification을 발송하므로, 순차 실행 시 타임아웃 없이 정상 동작합니다. 프록시 모드에서는 10초간 자연 부팅을 먼저 기다리므로 실제 충전기의 Cold Boot도 정상 감지됩니다. Batch Compatibility: Cold Boot scenarios (TC_B_02, B_03, B_11~B_13, E_19, E_20) use triggerMessage: "BootNotification". In batch mode, even already-booted chargers will send BootNotification via TriggerMessage, ensuring sequential execution without timeouts. In proxy mode, the 10-second delay allows natural boot detection from real chargers.

delay - Time Delay

{ "type": "delay", "duration": 2000 }

reusable_state - Expand Reusable State

{ "type": "reusable_state", "state": "BootedAndAvailable" }

13. Reusable States

test-scenarios/_reusable-states.json에 정의된 재사용 가능한 스텝 시퀀스: Reusable step sequences defined in test-scenarios/_reusable-states.json:

StateMode Description
BootedProxyBootNotification 대기Wait for BootNotification
AvailableProxyStatusNotification Available 대기Wait for StatusNotification Available
BootedAndAvailableProxyBoot + Available 대기Boot + Available wait
EnergyTransferStartedProxy부팅 → RemoteStart → Transaction 전체 흐름Full boot → RemoteStart → Transaction flow
AuthorizedProxyAuthorize 대기Wait for Authorize
TransactionStartedProxyTransactionEvent Started 대기Wait for TransactionEvent Started
TransactionEndedProxyTransactionEvent Ended 대기Wait for TransactionEvent Ended
EVConnectedProxyStatusNotification Occupied 대기Wait for StatusNotification Occupied
EVDisconnectedProxyStatusNotification Available 대기Wait for StatusNotification Available
ReservedProxyStatusNotification Reserved 대기Wait for StatusNotification Reserved
UnavailableProxyStatusNotification Unavailable 대기Wait for StatusNotification Unavailable

14. Docker Build

# Build for Linux/AMD64 (AKS)
docker build --platform linux/amd64 \
  -t csmsdevacr.azurecr.io/ocpp-simulator:latest .

# Login to ACR (if auth expired)
az acr login --name csmsdevacr

# Push image
docker push csmsdevacr.azurecr.io/ocpp-simulator:latest
Dockerfile 주의: COPY test-scenarios/ ./test-scenarios/가 포함되어 있어야 합니다. 누락 시 테스트 시나리오가 로드되지 않습니다. Dockerfile Note: Must include COPY test-scenarios/ ./test-scenarios/. Missing this will prevent test scenarios from loading.

15. AKS Deployment

# Rolling restart
kubectl rollout restart deployment/ocpp-simulator -n ceer-ocpp

# Check status
kubectl rollout status deployment/ocpp-simulator -n ceer-ocpp

# View logs
kubectl logs deployment/ocpp-simulator -n ceer-ocpp --tail=50

# Verify scenarios loaded
kubectl logs deployment/ocpp-simulator -n ceer-ocpp | grep "Loaded"
# [TEST] Loaded 11 reusable states
# [TEST] Loaded 240 test scenarios (v2.0.1: 231, v1.6: 9)

K8s Environment (k8s-deploy.yaml)

env:
  - name: UPSTREAM_CSMS_URL
    value: "ws://cpos-websocket:8080"
  - name: UPSTREAM_REDIS_URL
    value: "rediss://:PASSWORD@redis-host:6380"
  - name: CSMS_BACKEND_URL
    value: "http://csms-backend.csms.svc.cluster.local:8000"
  - name: BASE_PATH
    value: "/simulator/"

Ingress Configuration

WebSocket 프록시를 위해 다음 Nginx Ingress 어노테이션이 필요합니다: The following Nginx Ingress annotations are required for WebSocket proxy:

annotations:
  nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
  nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
  nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
  nginx.ingress.kubernetes.io/websocket-services: ocpp-simulator

16. Scenario Compatibility

240개 시나리오 (OCPP 2.0.1: 231개 + OCPP 1.6: 9개)의 Smart Charger(로컬 CSMS 모드) 호환성 분류입니다. Total 240 scenarios (OCPP 2.0.1: 231, OCPP 1.6: 9). Smart Charger (Test용 CSMS API Server mode) compatibility breakdown.

대부분 자동 PASS: Smart Charger의 자동 응답 및 follow-up 메시지로 대부분의 AOS 시나리오가 자동 통과합니다 (물리적 한계 시나리오 19개 제외). Most pass automatically: Most AOS scenarios pass automatically via Smart Charger auto-responses and follow-up messages (excluding 19 physical-limitation scenarios).

물리적 한계 시나리오 (19개)Physical Limitation Scenarios (19)

CS 자율 Authorize 필요 (12개)CS-initiated Authorize Required (12)

RFID 카드 태그, PIN 입력, eMAID 등 사용자 물리 행위로 CS가 자발적으로 Authorize를 전송해야 합니다. OCPP 스펙에 TriggerMessage(Authorize)가 없어 CSMS에서 유도할 수 없습니다. CS must autonomously send Authorize via physical user actions (RFID card tap, PIN input, eMAID). OCPP spec lacks TriggerMessage(Authorize), so CSMS cannot trigger it.

IDName LimitationLimitation
TC_C_01EV Driver Auth RFID물리 RFID 카드 태그 필요Physical RFID card tap required
TC_C_02Authorization - Invalid/Unknown물리 RFID 카드 태그 필요Physical RFID card tap required
TC_C_03Authorization - Invalid Token물리 RFID 카드 태그 필요Physical RFID card tap required
TC_C_04Authorization using PIN CodePIN 코드 물리 입력 필요Physical PIN code input required
TC_C_07Authorization using Contract CertificateEV 차량 PLC 통신 (eMAID) 필요EV PLC communication (eMAID) required
TC_C_08Authorization - Expired Token물리 카드 태그 필요Physical card tap required
TC_C_09Authorization - No Credit물리 카드 태그 필요Physical card tap required
TC_C_10Authorization - Not Allowed at Location물리 카드 태그 필요Physical card tap required
TC_C_11Authorization with GroupIdToken물리 카드 태그 필요Physical card tap required
TC_C_12Authorization Concurrent Transactions물리 카드 태그 필요Physical card tap required
TC_C_13Authorization with Local List Fallback물리 카드 태그 필요Physical card tap required
TC_C_14Authorization - Unknown Token물리 카드 태그 필요Physical card tap required

기타 물리적 한계 (7개)Other Physical Limitations (7)

IDName LimitationLimitation
TC_E_06Start Transaction - Id Not AcceptedCS 자율 Authorize 전송 필요 (물리 RFID 카드 태그)CS-initiated Authorize required (physical RFID card tap)
TC_E_07Stop Transaction - LocalCS 자율 트랜잭션 로컬 정지 필요 (사용자 물리 행위)CS-initiated local transaction stop required (physical user action)
TC_E_18Transaction - EVDisconnected StopEV 케이블 물리 분리 시뮬레이션 필요Physical EV cable disconnect simulation required
TC_E_19Transaction PowerLoss전원 차단 후 트랜잭션 복구 (영속성)Transaction recovery after power loss (persistence)
TC_E_21Remote Stop TransactionCS 자율 트랜잭션 시작 필요CS-initiated transaction start required
TC_F_04Remote Start Cable Timeout물리 케이블 미연결 시뮬레이션Physical cable not-connected simulation
TC_G_12StatusNotification Faulted하드웨어 결함 자율 보고Hardware fault autonomous reporting

Smart Charger 자동 동작Smart Charger Auto Behavior

Smart Charger(charger-client.js)는 CSMS 명령에 대해 자동으로 응답하고 후속 메시지를 전송합니다: Smart Charger (charger-client.js) auto-responds to CSMS commands and sends follow-up messages:

CSMS CommandAuto ResponseFollow-up Messages
RequestStartTransactionAcceptedAuthorize → TransactionEvent(Started) → StatusNotification(Occupied)
RequestStopTransactionAcceptedTransactionEvent(Ended) → StatusNotification(Available)
ResetAccepted[TransactionEvent(Ended)] → BootNotification → StatusNotification(Available)
TriggerMessageAccepted / NotImplemented해당 메시지 전송 (Boot, Heartbeat, Status 등)Sends requested message (Boot, Heartbeat, Status, etc.)
ChangeAvailabilityAccepted / ScheduledStatusNotification(Available/Unavailable)
ReserveNowAcceptedStatusNotification(Reserved)
UpdateFirmwareAcceptedFirmwareStatusNotification (Downloading → Installed)

데모 시뮬레이션 Demo Simulation

개요: 실제 충전기 없이 CSMS 전체 기능을 검증할 수 있는 데모 환경입니다. 최대 500대까지 시뮬레이션 가능하며, 기본 20대로 9가지 충전 시나리오를 동시에 실행합니다. Overview: A demo environment to verify all CSMS features without real chargers. Supports up to 500 chargers, default 20 chargers running 9 charging scenarios simultaneously.

구성 Architecture

Demo Dashboard (Web UI) │ │ Start (count=20) ▼ Demo Orchestrator │ │ 20× WebSocket Connect ▼ Charger Client (DEMO-001 ~ DEMO-020) │ │ WSS + Basic Auth ▼ CSMS WebSocket ──▶ CSMS Backend ──▶ PostgreSQL DB

각 충전기는 실제 OCPP 2.0.1 메시지를 전송합니다. CSMS WebSocket 서버를 거쳐 CSMS Backend에 트랜잭션, 미터값이 기록되므로 CSMS Frontend에서 세션 이력을 조회할 수 있습니다. Each charger sends real OCPP 2.0.1 messages. Transactions and meter values are recorded in CSMS Backend via CSMS WebSocket server, so session history is viewable in CSMS Frontend.

충전기 모델 분류 (20대 기준) Charger Model Distribution (20 units)

충전기Chargers모델Model전력Power타입Type
DEMO-001 ~ 008CEER-7kW-AC7 kWAC Type2
DEMO-009 ~ 015CEER-50kW-DC50 kWDC CCS2
DEMO-016 ~ 020CEER-150kW-DC150 kWDC CCS2

9가지 충전 시나리오 9 Charging Scenarios

시나리오Scenario 충전기Chargers 대수Count 설명Description
SC-01 RFIDDEMO-001~0044RFID 카드 태그 인증 후 충전 시작/종료RFID card tap authentication, start/stop charging
SC-02 Plug & ChargeDEMO-005~0073케이블 연결 시 eMAID 자동 인증 (ISO 15118)Auto-auth via eMAID on cable plug (ISO 15118)
SC-03 VIN AutoChargeDEMO-008~0103차량 VIN 기반 자동 인증 및 충전Vehicle VIN-based auto-authentication
SC-04 Remote Start/StopDEMO-011~0133모바일 앱에서 원격 충전 시작/종료Remote charge start/stop from mobile app
SC-05 User StopDEMO-014~0152충전 중 사용자가 직접 종료User manually stops charging mid-session
SC-06 ErrorDEMO-0161충전 중 접지 오류(GroundFault) 감지 → 자동 복구GroundFault detected during charging → auto recovery
SC-07 Remote ResetDEMO-0171CSMS에서 충전기 원격 재부팅Remote reboot charger from CSMS
SC-08 Suspended EVDEMO-018~0192차량 BMS가 충전 일시정지 → 자동 재개EV BMS pauses charging → auto resume
IDLEDEMO-0201충전 요청 없이 대기 상태 유지Standby, no charging activity

시나리오별 OCPP 메시지 흐름 OCPP Message Flow per Scenario

SC-01 RFID

CS ──▶ Authorize (RFID token) CS ──▶ TransactionEvent (Started, meterValue: 0 Wh) CS ──▶ StatusNotification (Occupied) CS ──▶ TransactionEvent (Updated, meterValue: energy Wh) × 3~5 CS ──▶ TransactionEvent (Ended, meterValue: final Wh) CS ──▶ StatusNotification (Available)

SC-06 Error

CS ──▶ Authorize → TransactionEvent (Started) CS ──▶ StatusNotification (Occupied) ... charging ... CS ──▶ StatusNotification (Faulted) ← GroundFault CS ──▶ TransactionEvent (Ended, GroundFault) ... 5s recovery ... CS ──▶ StatusNotification (Available) ← Auto recovery

SC-08 Suspended EV

CS ──▶ Authorize → TransactionEvent (Started) CS ──▶ StatusNotification (Occupied) ... charging ... CS ──▶ StatusNotification (SuspendedEV) ← BMS pause CS ──▶ TransactionEvent (Updated, ChargingStateChanged) ... 5~10s suspended ... CS ──▶ StatusNotification (Occupied) ← Resume CS ──▶ TransactionEvent (Ended) CS ──▶ StatusNotification (Available)

데모 대시보드 사용법 Demo Dashboard Guide

시작하기Getting Started

사이드바 → DemoDemo Dashboard에서 실행합니다. Navigate to DemoDemo Dashboard in the sidebar.

설정Setting기본값Default설명Description
충전기 수Charger Count20시뮬레이션할 충전기 수 (최대 500)Number of chargers to simulate (max 500)
CSMS URLwss://...alb.azure.com충전기가 접속할 CSMS 주소CSMS endpoint for charger connections
Rate Limit20 msg/s초당 최대 메시지 전송 수Max messages per second

Start 버튼 클릭 → 충전기가 배치로 접속 → 시나리오 자동 실행 → Stop으로 중지. Click Start → chargers connect in batches → scenarios run automatically → Stop to halt.

대시보드 구성Dashboard Layout

영역Area내용Content
상단 카운터Top Counters접속 / 충전중 / 대기 / 오류 / 미접속 / 시나리오 사이클 수Connected / Charging / Available / Faulted / Disconnected / Scenario cycles
충전기 그리드Charger Grid타일 색상으로 상태 구분 (클릭 시 상세 정보)Color-coded tiles showing status (click for details)
시나리오 분포Scenario ChartSC-01~08별 충전기 비율 차트Distribution chart by scenario
실시간 이벤트Event Feed충전 시작/종료, 오류 등 실시간 로그Real-time log of charge start/stop, errors
충전기 상세Charger Detail선택한 충전기의 현재 상태, 에너지, SoCSelected charger's status, energy, SoC

Demo API Reference Demo API Reference

POST /api/demo/start

데모 시뮬레이션 시작Start demo simulation

// Request body (all optional, defaults shown)
{
  "count": 20,
  "csmsUrl": "wss://your-csms-host/ocpp201",
  "batchSize": 10,
  "maxMsgPerSec": 20
}

POST /api/demo/stop

데모 중지 및 전체 충전기 접속 해제Stop demo and disconnect all chargers

GET /api/demo/status

현재 데모 상태 (running, 충전기 수, 시나리오 카운트 등)Current demo status (running, charger counts, scenario stats)

GET /api/demo/chargers

전체 충전기 상태 목록 (status, scenario, energy, power, SoC)All charger states (status, scenario, energy, power, SoC)

GET /api/demo/charger/{id}

개별 충전기 상세 상태Individual charger detail

POST /api/demo/remote-start

모바일 앱 Mock에서 원격 충전 시작Remote start from Mobile App Mock

{ "chargerId": "DEMO-011", "userId": "USER-001" }

POST /api/demo/remote-stop

원격 충전 종료Remote stop charging

{ "chargerId": "DEMO-011" }

GET /api/demo/users

생성된 데모 사용자 목록 (userId, name, rfidToken, emaId)Generated demo users list

GET /api/demo/nearby

위치 기반 주변 충전기 검색Location-based nearby charger search

// Query params
?lat=37.4979&lng=127.0276&radius=5

실기 충전기 접속 가이드 Real Charger Connection Guide

대상: Autocrypt CSMS에 OCPP 2.0.1로 충전기를 접속하려는 충전기 제조업체 / 연동 담당자를 위한 가이드입니다. Audience: This guide is for charger manufacturers and integration engineers connecting chargers to Autocrypt CSMS via OCPP 2.0.1.

1. WebSocket 접속 정보 1. WebSocket Connection Details

항목Item Value 설명Description
Endpoint wss://your-csms-host/ocpp/{stationId} {stationId}를 충전기 고유 ID로 교체Replace {stationId} with your charger's unique ID
Protocol ocpp2.0.1 WebSocket Subprotocol 헤더에 설정Set in WebSocket Subprotocol header
TLS WSS (TLS 1.2+) 인증서 검증 필수Certificate validation required
인증Auth Basic Auth (선택optional) 필요 시 사전 협의Coordinate in advance if needed
대체 경로Alt Path /ocpp201/{stationId} 동일하게 동작Works identically

2. 접속 예시 2. Connection Example

WebSocket 클라이언트 (Python)WebSocket Client (Python)

# pip install websockets
import asyncio, websockets, json

async def connect():
    uri = "wss://your-csms-host/ocpp/MY_CHARGER_001"
    async with websockets.connect(uri, subprotocols=["ocpp2.0.1"]) as ws:
        # Send BootNotification
        boot = [2, "msg001", "BootNotification", {
            "chargingStation": {
                "model": "ModelX",
                "vendorName": "YourCompany"
            },
            "reason": "PowerUp"
        }]
        await ws.send(json.dumps(boot))
        response = await ws.recv()
        print("Boot response:", response)

        # Send Heartbeat every 60s
        while True:
            hb = [2, "hb001", "Heartbeat", {}]
            await ws.send(json.dumps(hb))
            await asyncio.sleep(60)

asyncio.run(connect())

필수 메시지 시퀀스Required Message Sequence

Charger CSMS │ │ │─── WebSocket Connect (WSS) ───────▶│ │ │ │─── BootNotification ─────────────▶│ │◀─── BootNotification.conf ────────│ (status: Accepted, interval: 60) │ │ │─── StatusNotification ───────────▶│ (connectorStatus: Available) │◀─── StatusNotification.conf ──────│ │ │ │─── Heartbeat ──────────────────▶│ (every interval seconds) │◀─── Heartbeat.conf ─────────────│ │ │

3. 접속 확인 방법 3. Verifying Connection

충전기가 접속되면 시뮬레이터 웹 UI에서 확인할 수 있습니다. Once connected, you can verify via the simulator web UI.

방법Method 경로Path 설명Description
웹 UIWeb UI 사이드바 → Backend (실기) → 충전기 관리 → "자동 발견" 클릭Sidebar → Backend (실기) → 충전기 관리 → Click "자동 발견" Redis에서 현재 접속 중인 충전기를 자동 검색하여 목록에 등록합니다Auto-discovers connected chargers from Redis and registers them
API POST /api/backend/chargers/discover 접속 중인 전체 충전기 목록 반환Returns list of all currently connected chargers
API GET /api/backend/chargers/{id}/status 개별 충전기 접속 상태 확인Check individual charger connection status

자동 발견 API 응답 예시Auto-discovery API Response Example

// POST /api/backend/chargers/discover
{
  "success": true,
  "chargers": [
    {
      "chargerId": "TD_CHARGER_001",
      "protocol_version": "2.0.1",
      "connected_at": "2026-03-20T04:38:30.626Z",
      "last_heartbeat": "2026-03-20T04:58:37.500Z",
      "pod_name": "cpos-websocket-69896b7988-57v8b"
    }
  ]
}

실기 충전기 역제어 (Remote Control) Real Charger Remote Control

접속이 확인된 충전기에 CSMS → 충전기 방향으로 OCPP 명령을 전송할 수 있습니다. You can send OCPP commands from CSMS to connected chargers.

웹 UI 사용법 Using Web UI

사이드바 → Backend (실기) → 역제어 페이지에서 직접 명령을 전송합니다. Navigate to Backend (실기) → 역제어 in the sidebar to send commands.

지원 명령 목록 Supported Commands

Action 용도Purpose 주요 파라미터Key Parameters
RequestStartTransaction 원격 충전 시작Remote start charging idToken, evseId
RequestStopTransaction 원격 충전 중지Remote stop charging transactionId
Reset 충전기 재부팅Reboot charger type: Immediate / OnIdle
ChangeAvailability 가용 상태 변경Change availability operationalStatus: Operative / Inoperative
TriggerMessage 메시지 요청Request message requestedMessage: StatusNotification, Heartbeat, etc.
UnlockConnector 커넥터 잠금 해제Unlock connector evseId, connectorId
GetVariables 설정값 조회Read configuration component, variable
SetVariables 설정값 변경Write configuration component, variable, attributeValue
GetBaseReport 전체 설정 리포트Full config report reportBase: ConfigurationInventory / FullInventory

역제어 API 사용 예시 Remote Control API Examples

TriggerMessage (StatusNotification 요청)

# 충전기에 StatusNotification 전송 요청
curl -X POST http://20.2.210.133/api/backend/send/TD_CHARGER_001 \
  -H "Content-Type: application/json" \
  -d '{
    "action": "TriggerMessage",
    "params": { "requestedMessage": "StatusNotification" }
  }'

# Response
{ "success": true, "data": "" }

RequestStartTransaction (원격 충전 시작Remote Start)

curl -X POST http://20.2.210.133/api/backend/send/TD_CHARGER_001 \
  -H "Content-Type: application/json" \
  -d '{
    "action": "RequestStartTransaction",
    "params": {
      "idToken": { "idToken": "TESTCARD001", "type": "ISO14443" },
      "remoteStartId": 12345,
      "evseId": 1
    }
  }'

GetVariables (HeartbeatInterval 조회Read HeartbeatInterval)

curl -X POST http://20.2.210.133/api/backend/send/TD_CHARGER_001 \
  -H "Content-Type: application/json" \
  -d '{
    "action": "GetVariables",
    "params": {
      "getVariableData": [{
        "component": { "name": "OCPPCommCtrlr" },
        "variable": { "name": "HeartbeatInterval" }
      }]
    }
  }'

Reset (충전기 재부팅Reboot Charger)

curl -X POST http://20.2.210.133/api/backend/send/TD_CHARGER_001 \
  -H "Content-Type: application/json" \
  -d '{ "action": "Reset", "params": { "type": "Immediate" } }'

Backend API Reference Backend API Reference

실기 충전기 관리를 위한 REST API 목록입니다. REST API reference for real charger management.

충전기 관리Charger Management

GET /api/backend/config

Backend 설정 상태 조회 (CSMS WebSocket, Redis 연결 여부)Check backend configuration status (CSMS WebSocket, Redis connectivity)

POST /api/backend/chargers/discover

Redis에서 접속 중인 충전기 자동 발견 및 등록Auto-discover connected chargers from Redis and register them

// Response
{
  "success": true,
  "chargers": [
    { "chargerId": "TD_CHARGER_001", "connected_at": "...", "last_heartbeat": "..." }
  ]
}

GET /api/backend/chargers

등록된 충전기 목록 + 상태 조회List registered chargers with status

POST /api/backend/chargers

충전기 수동 등록Manually register chargers

// Request body
{ "chargerIds": ["CP001", "CP002"] }

GET /api/backend/chargers/{id}/status

개별 충전기 실시간 상태 조회 (CSMS WebSocket 서버 직접 확인)Check individual charger's real-time status via CSMS WebSocket server

DELETE /api/backend/chargers/{id}

충전기 등록 해제Unregister a charger

역제어 (명령 전송)Remote Control (Send Commands)

POST /api/backend/send/{chargerId}

CSMS WebSocket 서버를 통해 충전기에 OCPP 명령을 전송합니다.Send OCPP commands to charger via CSMS WebSocket server.

// Request body
{
  "action": "TriggerMessage",
  "params": { "requestedMessage": "StatusNotification" }
}

// Success response
{ "success": true, "data": { ... } }

// Error response
{ "success": false, "message": "error description" }
주의: action 값은 OCPP 2.0.1 스펙의 정확한 Action 이름을 사용해야 합니다 (예: RequestStartTransaction, 대소문자 정확히). Note: The action value must match the exact OCPP 2.0.1 Action name (e.g., RequestStartTransaction, case-sensitive).

트러블슈팅Troubleshooting

증상Symptom 원인Cause 해결Solution
자동 발견에서 충전기가 안 보임Charger not found in auto-discovery WebSocket 미접속 또는 접속 끊김WebSocket not connected or disconnected 충전기 로그에서 WSS 접속 상태 확인. wss:// 프로토콜 및 ocpp2.0.1 subprotocol 확인Check WSS connection in charger logs. Verify wss:// protocol and ocpp2.0.1 subprotocol
역제어 명령 실패 (Validation error)Remote control fails (Validation error) OCPP 메시지 포맷 불일치OCPP message format mismatch OCPP 2.0.1 스펙 기준으로 params 필드 확인. 에러 메시지의 required property 참고Verify params fields per OCPP 2.0.1 spec. Check required property in error
BootNotification 응답이 RejectedBootNotification response is Rejected 충전기 ID 미등록 또는 인증 실패Charger ID not registered or auth failure CSMS 관리자에게 충전기 ID 사전 등록 요청Request charger ID pre-registration from CSMS admin
Heartbeat 응답 없음 (타임아웃)No Heartbeat response (timeout) 네트워크 불안정 또는 방화벽Unstable network or firewall WSS 443 포트 아웃바운드 허용 확인. 재접속 로직 구현Verify WSS port 443 outbound allowed. Implement reconnection logic

Autocrypt · AOS Simulator Documentation · Updated 2026-04-01