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 subprotocol | ocpp1.6 — 핸드셰이크 시 Sec-WebSocket-Protocol: ocpp1.6 헤더 필수 |
| 엔드포인트 | wss://<csms-host>/<chargePointIdentity> |
| chargePointIdentity | URL 경로의 마지막 세그먼트로 전달 (예: wss://cp.oasis-arca.com/KR-BNV-0001). CSMS에 사전 등록된 identity여야 함 |
| 전송 보안 | 운영 환경은 TLS(wss) 필수. 사업자 구성에 따라 상호 TLS(mTLS)를 요구할 수 있음 (2.3 참조) |
| Heartbeat 주기 | BootNotification 응답의 interval 값 사용 (기본 300초) |
1.1 연결 수립 순서
- 충전기가
wss://<host>/<identity>로 WebSocket 핸드셰이크(subprotocolocpp1.6). - 연결 직후 충전기가 BootNotification 전송.
- CSMS가 등록된 충전기면
Accepted+interval반환. 미등록이면Rejected. - 충전기는
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 | 방향 | 지원 |
|---|---|---|
| SecurityEventNotification | CP → CSMS | 지원 |
| LogStatusNotification | CP → CSMS | 지원 |
| SignedFirmwareStatusNotification | CP → CSMS | 지원 |
| SignCertificate | CP → CSMS | 지원 (CSR를 CSMS가 처리) |
| ExtendedTriggerMessage | CSMS → CP | 지원 |
| GetLog | CSMS → CP | 지원 |
| InstallCertificate | CSMS → CP | 지원 |
| GetInstalledCertificateIds | CSMS → CP | 지원 |
| DeleteCertificate | CSMS → CP | 지원 |
| CertificateSigned | CSMS → CP | 지원 |
| SignedUpdateFirmware | CSMS → CP | 지원 |
2.4 ChangeConfiguration 커스텀 키 (비표준 확장)
CSMS는 표준 설정 키 외에 아래 커스텀 키를 ChangeConfiguration.req로 전송할 수 있습니다. 충전기는 각 키를 아래 규칙대로 처리해야 합니다.
| key | 설명 / 처리 규칙 | value 예시 |
|---|---|---|
CsmsUrl | CSMS 접속 주소 변경.
| 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. 프로토콜 프로파일 (중요)
| 프로파일 | 대상 | vendorId | DataTransfer 지원 messageId |
|---|---|---|---|
OCPP_16_STANDARD | 표준 충전기 | (검사 안 함) | (비표준 확장 없음) |
OCPP_16_AMANO | 아마노 규격 충전기 | com.bionever | Authorize, GetVariables, SetVariables, GetUnitPrice/getPrice.req, 기타 (규격은 별도 전달) |
OCPP_16_BIONEVER | Bionever 규격 충전기 | com.bionever | SetPaymentInfo, 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 내부 필드로 판단 |
Rejected | payload 파싱 실패 등 처리 거부 |
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)
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
}
}| 필드 | 설명 |
|---|---|
paymentStatus | PAYMENT / PARTIAL_CANCEL / ALL_CANCEL / FINALIZE |
pgType | VAN(CP가 결제·취소 전담, CSMS는 기록만) / PG(CSMS가 부분환불 수행) |
tid | CP 거래 고유 ID. PG 결제 ID(pgTid)와 다른 값이며 별도 보관됩니다. |
connectorId | PAYMENT 시 필수 — 비회원 세션 생성에 사용 |
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"
}
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
connectorId | int | 필수 | 커넥터 번호 (1 이상) |
targetSoC | integer | 필수 | 목표 SoC 0~100. 한도만 설정할 때는 100 권장 |
limitWh | number | 선택 | 충전량 한도 (Wh, 양수) |
limitAmount | number | 선택 | 충전 금액 한도 (원, 양수) |
idTag | string | 선택 | 설정 주체 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 }
]
}
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
connectorId | int | 필수 | 커넥터 번호 (1 이상) |
timestamp | string | 필수 | 동의 확인 시각 (ISO 8601, UTC) — 목록 공통 |
idTag | string | 선택 | 동의 주체 idTag (100자 이내) |
policies | array | 필수 | 정책별 동의 목록 (1건 이상, policyCode 중복 불가) |
policies[].policyCode | string | 필수 | 정책 코드 (50자 이내, 운영팀과 합의된 식별자) |
policies[].consented | boolean | 필수 | 해당 정책 동의 여부 |
응답 (status = "Accepted"). Rejected 조건: timestamp 누락/형식 오류, policies 누락/빈 배열, policyCode 누락·50자 초과·중복, consented 누락.
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"
}
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
managedVersion | string | 선택* | 관리 프로그램 버전 (50자 이내) |
seccVersion | string | 선택* | SECC 펌웨어 버전 (50자 이내) |
* 두 필드 모두 선택이나 최소 한 개는 값이 있어야 합니다. 존재하는 필드만 갱신되며, 누락한 필드의 기존 저장값은 유지됩니다.
응답 (status = "Accepted", data는 빈 객체). Rejected 조건(data.message에 사유): 두 필드 모두 없거나 공백, 값이 50자 초과.
4.2 K-VAS 스마트 제어 충전기 (환경부 배터리 상태정보 수집)
ReportBatteryData, RequestBatteryEncKey / InstallBatteryEncKey, RequestBatteryCertificate / InstallBatteryCertificate)의 상세 규격은 K-VAS 연동 가이드에 별도로 정리되어 있습니다 — 전체 플로우 시퀀스, 메시지별 요청/응답 프레임 샘플, 암호화·오류 처리·검증 시나리오 포함. 해당 메시지는 CSMS에서 충전기의 KVAS 사용이 켜져 있어야 처리됩니다.5. 충전기 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 프로파일별 확장 요약
| 프로파일 | vendorId | DataTransfer messageId | 명령 확장 |
|---|---|---|---|
| STANDARD | (검사 안 함) | (없음) | (없음) |
| Bionever | com.bionever | SetPaymentInfo, 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 객체로 전송하고, 응답의 OCPPstatus뿐 아니라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