เราจะเขียน OCPP server อย่างไร
ตอนนี้กระแส EV กำลังมา เวลาเราไปตามปั๊มน้ำมันเราก็จะเห็นจุด charge ev กันใช่ไหมครับ เราเคยสงสัยไหมว่า จุด charge ติดต่อกับ server และ mobile app ของเราอย่างไร เค้าสื่อสารผ่าน OCPP protocol กัน เราลองมาทำความเข้าใจกันดีกว่า
บทความที่เกี่ยวข้อง
- ⚡ สร้างระบบ EV Charging ที่ขยายได้ สำหรับผู้ให้บริการ นักพัฒนา และนวัตกร
- 📱 ข้อเสนอระบบ OCPP สำหรับเชื่อมต่อแอป EV กับระบบศูนย์กลาง (Customer Proposal)
- 🔌 เชื่อมต่อแอปมือถือกับระบบ OCPP ด้วย FastAPI
- 🔐 วิธีเชื่อมต่อระบบยืนยันตัวตนของแอป EV เข้ากับระบบ OCPP Central
- 📊 คู่มือเริ่มต้น: แอป EV สื่อสารอย่างไร ติดตามการชาร์จ และคำนวณค่าใช้จ่ายอย่างไร
- 🧠 พัฒนาระบบ OCPP 1.6 ด้วย Flask, WebSocket แบบ Async และ MongoDB
- 🛠️ สร้างระบบ OCPP ตั้งแต่ศูนย์ – คู่มือฉบับสมบูรณ์
OCPP ( Open Charge Point Protocol ) คือมาตรฐานการสื่อสารระหว่าง OCPP client ( charger station ) และ OCPP server ( server ที่มีหน้าที่จัดการและรับส่งข้อมูลระหว่าง OCPP client ) สำหรับคนที่ยังไม่เคยชินกับ server - client architecture จะอธิบายให้เข้าใจง่ายๆ คือ ในระบบจะแบ่งกลุ่มของหน้าที่การทำงานในระบบออกเป็น สองกลุ่ม 1. Client คือกลุ่มของผู้รับบริการจาก server 2. Server คือกลุ่มของผู้ให้บริการในระบบ

กลับมาที่ OCPP server-client ที่เรากำลังสนใจอยู่

OCPP client จะอยู่ใน Charging point โดยผ่าน OCPP protocol ( ตอนนี้ 1.6 และ 2.0.1 )
คนที่เขียน program พอจะนึกภาพออกว่า ถ้าเราจะทำให้การสื่อสารระหว่าง client - server ให้ใกล้เคียงกับ realtime เราจะต้องใช้ web socket https://simplico.net/2022/04/30/web-socket-%E0%B8%84%E0%B8%B7%E0%B8%AD%E0%B8%AD%E0%B8%B0%E0%B9%84%E0%B8%A3/
ให้คิดง่ายๆว่า เราเขียน web socket server - client ที่มี flow การทำงาน และ message ที่แลกเปลี่ยนกันระหว่าง server - client ให้เป็นไปตาม OCPP protocol แล้วเราจะรู้ได้อย่างไรว่าจะต้องเขียนอะไรบ้าง เราก็ไปดูที่
https://openchargealliance.org/my-oca/ocpp/ เราก็เลือก version ที่เราต้องการจะเขียน
ผมขอยกตัวอย่าง sequence diagram ใน pdf นะครับ

