Skip to content

Jaypatelbond/ocpp-kotlin

Repository files navigation

OCPP Kotlin

License: MIT API Kotlin

A comprehensive, type-safe OCPP (Open Charge Point Protocol) client library for Kotlin and Android. Built for EV charging station developers who need reliable, production-ready OCPP communication.

✨ Features

  • πŸ”Œ OCPP 2.0.1 - Full support for all 47+ message types across 15 functional blocks
  • πŸ”Œ OCPP 1.6 - Core, Smart Charging, Firmware Management profiles
  • πŸ“± Android-First - Lifecycle-aware components, ViewModel support
  • πŸ”’ Type-Safe - Compile-time safety with Kotlin data classes and enums
  • ⚑ Coroutines - Modern async/await patterns with Kotlin Coroutines and Flow
  • πŸ”„ Auto-Reconnect - Automatic reconnection with exponential backoff
  • πŸ” Secure - Basic auth and certificate-based authentication support

πŸ“Έ Screenshots

Home Charging History Settings
Home Charging History Settings

πŸ“¦ Installation

Add JitPack repository to your project's settings.gradle.kts:

dependencyResolutionManagement {
    repositories {
        maven { url = uri("https://jitpack.io") }
    }
}

Add the dependencies to your module's build.gradle.kts:

dependencies {
    // Core library (required)
    implementation("com.github.Jaypatelbond.ocpp-kotlin:ocpp-core:1.1.0")
    
    // OCPP 2.0.1 support
    implementation("com.github.Jaypatelbond.ocpp-kotlin:ocpp-2.0.1:1.1.0")
    
    // OCPP 1.6 support (optional)
    implementation("com.github.Jaypatelbond.ocpp-kotlin:ocpp-1.6:1.1.0")
    
    // Android extensions (optional, for Android apps)
    implementation("com.github.Jaypatelbond.ocpp-kotlin:ocpp-android:1.1.0")
}

πŸš€ Quick Start

Basic Connection (OCPP 2.0.1)

import com.ocpp.v201.client.Ocpp201Client
import com.ocpp.v201.types.*

// Create client
val client = Ocpp201Client()

// Connect to CSMS
client.connect("ws://csms.example.com/ocpp", "CP001")

// Send BootNotification
val response = client.bootNotification(
    chargingStation = ChargingStationType(
        model = "FastCharger",
        vendorName = "MyCompany"
    ),
    reason = BootReasonEnumType.PowerUp
)

when (response.status) {
    RegistrationStatusEnumType.Accepted -> println("Charger registered!")
    RegistrationStatusEnumType.Pending -> println("Registration pending...")
    RegistrationStatusEnumType.Rejected -> println("Registration rejected")
}

Android ViewModel Integration

class ChargingViewModel : Ocpp201ViewModel() {
    
    fun startCharging(customerId: String) {
        viewModelScope.launch {
            // Authorize customer
            val authResult = authorize(customerId)
            if (authResult.isSuccess) {
                // Start transaction
                startTransaction(
                    transactionId = UUID.randomUUID().toString(),
                    evseId = 1,
                    connectorId = 1,
                    idToken = customerId,
                    timestamp = Instant.now().toString()
                )
            }
        }
    }
}

🧩 Generic API (Version Agnostic)

Write code that works with both OCPP 1.6 and 2.0.1:

// Select adapter
val client: GenericOcppClient = when (config.version) {
    "1.6" -> GenericOcpp16Adapter()
    "2.0.1" -> GenericOcpp201Adapter()
    else -> throw IllegalArgumentException("Unknown version")
}

// Connect & Authenticate (works for both!)
client.connect(url, chargePointId)
val bootParams = client.bootNotification("MyCharger", "MyCompany").getOrThrow()

if (bootParams.accepted) {
    client.startTransaction(connectorId = 1, idToken = "TAG123", meterStart = 0)
}

Complete Transaction Flow

// 1. Boot & Register
client.bootNotification(station, BootReasonEnumType.PowerUp)

// 2. Report Available
client.statusNotification(timestamp, ConnectorStatusEnumType.Available, evseId = 1, connectorId = 1)

// 3. Authorize Customer
val auth = client.authorize(idToken).getOrThrow()

// 4. Start Transaction
client.transactionEvent(TransactionEventEnumType.Started, timestamp, TriggerReasonEnumType.Authorized, seqNo = 0, transactionInfo)

// 5. Charging - Send Meter Values
client.transactionEvent(TransactionEventEnumType.Updated, timestamp, TriggerReasonEnumType.MeterValuePeriodic, seqNo = 1, transactionInfo, meterValue = meterValues)

// 6. Stop Transaction
client.transactionEvent(TransactionEventEnumType.Ended, timestamp, TriggerReasonEnumType.Local, seqNo = 2, transactionInfo)

πŸ“– See Full Transaction Examples β†’

πŸ—οΈ Architecture

OCPP Architecture

πŸ“š Modules

Module Description
ocpp-core Base transport, message parsing, request/response correlation
ocpp-2.0.1 OCPP 2.0.1 messages, types, and type-safe client
ocpp-1.6 OCPP 1.6 messages, types, and type-safe client
ocpp-android Android lifecycle integration, ViewModel base classes
sample-app Demo Android app with charging simulation
ocpp-simulator CSMS simulator for testing

πŸ”Œ Supported OCPP 2.0.1 Messages

Charging Station β†’ CSMS

  • BootNotification, Heartbeat, StatusNotification
  • Authorize, TransactionEvent, MeterValues
  • FirmwareStatusNotification, LogStatusNotification
  • SecurityEventNotification, DataTransfer
  • And more...

CSMS β†’ Charging Station

  • RequestStartTransaction, RequestStopTransaction
  • SetVariables, GetVariables, GetBaseReport
  • SetChargingProfile, ClearChargingProfile
  • TriggerMessage, Reset, UnlockConnector
  • And more...

πŸ§ͺ Testing with Simulator

Run the included OCPP CSMS simulator for testing:

./gradlew :ocpp-simulator:run

Then run the sample app on an Android emulator and connect to:

  • Emulator: ws://10.0.2.2:8080/ocpp
  • Physical device: ws://YOUR_PC_IP:8080/ocpp

🀝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

❓ FAQ

Q: Does this library support different connector types (Type 2, CCS, CHAdeMO)? A: Yes. The library operates at the OCPP protocol level, which is agnostic to the physical connector type. It supports configuring and separately managing multiple connectors/EVSEs using standard OCPP identifiers (connectorId / evseId). The actual physical hardware control is handled by your charger's firmware, not this client library.

About

Type-safe OCPP 1.6 & 2.0.1 client library for Kotlin/Android. Build EV charging station apps with ease.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages