CSMS Integration
OCPP 1.6 연동 가이드
충전기 제조사용
본 문서는 충전기(Charge Point)를 CSMS(Charging Station Management System)에 연동하기 위한 규격을 정의합니다. 충전기 제조사 및 연동 개발자를 대상으로 합니다.

0. 문서 개요

  • 표준 OCPP 1.6 메시지는 OCPP 1.6 규격(OCPP-J 1.6)을 그대로 따르므로 본 문서에서는 지원 여부만 목록화합니다.
  • 비표준 확장(DataTransfer 및 명령 확장)은 CSMS 고유 규격이므로 요청/응답 payload 스키마와 처리 로직을 상세히 기술합니다.

대상 독자: 충전기 펌웨어/연동 개발자  |  전제 지식: OCPP 1.6 규격, WebSocket, JSON, TLS

1. 연결 개요

충전기는 OCPP 1.6 JSON(OCPP-J) 프로토콜로 CSMS에 WebSocket 연결합니다. 연결 시 반드시 아래 규격을 따라야 합니다.

항목값 / 설명
프로토콜OCPP 1.6 (JSON over WebSocket, "OCPP-J")
WebSocket subprotocolocpp1.6 — 핸드셰이크 시 Sec-WebSocket-Protocol: ocpp1.6 헤더 필수
엔드포인트wss://<csms-host>/<chargePointIdentity>
chargePointIdentityURL 경로의 마지막 세그먼트로 전달 (예: wss://cp.oasis-arca.com/KR-BNV-0001). CSMS에 사전 등록된 identity여야 함
전송 보안운영 환경은 TLS(wss) 필수. 사업자 구성에 따라 상호 TLS(mTLS)를 요구할 수 있음 (2.3 참조)
Heartbeat 주기BootNotification 응답의 interval 값 사용 (기본 300초)

1.1 연결 수립 순서

  1. 충전기가 wss://<host>/<identity>로 WebSocket 핸드셰이크(subprotocol ocpp1.6).
  2. 연결 직후 충전기가 BootNotification 전송.
  3. CSMS가 등록된 충전기면 Accepted + interval 반환. 미등록이면 Rejected.
  4. 충전기는 interval 주기로 Heartbeat 전송, 커넥터 상태는 StatusNotification으로 통지.
단일 연결 정책: 하나의 chargePointIdentity에 대해 동시 접속은 1개만 허용됩니다. 동일 identity의 신규 접속이 감지되면 CSMS는 중복 접속을 거부합니다. 재접속 시 이전 소켓이 정리된 뒤 연결하십시오.

1.2 메시지 프레임 (OCPP-J)

모든 메시지는 JSON 배열입니다.

CALL       [2, "<uniqueId>", "<Action>", {<payload>}]
CALLRESULT [3, "<uniqueId>", {<payload>}]
CALLERROR  [4, "<uniqueId>", "<errorCode>", "<description>", {<details>}]
  • uniqueId: 요청/응답을 짝짓는 메시지 ID. 응답은 요청과 동일한 uniqueId 사용.
  • 미지원 Action 수신 시 CSMS는 CALLERROR errorCode = "NotImplemented"를 반환합니다.

예시 — Heartbeat

→ [2, "msg-001", "Heartbeat", {}]
← [3, "msg-001", {"currentTime": "2026-07-06T09:00:00Z"}]

2. 표준 OCPP 1.6 메시지 지원 목록

아래 표준 메시지의 payload 필드·enum·제약 조건은 OCPP 1.6 규격서를 그대로 따릅니다. 충전기는 규격서 기준으로 구현하면 되며 별도 커스터마이징은 없습니다(비표준 확장은 3~4장 참조).

2.1 Charge Point → CSMS (충전기가 전송)

Action지원비고
BootNotification지원미등록 충전기는 Rejected. 승인 시 interval=300 반환
Heartbeat지원currentTime 반환
StatusNotification지원커넥터 상태 반영
Authorize지원idTag 인증
StartTransaction지원충전 시작
StopTransaction지원충전 종료
MeterValues지원계량값 전송
DataTransfer확장비표준 확장 — 4장 참조
FirmwareStatusNotification지원status 값은 표준 enum으로 검증
DiagnosticsStatusNotification지원status 값은 표준 enum으로 검증

2.2 CSMS → Charge Point (CSMS가 전송)

Action지원비고
RemoteStartTransaction지원Bionever 프로파일은 비표준 additionalInfo 필드 추가(별도 규격 전달)
RemoteStopTransaction지원
Reset지원Soft / Hard
UnlockConnector지원
ChangeAvailability지원
ChangeConfiguration지원표준 키 외 커스텀 키 지원 — 2.4 참조
GetConfiguration지원
ClearCache지원
GetDiagnostics지원
UpdateFirmware지원
ReserveNow지원
CancelReservation지원
SendLocalList지원
GetLocalListVersion지원
SetChargingProfile지원
ClearChargingProfile지원
GetCompositeSchedule지원
TriggerMessage지원
DataTransfer확장CSMS가 충전기로도 발신 가능

2.3 보안 확장 (OCPP 1.6 Security Whitepaper, 선택 지원)

mTLS/인증서 기반 사업자 구성에서만 사용합니다.

Action방향지원
SecurityEventNotificationCP → CSMS지원
LogStatusNotificationCP → CSMS지원
SignedFirmwareStatusNotificationCP → CSMS지원
SignCertificateCP → CSMS지원 (CSR를 CSMS가 처리)
ExtendedTriggerMessageCSMS → CP지원
GetLogCSMS → CP지원
InstallCertificateCSMS → CP지원
GetInstalledCertificateIdsCSMS → CP지원
DeleteCertificateCSMS → CP지원
CertificateSignedCSMS → CP지원
SignedUpdateFirmwareCSMS → CP지원

2.4 ChangeConfiguration 커스텀 키 (비표준 확장)

CSMS는 표준 설정 키 외에 아래 커스텀 키ChangeConfiguration.req로 전송할 수 있습니다. 충전기는 각 키를 아래 규칙대로 처리해야 합니다.

key설명 / 처리 규칙value 예시
CsmsUrlCSMS 접속 주소 변경.
  • 충전기는 현재 정상동작하는 CSMS URL을 저장하고 있어야 합니다.
  • 요청된 CsmsUrl이 현재 정상동작하는 CSMS URL과 다른 경우, 다음 충전기 Hard Reset 시 요청된 CsmsUrl로 접속합니다.
  • 요청된 CsmsUrl로 접속 실패(3회 이상 재시도) 시, 정상동작했던 가장 최근의 CSMS URL로 복구합니다.
ws://cp.oasis-arca.com/ocpp
SecurityProfile요청된 security profile은 충전기 Hard Reset 이후 적용됩니다.1
StationName충전소 이름테스트 충전소 1
SecurityProfile의 허용 값은 1, 2, 3입니다. 커스텀 키도 표준 ChangeConfiguration.conf(Accepted / RebootRequired / Rejected / NotSupported)로 응답합니다.

3. 프로토콜 프로파일 (중요)

CSMS는 충전기별로 프로토콜 프로파일(protocol profile)을 지정합니다. DataTransfer 및 일부 명령의 확장 동작은 이 프로파일에 따라 완전히 달라집니다. 프로파일은 CSMS에서 충전기 등록 시 지정되며, 제조사는 자사에 할당된 프로파일 규격을 따라야 합니다.
프로파일대상vendorIdDataTransfer 지원 messageId
OCPP_16_STANDARD표준 충전기(검사 안 함)(비표준 확장 없음)
OCPP_16_AMANO아마노 규격 충전기com.bioneverAuthorize, GetVariables, SetVariables, GetUnitPrice/getPrice.req, 기타 (규격은 별도 전달)
OCPP_16_BIONEVERBionever 규격 충전기com.bioneverSetPaymentInfo, SetChargePreference, SetPrivacyConsent, ReportDeviceVersions (4.1), K-VAS 메시지(ReportBatteryData·세션키·인증서, 4.2)

4. DataTransfer 확장 규격

4.0 공통 규칙

요청 (CP → CSMS) — 표준 OCPP DataTransfer.req 구조:

{
  "vendorId": "<문자열>",
  "messageId": "<문자열>",
  "data": { ... }        // 확장별 JSON. 문자열이 아닌 JSON 객체로 전송
}

응답 (CSMS → CP) — 표준 OCPP DataTransfer.conf 구조:

{
  "status": "Accepted | Rejected | UnknownMessageId | UnknownVendorId",
  "data": { ... }        // 확장별 결과 JSON
}
status의미
Accepted메시지 수신·처리 성공. 비즈니스 결과(인증 성공/실패 등)는 data 내부 필드로 판단
Rejectedpayload 파싱 실패 등 처리 거부
UnknownMessageId해당 프로파일이 지원하지 않는 messageId
UnknownVendorId프로파일이 기대하는 vendorId와 불일치
중요 설계 원칙
  • data 필드는 JSON 문자열이 아니라 JSON 객체로 전송합니다.
  • data가 없거나 null이면 빈 객체 {}로 간주하여 처리합니다.
  • 다수 확장에서 OCPP status는 항상 Accepted이고, 실제 성공/실패는 응답 data 안의 필드(idTokenInfo.status, cardStatus 등)로 전달됩니다. 충전기는 반드시 data를 파싱해 결과를 판단해야 합니다.

4.1 Bionever 프로파일 (vendorId = com.bionever)

프로파일 코드 OCPP_16_BIONEVER. vendorId는 com.bionever (대소문자 무관, 불일치 시 UnknownVendorId). 아래 messageId 외에는 UnknownMessageId로 응답합니다.

4.1.1 SetPaymentInfo — 비회원 결제 통보 (CP → CSMS)

충전기(CP)가 수행한 비회원 결제/취소 결과를 CSMS에 통보합니다. paymentStatus = PAYMENT이면 CSMS가 비회원 세션을 생성하고 발급한 idTag를 응답합니다. 충전기는 이 idTag StartTransaction을 수행합니다. (앱-주도 PG 선결제와 병행 사용)

요청

{
  "vendorId": "com.bionever",
  "messageId": "SetPaymentInfo",
  "data": {
    "paymentStatus": "PAYMENT",
    "pgType": "VAN",
    "tid": "<거래 고유 ID>",
    "amount": "10000",
    "phoneNo": "01012345678",
    "connectorId": 1,
    "mid": "<상점 ID>",
    "authCode": "<카드사 승인번호>",
    "parentTid": "<원거래 tid, 취소 시>",
    "paidAt": "2026-07-08T10:00:00+09:00",
    "responseCode": "0000",
    "responseMsg": "정상",
    "ext1": null,
    "ext2": null
  }
}
필드설명
paymentStatusPAYMENT / PARTIAL_CANCEL / ALL_CANCEL / FINALIZE
pgTypeVAN(CP가 결제·취소 전담, CSMS는 기록만) / PG(CSMS가 부분환불 수행)
tidCP 거래 고유 ID. PG 결제 ID(pgTid)와 다른 값이며 별도 보관됩니다.
connectorIdPAYMENT 시 필수 — 비회원 세션 생성에 사용
amount결제 금액 (원, 정수 문자열)
phoneNo정보제공에 동의한 고객의 전화번호. 동의받지 않은 경우 전송하지 않음(선택 필드)
mid, authCode, paidAt, responseCode, responseMsg, ext1, ext2결제 상세 (기록용)
parentTid취소 시 원거래 tid (미지정 시 tid로 조회)

응답PAYMENT: status = "Accepted", data에 발급된 idTag:

{ "idTag": "G1234567890" }

취소/FINALIZE: status = "Accepted" (data 없음).

취소 처리 주체는 pgType에 따라 갈립니다. VAN은 CP가 결제·취소를 전담하므로 CSMS는 상태·금액만 기록합니다. PG는 CSMS가 GuestPrepaidRefundService로 부분환불을 수행하며, 이때 필요한 tid → pgTid 매핑(별도 API)은 연동 예정(TODO)입니다 — 매핑 전에는 PG 취소가 보류됩니다.

4.1.2 SetChargePreference — 사용자 충전 설정: 목표 SoC + 한도 (CP ↔ CSMS)

SetChargeLimit이 메시지로 대체되어 제거되었습니다(2026-07-19).SetChargeLimit을 전송하면 UnknownMessageId로 응답합니다.

사용자가 충전기 화면에서 설정한 목표 SoC(필수) 충전량/금액 한도(선택)를 전달합니다. 한도에 도달하면 CSMS가 원격 정지를 요청합니다. KVAS 사용 설정과 무관하게 모든 Bionever 충전기에서 처리됩니다.

요청

{
  "vendorId": "com.bionever",
  "messageId": "SetChargePreference",
  "data": {
    "connectorId": 1,
    "targetSoC": 80,
    "limitWh": 30500,
    "limitAmount": 10000,
    "idTag": "CARD-0001"
  }
}
필드타입필수설명
connectorIdint필수커넥터 번호 (1 이상)
targetSoCinteger필수목표 SoC 0~100. 한도만 설정할 때는 100 권장
limitWhnumber선택충전량 한도 (Wh, 양수)
limitAmountnumber선택충전 금액 한도 (원, 양수)
idTagstring선택설정 주체 idTag (100자 이내) — 거래 매칭 검증에 사용

응답 (status = "Accepted", data는 빈 객체). Rejected 조건: connectorId < 1, SoC 범위 밖, limitWh/limitAmount가 양수가 아님, idTag 100자 초과.

한도 반영 시점
  • 충전 시작 전 수신(권장): CSMS가 보관했다가 해당 커넥터의 거래 시작 시 자동 이관합니다. idTag를 보낸 경우 충전 인증 idTag와 일치할 때만 이관되고, 없으면 설정 후 30분 이내 시작된 거래에만 이관됩니다.
  • 충전 중 재수신: 진행 중 거래의 한도를 즉시 갱신합니다.
  • 선결제 등 결제 기반 한도가 이미 있으면 그 한도가 우선하며, 비어 있는 항목만 채워집니다.

CSMS → CP 방향: 원격 충전 시작 시 CSMS가 이 메시지로 목표 SoC(기본 100)를 내려보냅니다. 충전기는 {"status":"Accepted"}로 응답해야 합니다.

4.1.3 SetPrivacyConsent — 개인정보 정책 동의 (CP ↔ CSMS)

개인정보 정책 N건의 동의 여부를 목록으로 전달합니다. 같은 세션에서 같은 policyCode를 다시 보내면 최신 값으로 갱신됩니다. KVAS 사용 설정과 무관하게 처리됩니다.

요청

{
  "vendorId": "com.bionever",
  "messageId": "SetPrivacyConsent",
  "data": {
    "connectorId": 1,
    "timestamp": "2026-07-19T10:30:00.000Z",
    "idTag": "CARD-0001",
    "policies": [
      { "policyCode": "PRIVACY_COLLECT", "consented": true },
      { "policyCode": "THIRD_PARTY_KECO", "consented": true }
    ]
  }
}
필드타입필수설명
connectorIdint필수커넥터 번호 (1 이상)
timestampstring필수동의 확인 시각 (ISO 8601, UTC) — 목록 공통
idTagstring선택동의 주체 idTag (100자 이내)
policiesarray필수정책별 동의 목록 (1건 이상, policyCode 중복 불가)
policies[].policyCodestring필수정책 코드 (50자 이내, 운영팀과 합의된 식별자)
policies[].consentedboolean필수해당 정책 동의 여부

응답 (status = "Accepted"). Rejected 조건: timestamp 누락/형식 오류, policies 누락/빈 배열, policyCode 누락·50자 초과·중복, consented 누락.

전송 게이트: 세션에서 수신된 모든 정책에 동의한 경우에만 CSMS가 배터리 데이터를 환경부로 전송합니다(4.2). 하나라도 미동의면 전송하지 않습니다(수신 자체는 Accepted).
단일 consented Boolean 포맷은 지원하지 않습니다 — policies 목록이 필수입니다(누락 시 Rejected).

4.1.4 ReportDeviceVersions — 장치 버전 보고 (CP → CSMS)

충전기가 자기 장치의 버전 정보를 CSMS에 보고합니다. CSMS는 해당 충전기에 버전을 저장하며, 부팅 후 또는 버전 변경(펌웨어 업데이트 등) 시 전송하는 것을 권장합니다. KVAS 사용 설정과 무관하게 처리됩니다.

요청

{
  "vendorId": "com.bionever",
  "messageId": "ReportDeviceVersions",
  "data": {
    "managedVersion": "MGR-1.2.3",
    "seccVersion": "SECC-0.9.1"
  }
}
필드타입필수설명
managedVersionstring선택*관리 프로그램 버전 (50자 이내)
seccVersionstring선택*SECC 펌웨어 버전 (50자 이내)

* 두 필드 모두 선택이나 최소 한 개는 값이 있어야 합니다. 존재하는 필드만 갱신되며, 누락한 필드의 기존 저장값은 유지됩니다.

응답 (status = "Accepted", data는 빈 객체). Rejected 조건(data.message에 사유): 두 필드 모두 없거나 공백, 값이 50자 초과.

4.2 K-VAS 스마트 제어 충전기 (환경부 배터리 상태정보 수집)

K-VAS 메시지(ReportBatteryData, RequestBatteryEncKey / InstallBatteryEncKey, RequestBatteryCertificate / InstallBatteryCertificate)의 상세 규격은 K-VAS 연동 가이드에 별도로 정리되어 있습니다 — 전체 플로우 시퀀스, 메시지별 요청/응답 프레임 샘플, 암호화·오류 처리·검증 시나리오 포함. 해당 메시지는 CSMS에서 충전기의 KVAS 사용이 켜져 있어야 처리됩니다.

5. 충전기 QR 생성 가이드

충전기 커넥터별로 QR을 발급합니다. 사용자가 QR을 스캔하면 qr.oasis-arca.com(딥링크 라우팅 서비스)이 앱(설치 시) 또는 게스트 웹으로 연결합니다. QR에 넣을 값은 CPO별로 운영팀이 지정해 전달합니다.

5.1 QR URL 형식

https://qr.oasis-arca.com/{CPO}/{cpid}/{connector}
토큰의미예시필수
{CPO}CPO 식별 키(소문자·영숫자·하이픈). 운영팀이 지정해 전달am필수
{cpid}충전기 식별자. OCPP 접속 경로의 chargePointIdentity와 동일하게 맞추길 권장CH001필수
{connector}커넥터 번호(OCPP connectorId)1선택 (생략 시 웹은 1번으로 처리)

각 토큰은 ^[A-Za-z0-9_-]{1,64}$ 문자셋만 허용됩니다(그 외 문자는 무시되고 웹 기본 화면으로 이동). 예시:

https://qr.oasis-arca.com/am/CH001/1   → 게스트 웹  ?charger=CH001&connector=1
https://qr.oasis-arca.com/am/CH001     → 게스트 웹  ?charger=CH001  (connector 생략)
반드시 https:// 로 인코딩하십시오. iOS Universal Link / Android App Link는 http URL로는 앱 자동 실행이 트리거되지 않습니다. (http로 스캔하면 https로 리다이렉트되더라도 앱 링크 검증 단계를 건너뜁니다.)

5.2 QR 코드 생성

  • QR에 인코딩할 내용은 위 URL 문자열 그대로입니다. 별도 인코딩·파라미터 불필요.
  • 커넥터마다 개별 QR을 발급합니다(듀얼 커넥터 충전기는 QR 2개).
  • 오류정정 레벨 M 이상 권장(URL이 짧아 충분). 스티커에는 충전기ID·커넥터 번호를 함께 표기 권장.

생성 예시

# qrencode CLI 예 (커넥터 1번)
qrencode -o CH001-1.png -l M "https://qr.oasis-arca.com/am/CH001/1"

# 커넥터 2번
qrencode -o CH001-2.png -l M "https://qr.oasis-arca.com/am/CH001/2"

5.3 스캔 시 연결 동작 (web / iOS / Android)

QR URL 자체가 Universal Link(iOS) / App Link(Android)입니다. 실행 환경에 따라 아래와 같이 분기합니다.

환경동작
iOS + 해당 CPO 앱 설치OS가 AASA 검증 후 앱을 직접 실행(qr 서버 미도달). 앱이 경로의 cpid/connector를 파싱해 충전 흐름 진입.
Android + 해당 CPO 앱 설치OS가 assetlinks 검증 후 앱을 직접 실행.
앱 미설치 (모바일 브라우저)qr 서버에 도달 → CPO 설정에 따라 분기(아래).
PC / 일반 웹 브라우저qr 서버에 도달 → CPO 설정에 따라 분기(아래).

서버 도달 시 CPO별 분기

CPO 유형결과
앱 없는 CPO (예: amano am — 게스트 전용)게스트 웹으로 302 리다이렉트: https://app-{CPO}.oasis-arca.com/?charger={cpid}&connector={connector} (connector 생략 시 charger만 전달, 웹은 1번으로 처리)
앱 있는 CPO미설치면 스토어로, 카카오/인스타 등 인앱 브라우저면 인터스티셜(앱 열기 시도 → 실패 시 스토어)로 앱 설치를 유도.
[사용자가 QR 스캔]
      │
      ▼
 앱 설치? ──── 예 ──▶ OS가 앱 직접 실행 (Universal/App Link, 서버 미도달)
      │
      아니오 (또는 PC/웹)
      ▼
 qr.oasis-arca.com 서버 도달
      │
      ├─ 앱 없는 CPO(am) ─▶ 302 → https://app-am.oasis-arca.com/?charger={cpid}&connector={connector}
      │
      └─ 앱 있는 CPO ─────▶ 스토어 / 인터스티셜 (앱 설치 유도)
{CPO}·도메인·쿼리 키 등 QR 발급에 필요한 값은 CSMS 운영팀이 CPO별로 지정해 전달합니다(6.3 문의).

6. 부록

6.1 프로파일별 확장 요약

프로파일vendorIdDataTransfer messageId명령 확장
STANDARD(검사 안 함)(없음)(없음)
Bionevercom.bioneverSetPaymentInfo, SetChargePreference, SetPrivacyConsent, ReportDeviceVersions, K-VAS(ReportBatteryData·세션키·인증서)RemoteStartTransaction.additionalInfo, ChangeConfiguration 커스텀 키(2.4)

6.2 구현 체크리스트 (제조사)

  • WebSocket subprotocol ocpp1.6로 접속하고 경로에 chargePointIdentity를 포함한다.
  • 표준 메시지(2장)는 OCPP 1.6 규격서 기준으로 구현한다.
  • CSMS가 할당한 프로파일과 vendorId를 확인한다(3장).
  • DataTransfer는 data를 JSON 객체로 전송하고, 응답의 OCPP status뿐 아니라 data 내부 결과 필드까지 파싱한다(4.0).
  • 프로파일 고유 확장(4.1 Bionever)을 구현한다. 목표 SoC·한도는 SetChargePreference, 동의는 SetPrivacyConsent(정책 목록)를 사용한다 — 구 SetChargeLimit은 제거됨.
  • (K-VAS) 세션키 요청·설치, 배터리 3초 적재·트리거 전송, counter 연속성, 암호화(base64)를 구현한다(4.2).
  • (Bionever) RemoteStartTransaction의 additionalInfo를 파싱해 단가/선결제 한도를 적용한다(규격은 별도 전달).
  • ChangeConfiguration 커스텀 키 CsmsUrl(Hard Reset 시 전환·실패 시 복구)·SecurityProfile(Hard Reset 후 적용)·StationName을 처리한다(2.4).

6.3 문의

연동 프로파일 지정, vendorId 할당, 단가/로밍 정책 등은 CSMS 운영팀에 문의하십시오.

문의: axd@bionever.com

CSMS OCPP 1.6 Integration Guide · 충전기 제조사용