Charge Point คือฝั่ง client และ Central System คือฝั่งของ server
Charge Point ส่ง Authorize request มา โดยใน diagram นี้อ้างอิง message ที่ส่งมาใน request คือ idTag ( id ของ Charge point ในระบบของเรา ที่จะต้องไม่ซ้ำกับเครื่องไหนเลย ) พอ central system รับ request ก็จะทำ process หลังบ้านอะไรก็ตาม ( ตรงนี้ขึ้นอยู่กับว่าเราจะเขียนอย่างไร ต้องเข้าใจว่า protocol คือการกำหนดข้อตกลงการสื่อสาร แต่ไม่ได้ระบุว่าระบบที่เราบอกว่ารองรับ protocol นั้นๆ จะมีรายละเอียดการทำงานด้านหลังการสื่อสารนั้นๆ อย่างไร
จาก digram , central system ก็จะส่ง Authorize.conf กลับไปให้ client พร้อมกับ idTagInfo แล้ว idTagInfo เราก็ต้องไปค้นหาดูใน pdf เราก็จะพบว่า

มี data field แบบนี้ สำหรับคนเขียน python ก็ให้คิดว่าเป็น dictionary datatype เราจะสนใจ field ที่ required กันก่อนนะครับ ในที่นี้คือ status เราก็ต้องดูว่าต่อว่า AuthorizationStatus มีค่าอะไรบ้าง

เริ่มพอเห็นแสงสว่างกันแล้วใช่ไหมครับ ในส่วนนี้เราก็ลองคิดง่ายๆ ว่าเราจะ implement เป็น code อย่างไรดี
ผมว่า Accepted, Blocked, … พวกนี้เราก็เขียนเป็น enum ดีกว่า
ผมใช้ project นี้ตั้งต้น https://github.com/mobilityhouse/ocpp เราลองมาดู schema ของ project นี้ดีกว่าว่าเค้าเขียน idTagInfo และ authorizationStatus อย่างไร


พอเราเริ่มเห็น message schema แล้ว ขั้นต่อไปเราจะเขียน logic code อย่างไร

Code ด้านบนเป็น code ที่ผมลองเขียนเอง ลองไปศึกษา https://openchargealliance.org/my-oca/ocpp/ แต่ code ที่สำคัญคือพวก @on(ActionName) decorator ครับ จากในภาพเช่น @on(Action.Authorize) เราก็เขียน function ที่อย่างน้อยต้อง return idTagInfo พร้อมกับ authorize status ในที่นี้ผมใช้ accepted
ถ้าเราเขียนระบบจริงๆ code ส่วนนี้เราควรจะต้องทำอะไรล่ะ อย่างแรกเลยต้องตรวจว่า id_tag นี้อยู่ในระบบของเราหรือไม่ ถ้าใช่ก็ return status = accepted ไปครับ
วันนี้ผมจะพอแค่นี้ก่อนแล้วกันครับ ผมใช้อะไรในการ simulate charging point ครับ ผมใช้ตัวนี้ครับ
https://github.com/vasyas/charger-simulator ลองไปเล่นกันดูนะครับ
Get in Touch with us
Related Posts
- How to Use Local LLM Models in Daily Work
- How to Use Embedding Models with LLMs for Smarter AI Applications
- Smart Vision System for Continuous Material Defect Detection
- Building a Real-Time Defect Detector with Line-Scan + ML (Reusable Playbook)
- How to Read Source Code: Frappe Framework Sample
- Interface-Oriented Design: The Foundation of Clean Architecture
- Understanding Anti-Drone Systems: Architecture, Hardware, and Software
- RTOS vs Linux in Drone Systems: Modern Design, Security, and Rust for Next-Gen Drones
- Why Does Spring Use So Many Annotations? Java vs. Python Web Development Explained
- From Django to Spring Boot: A Practical, Visual Guide for Web Developers
- How to Build Large, Maintainable Python Systems with Clean Architecture: Concepts & Real-World Examples
- Why Test-Driven Development Makes Better Business Sense
- Continuous Delivery for Django on DigitalOcean with GitHub Actions & Docker
- Build a Local Product Recommendation System with LangChain, Ollama, and Open-Source Embeddings
- 2025 Guide: Comparing the Top Mobile App Frameworks (Flutter, React Native, Expo, Ionic, and More)
- Understanding `np.meshgrid()` in NumPy: Why It’s Needed and What Happens When You Swap It
- How to Use PyMeasure for Automated Instrument Control and Lab Experiments
- Supercharge Your Chatbot: Custom API Integration Services for Your Business
- How to Guess an Equation Without Math: Exploring Cat vs. Bird Populations
- How to Build an AI-Resistant Project: Ideas That Thrive on Human Interaction