Реалізація моніторингу зарядної станції EV через мобільний додаток
Зарядна станція для електромобілів працює за OCPP — Open Charge Point Protocol. OCPP 1.6 — JSON поверх WebSocket, OCPP 2.0.1 — складніша версія з поліпшеною безпекою. Мобільний додаток не говорить з зарядкою напрямку: між ними — Central System (CSMS), який управляє сеансами й зберігає історію. Завдання розробника: інтеграція з CSMS через REST API або WebSocket, плюс опціонально — робота з OCPI для роумінгу між мережами.
Архітектура: OCPP та CSMS
Електромобіль
↓ CCS / CHAdeMO / Type 2
Зарядна станція (Charge Point)
↓ OCPP 1.6/2.0.1 WebSocket
Central System (CSMS) — Everest, ChargePoint, EVCC, кастомна
↓ REST API / WebSocket
Мобільний додаток
Найпоширеніші open-source CSMS: EVCC (німецька, Go, фокус на home charging), Everest (Linux Foundation EV Charging, C++), SteVe (Java, для публічних мереж). Для комерційних — ChargePoint, Driivz, Ampeco.
Моніторинг сеансу зарядки
Ключові дані сеансу: статус коннектора (Available/Occupied/Charging/Faulted), потужність зарядки (кВт), передана енергія (кВт·ч), тривалість, SoC автомобіля (якщо OCPP 2.0.1 та авто підтримує).
WebSocket підписка на оновлення через CSMS API:
class ChargingSessionRepository(
private val wsClient: OkHttpClient,
private val restApi: CsmsApi,
) {
private var webSocket: WebSocket? = null
private val _sessionFlow = MutableStateFlow<ChargingSession?>(null)
val sessionFlow: StateFlow<ChargingSession?> = _sessionFlow.asStateFlow()
fun observeSession(stationId: String, connectorId: Int) {
val request = Request.Builder()
.url("wss://csms.example.com/api/v1/stations/$stationId/events")
.header("Authorization", "Bearer $accessToken")
.build()
webSocket = wsClient.newWebSocket(request, object : WebSocketListener() {
override fun onMessage(webSocket: WebSocket, text: String) {
val event = json.decodeFromString<StationEvent>(text)
when (event.type) {
"MeterValues" -> _sessionFlow.update { current ->
current?.copy(
currentPowerKw = event.payload.activePower,
energyDeliveredKwh = event.payload.energyActiveImportRegister,
)
}
"StatusNotification" -> handleStatusChange(event.payload.status)
"TransactionEvent" -> handleTransactionEvent(event.payload)
}
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
// Експоненціальний backoff для переподключення
scheduleReconnect(stationId, connectorId, t)
}
})
}
}
Дистанційний запуск зарядки
Remote Start Transaction через CSMS API — один з базових сценаріїв. Користувач сканує QR-код на станції (в якому закодовані stationId та connectorId), додаток авторизує транзакцію:
// iOS
func startCharging(stationId: String, connectorId: Int) async throws -> Transaction {
let request = RemoteStartRequest(
connectorId: connectorId,
idTag: currentUser.rfidToken, // токен користувача для авторизації на станції
chargingProfile: ChargingProfile(
chargingProfilePurpose: .txProfile,
chargingSchedule: ChargingSchedule(
chargingRateUnit: .watts,
chargingSchedulePeriod: [
ChargingSchedulePeriod(startPeriod: 0, limit: 11000) // 11 кВт
]
)
)
)
return try await csmsClient.remoteStart(stationId: stationId, request: request)
}
OCPP 1.6 RemoteStartTransaction.conf повертає Accepted або Rejected — це тільки підтвердження, що станція прийняла команду, не що зарядка почалася. Фактичне початок сеансу — окремий StartTransaction.req від станції до CSMS. Статус потрібно відслідковувати через WebSocket або polling.
Карта зарядних станцій
Для публічних мереж — карта з кластеризацією, фільтрація за типом роз'єму (CCS, CHAdeMO, Type 2) та потужністю. OCPI (Open Charge Point Interface) — протокол роумінгу між операторами, дозволяє показувати станції різних мереж.
На Flutter з Google Maps SDK або MapLibre:
Future<List<ChargingStation>> loadNearbyStations(LatLng center) async {
return _ocpiClient.getLocations(
latitude: center.latitude,
longitude: center.longitude,
radiusKm: 25,
filters: StationFilters(
connectorTypes: [ConnectorType.ccs2, ConnectorType.type2],
minPowerKw: 11,
availableOnly: true,
),
);
}
Кластеризація через google_maps_cluster_manager для великих списків — без неї при 500+ точках карта гальмує при зумі.
Оплата та тарифікація
Тарифікація в EV-додатках — складна частина. Станція може тарифікувати по кВт·ч, по часу, з мінімальною сумою сеансу або по комбінованій схемі. OCPI TariffElement описує всі варіанти. Оплата — через Stripe або локальний платіжний шлюз, інтегрований з CSMS.
Розробка додатка для моніторингу та управління зарядними станціями з інтеграцією в існуючий CSMS: 4-6 тижнів. Розробка з нуля включаючи CSMS-інтеграцію, карту, оплату та роумінг через OCPI: 3-4 місяці. Вартість розраховується після аналізу стека та вимог.







