### AT Commands for ELM327 Adapter Setup Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt These AT commands are used to configure the ELM327 adapter before sending OBD-II diagnostic commands. They should be run once during initialization. ```APIDOC ## AT Commands — ELM327 Adapter Setup AT commands configure the ELM327 adapter before OBD-II queries. All extend `ATCommand` (which sets `mode = "AT"` and `skipDigitCheck = true`). Run these once during initialization before sending diagnostic commands. ### Initialization Sequence Examples ```kotlin connection.run(ResetAdapterCommand()) // ATZ — full reset connection.run(WarmStartCommand()) // ATWS — warm start (faster than full reset) connection.run(SetEchoCommand(Switcher.OFF)) // ATE0 — disable echo connection.run(SetLineFeedCommand(Switcher.OFF)) // ATL0 — disable line feed connection.run(SetHeadersCommand(Switcher.OFF)) // ATH0 — disable headers connection.run(SetSpacesCommand(Switcher.OFF)) // ATS0 — disable spaces ``` ### Protocol Selection ```kotlin connection.run(SelectProtocolCommand(ObdProtocols.AUTO)) // ObdProtocols: AUTO, SAE_J1850_PWM, SAE_J1850_VPW, ISO_9141_2, // ISO_14230_4_KWP, ISO_14230_4_KWP_FAST, // ISO_15765_4_CAN, ISO_15765_4_CAN_B, ISO_15765_4_CAN_C, // ISO_15765_4_CAN_D, SAE_J1939_CAN ``` ### Adaptive Timing and Timeout ```kotlin connection.run(SetAdaptiveTimingCommand(AdaptiveTimingMode.AUTO_1)) // ATAT1 // AdaptiveTimingMode: OFF, AUTO_1, AUTO_2 connection.run(SetTimeoutCommand(255)) // ATST FF — max timeout ``` ### Info Commands ```kotlin val protocol = connection.run(DescribeProtocolCommand()) // ATDP println(protocol.value) // "AUTO, ISO 15765-4 (CAN 11/500)" val protocolNum = connection.run(DescribeProtocolNumberCommand()) // ATDPN println(protocolNum.value) // "ISO 15765-4 (CAN 11/500)" val ignition = connection.run(IgnitionMonitorCommand()) // ATIGN println(ignition.value) // "ON" val voltage = connection.run(AdapterVoltageCommand()) // ATRV println(voltage.value) // "12.4V" ``` ### Other Action Commands ```kotlin connection.run(SlowInitiationCommand()) // ATSI connection.run(LowPowerModeCommand()) // ATLP connection.run(BufferDumpCommand()) // ATBD connection.run(BypassInitializationCommand()) // ATBI connection.run(ProtocolCloseCommand()) // ATPC ``` ``` -------------------------------- ### Read Live Telemetry Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Example of reading live vehicle data such as RPM and Speed. ```APIDOC ## Reading Live Telemetry ### Description This pattern shows how to continuously read live vehicle data like engine revolutions per minute (RPM) and vehicle speed. ### Example Usage ```kotlin val rpm = obdConnection.run(RPMCommand()) val speed = obdConnection.run(SpeedCommand()) ``` ``` -------------------------------- ### Read VIN with Cache Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Example of reading the Vehicle Identification Number (VIN) and utilizing the caching mechanism. ```APIDOC ## Reading VIN with Caching ### Description Demonstrates how to retrieve the Vehicle Identification Number (VIN) and enable caching for subsequent requests, reducing redundant communication. ### Example Usage ```kotlin val vin = obdConnection.run(VINCommand(), useCache = true) ``` ``` -------------------------------- ### Read and Clear DTC Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Example of reading current Diagnostic Trouble Codes (DTC) and then clearing them. ```APIDOC ## Reading and Clearing DTC ### Description This pattern illustrates how to first retrieve any active Diagnostic Trouble Codes (DTC) and then subsequently clear them from the vehicle's system. ### Example Usage ```kotlin val currentCodes = obdConnection.run(TroubleCodesCommand()) obdConnection.run(ResetTroubleCodesCommand()) ``` ``` -------------------------------- ### Get Vehicle Information and Status Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Retrieve Vehicle Identification Number (VIN), check engine light (MIL) status, and related distances/times. Also includes commands for timing advance, module voltage, DTC count, and available PIDs. ```kotlin import com.github.eltonvs.obd.command.control.* // VIN — cache it to avoid repeated multi-frame reads val vin = connection.run(VINCommand(), useCache = true) println(vin.value) // "1HGCM82633A123456" // MIL (check engine light) state val mil = connection.run(MILOnCommand()) println(mil.value) // "true" or "false" println(mil.formattedValue) // "MIL is ON" or "MIL is OFF" val distanceMilOn = connection.run(DistanceMILOnCommand()) println("${distanceMilOn.value} ${distanceMilOn.unit}") // "120 Km" val timeMilOn = connection.run(TimeSinceMILOnCommand()) println("${timeMilOn.value} ${timeMilOn.unit}") // "45 min" // Timing advance val timingAdvance = connection.run(TimingAdvanceCommand()) println("${timingAdvance.value} ${timingAdvance.unit}") // "14.00 °" // Control module voltage val voltage = connection.run(ModuleVoltageCommand()) println("${voltage.value} ${voltage.unit}") // "12.35 V" // DTC count val dtcNumber = connection.run(DTCNumberCommand()) println("${dtcNumber.value} ${dtcNumber.unit}") // "2 codes" // Distance / time since codes cleared val distCleared = connection.run(DistanceSinceCodesClearedCommand()) println("${distCleared.value} ${distCleared.unit}") // "340 Km" val timeCleared = connection.run(TimeSinceCodesClearedCommand()) println("${timeCleared.value} ${timeCleared.unit}") // "1200 min" // Available PIDs in a range val availablePids = connection.run(AvailablePIDsCommand(AvailablePIDsCommand.AvailablePIDsRanges.PIDS_01_TO_20)) println(availablePids.value) // "04,05,0C,0D,0E,0F,10,11,1F" // Ranges: PIDS_01_TO_20, PIDS_21_TO_40, PIDS_41_TO_60, PIDS_61_TO_80, PIDS_81_TO_A0 ``` -------------------------------- ### Initialization Flow (ELM327) Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Demonstrates the recommended sequence of AT commands to initialize an ELM327 adapter for optimal communication. ```APIDOC ## ELM327 Initialization Commands ### Description This sequence of commands is recommended to configure the ELM327 adapter for reliable communication by disabling echoing, line feeds, and headers, and resetting the adapter. ### Commands 1. **`ResetAdapterCommand()`**: Resets the ELM327 adapter to its default state. 2. **`SetEchoCommand(Switcher.OFF)`**: Disables command echoing. 3. **`SetLineFeedCommand(Switcher.OFF)`**: Disables line feed characters in responses. 4. **`SetHeadersCommand(Switcher.OFF)`**: Disables response headers. 5. **`SelectProtocolCommand(ObdProtocols.AUTO)`** (Optional): Explicitly sets the communication protocol to automatic detection, if needed for specific vehicles. ``` -------------------------------- ### Initialize ELM327 Adapter with AT Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Run these AT commands once during initialization to configure the ELM327 adapter before sending diagnostic commands. Ensure necessary imports are included. ```kotlin import com.github.eltonvs.obd.command.AdaptiveTimingMode import com.github.eltonvs.obd.command.ObdProtocols import com.github.eltonvs.obd.command.Switcher import com.github.eltonvs.obd.command.at.* // Full initialization sequence connection.run(ResetAdapterCommand()) // ATZ — full reset connection.run(WarmStartCommand()) // ATWS — warm start (faster than full reset) connection.run(SetEchoCommand(Switcher.OFF)) // ATE0 — disable echo connection.run(SetLineFeedCommand(Switcher.OFF)) // ATL0 — disable line feed connection.run(SetHeadersCommand(Switcher.OFF)) // ATH0 — disable headers connection.run(SetSpacesCommand(Switcher.OFF)) // ATS0 — disable spaces // Protocol selection connection.run(SelectProtocolCommand(ObdProtocols.AUTO)) // ObdProtocols: AUTO, SAE_J1850_PWM, SAE_J1850_VPW, ISO_9141_2, // ISO_14230_4_KWP, ISO_14230_4_KWP_FAST, // ISO_15765_4_CAN, ISO_15765_4_CAN_B, ISO_15765_4_CAN_C, // ISO_15765_4_CAN_D, SAE_J1939_CAN // Adaptive timing and timeout connection.run(SetAdaptiveTimingCommand(AdaptiveTimingMode.AUTO_1)) // ATAT1 // AdaptiveTimingMode: OFF, AUTO_1, AUTO_2 connection.run(SetTimeoutCommand(255)) // ATST FF — max timeout // Info commands val protocol = connection.run(DescribeProtocolCommand()) // ATDP println(protocol.value) // "AUTO, ISO 15765-4 (CAN 11/500)" val protocolNum = connection.run(DescribeProtocolNumberCommand()) // ATDPN println(protocolNum.value) // "ISO 15765-4 (CAN 11/500)" val ignition = connection.run(IgnitionMonitorCommand()) // ATIGN println(ignition.value) // "ON" val voltage = connection.run(AdapterVoltageCommand()) // ATRV println(voltage.value) // "12.4V" // Other action commands connection.run(SlowInitiationCommand()) // ATSI connection.run(LowPowerModeCommand()) // ATLP connection.run(BufferDumpCommand()) // ATBD connection.run(BypassInitializationCommand()) // ATBI connection.run(ProtocolCloseCommand()) // ATPC ``` -------------------------------- ### Read OBD Data with Kotlin Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/README.md Demonstrates how to establish an OBD connection and execute common commands like resetting the adapter, setting echo, and retrieving RPM, VIN, and trouble codes. Ensure to call `run()` from a background coroutine context. ```kotlin import com.github.eltonvs.obd.command.Switcher import com.github.eltonvs.obd.command.at.ResetAdapterCommand import com.github.eltonvs.obd.command.at.SetEchoCommand import com.github.eltonvs.obd.command.control.TroubleCodesCommand import com.github.eltonvs.obd.command.control.VINCommand import com.github.eltonvs.obd.command.engine.RPMCommand import com.github.eltonvs.obd.connection.ObdDeviceConnection import java.io.InputStream import java.io.OutputStream suspend fun readObd(inputStream: InputStream, outputStream: OutputStream) { val obdConnection = ObdDeviceConnection(inputStream, outputStream) // Typical ELM327 setup obdConnection.run(ResetAdapterCommand()) obdConnection.run(SetEchoCommand(Switcher.OFF)) val rpm = obdConnection.run(RPMCommand()) val vin = obdConnection.run(VINCommand(), useCache = true) val troubleCodes = obdConnection.run(TroubleCodesCommand()) println("RPM: ${rpm.value} ${rpm.unit}") println("VIN: ${vin.value}") println("DTC: ${troubleCodes.value.ifBlank { "none" }}") } ``` -------------------------------- ### Execute OBD Command with Options Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Use the run() method with optional parameters like useCache, delayTime, and maxRetries to control command execution and response handling. Access formatted values combining value and unit. ```kotlin // useCache: true — useful for slow-changing data like VIN val vin = connection.run(VINCommand(), useCache = true) println(vin.value) // "1HGCM82633A123456" // delayTime: useful for adapters that need settling time val coolant = connection.run(EngineCoolantTemperatureCommand(), delayTime = 100) println("${coolant.value} ${coolant.unit}") // "87.0 °C" // maxRetries: reduce for faster failure detection on unsupported PIDs val maf = connection.run(MassAirFlowCommand(), maxRetries = 2) println("${maf.value} ${maf.unit}") // "14.23 g/s" // formattedValue: combines value + unit via command.format() println(rpm.formattedValue) // "850RPM" ``` -------------------------------- ### Initialize ELM327 Adapter Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Perform essential AT commands to configure the ELM327 adapter for communication. This includes resetting the adapter, disabling echo and line feeds, and disabling headers. ```kotlin obdConnection.run(ResetAdapterCommand()) obdConnection.run(SetEchoCommand(Switcher.OFF)) obdConnection.run(SetLineFeedCommand(Switcher.OFF)) obdConnection.run(SetHeadersCommand(Switcher.OFF)) ``` -------------------------------- ### Create a Custom OBD Command in Kotlin Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/README.md Shows how to extend the `ObdCommand` class to create a custom command. Override `tag`, `name`, `mode`, and `pid` for basic functionality. The `handler` can be customized to process raw responses. ```kotlin class CustomCommand : ObdCommand() { // Required override val tag = "CUSTOM_COMMAND" override val name = "Custom Command" override val mode = "01" override val pid = "FF" // Optional override val defaultUnit = "" override val handler = { response: ObdRawResponse -> "Calculated value from ${response.processedValue}" } } ``` -------------------------------- ### Pressure Commands in Kotlin Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Retrieve various pressure readings including barometric, intake manifold, and fuel pressures. All values are returned in kPa. ```kotlin import com.github.eltonvs.obd.command.pressure.* val barometric = connection.run(BarometricPressureCommand()) println("${barometric.value} ${barometric.unit}") // "101 kPa" val intakeManifold = connection.run(IntakeManifoldPressureCommand()) println("${intakeManifold.value} ${intakeManifold.unit}") // "97 kPa" val fuelPressure = connection.run(FuelPressureCommand()) println("${fuelPressure.value} ${fuelPressure.unit}") // "270 kPa" val fuelRailPressure = connection.run(FuelRailPressureCommand()) println("${fuelRailPressure.value} ${fuelRailPressure.unit}") // "35.123 kPa" val fuelRailGauge = connection.run(FuelRailGaugePressureCommand()) println("${fuelRailGauge.value} ${fuelRailGauge.unit}") // "3500 kPa" ``` -------------------------------- ### Add Kotlin OBD API Dependency (Gradle) Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Add the JitPack repository and the library dependency to your build.gradle.kts file. ```kotlin repositories { maven("https://jitpack.io") } dependencies { implementation("com.github.eltonvs:kotlin-obd-api:1.4.1") } ``` -------------------------------- ### Add Kotlin OBD API Dependency (Maven) Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Add the JitPack repository and the library dependency to your Maven pom.xml file. ```xml jitpack.io https://jitpack.io com.github.eltonvs kotlin-obd-api 1.4.1 ``` -------------------------------- ### Retrieve Engine Parameters Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt These commands retrieve engine-related data such as RPM, speed, and throttle position. All commands use Mode 01 and return parsed numeric values with units. ```kotlin import com.github.eltonvs.obd.command.engine.* val rpm = connection.run(RPMCommand()) println("${rpm.value} ${rpm.unit}") // "1500 RPM" val speed = connection.run(SpeedCommand()) println("${speed.value} ${speed.unit}") // "80 Km/h" val throttle = connection.run(ThrottlePositionCommand()) println("${throttle.value} ${throttle.unit}") // "25.5 %" val relativeThrottle = connection.run(RelativeThrottlePositionCommand()) println("${relativeThrottle.value} ${relativeThrottle.unit}") // "12.2 %" val maf = connection.run(MassAirFlowCommand()) println("${maf.value} ${maf.unit}") // "14.23 g/s" val load = connection.run(LoadCommand()) println("${load.value} ${load.unit}") // "42.0 %" val absLoad = connection.run(AbsoluteLoadCommand()) println("${absLoad.value} ${absLoad.unit}") // "38.5 %" val runtime = connection.run(RuntimeCommand()) println(runtime.value) // "00:12:34" (hh:mm:ss) ``` -------------------------------- ### Implement Custom OBD Commands in Kotlin Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Extend the ObdCommand class to create custom commands for vehicle-specific or proprietary PIDs. Override required fields and optionally provide default units, custom handlers, and formatting. ```kotlin import com.github.eltonvs.obd.command.ObdCommand import com.github.eltonvs.obd.command.ObdRawResponse import com.github.eltonvs.obd.command.ObdResponse import com.github.eltonvs.obd.command.bytesToInt // Example: read a custom manufacturer PID class TransmissionTemperatureCommand : ObdCommand() { override val tag = "TRANSMISSION_TEMP" override val name = "Transmission Temperature" override val mode = "01" override val pid = "7C" // hypothetical custom PID override val defaultUnit = "°C" override val handler = { response: ObdRawResponse -> // Apply the standard OBD temperature formula: value - 40 (bytesToInt(response.bufferedValue, bytesToProcess = 1) - 40).toString() } override fun format(response: ObdResponse): String = "Transmission: ${response.value}${response.unit}" } // Usage val transTemp = connection.run(TransmissionTemperatureCommand()) println(transTemp.value) // "78" println(transTemp.unit) // "°C" println(transTemp.formattedValue) // "Transmission: 78°C" ``` -------------------------------- ### Gradle Kotlin DSL Dependency Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/README.md Add this to your root build.gradle.kts file to include the Kotlin OBD API library. ```kotlin repositories { maven("https://jitpack.io") } dependencies { implementation("com.github.eltonvs:kotlin-obd-api:1.4.1") } ``` -------------------------------- ### Select OBD-II Protocol Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Explicitly select the OBD-II protocol for communication with the vehicle. AUTO attempts to automatically detect the protocol. ```kotlin obdConnection.run(SelectProtocolCommand(ObdProtocols.AUTO)) ``` -------------------------------- ### Connect and Read OBD Data Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Connect to an OBD device using ObdDeviceConnection, initialize the adapter, and read engine telemetry like RPM and speed. Access raw response data and timing information. ```kotlin import com.github.eltonvs.obd.command.Switcher import com.github.eltonvs.obd.command.at.* import com.github.eltonvs.obd.command.engine.RPMCommand import com.github.eltonvs.obd.command.engine.SpeedCommand import com.github.eltonvs.obd.connection.ObdDeviceConnection import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.InputStream import java.io.OutputStream suspend fun connectAndRead(inputStream: InputStream, outputStream: OutputStream) { val connection = ObdDeviceConnection(inputStream, outputStream) // ioDispatcher defaults to Dispatchers.IO withContext(Dispatchers.IO) { // ELM327 initialization sequence connection.run(ResetAdapterCommand()) connection.run(SetEchoCommand(Switcher.OFF)) connection.run(SetLineFeedCommand(Switcher.OFF)) connection.run(SetHeadersCommand(Switcher.OFF)) // Read telemetry val rpm = connection.run(RPMCommand()) println("${rpm.value} ${rpm.unit}") // e.g. "850 RPM" val speed = connection.run(SpeedCommand()) println("${speed.value} ${speed.unit}") // e.g. "60 Km/h" // Access raw hex response and elapsed time println("Raw: ${rpm.rawResponse.value}") // "41 0C 0D 5C" println("Processed: ${rpm.rawResponse.processedValue}") // "410C0D5C" println("Elapsed: ${rpm.rawResponse.elapsedTime}ms") // "23ms" println("Buffer: ${rpm.rawResponse.bufferedValue.toList()}") // [65, 12, 13, 92] } } ``` -------------------------------- ### Gradle Groovy Dependency Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/README.md Add this to your root build.gradle file to include the Kotlin OBD API library. ```gradle repositories { maven { url 'https://jitpack.io' } } dependencies { // Kotlin OBD API implementation 'com.github.eltonvs:kotlin-obd-api:1.4.1' } ``` -------------------------------- ### Maven Dependency Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/README.md Add the JitPack repository and the Kotlin OBD API dependency to your Maven project. ```xml jitpack.io https://jitpack.io com.github.eltonvs kotlin-obd-api 1.4.1 ``` -------------------------------- ### Fuel Commands in Kotlin Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Retrieve various fuel-related data such as level, type, consumption rate, ethanol content, and fuel trim. Fuel trim commands require specifying the bank and sensor. ```kotlin import com.github.eltonvs.obd.command.fuel.* val fuelLevel = connection.run(FuelLevelCommand()) println("${fuelLevel.value} ${fuelLevel.unit}") // "72.5 %" val fuelType = connection.run(FuelTypeCommand()) println(fuelType.value) // "Gasoline" // Other values: "Diesel", "Ethanol", "Electric", "Hybrid Gasoline", "Hybrid Diesel", etc. val consumptionRate = connection.run(FuelConsumptionRateCommand()) println("${consumptionRate.value} ${consumptionRate.unit}") // "8.5 L/h" val ethanolLevel = connection.run(EthanolLevelCommand()) println("${ethanolLevel.value} ${ethanolLevel.unit}") // "10.0 %" // Fuel trim — select bank with FuelTrimBank enum val shortTerm1 = connection.run(FuelTrimCommand(FuelTrimCommand.FuelTrimBank.SHORT_TERM_BANK_1)) println("${shortTerm1.value} ${shortTerm1.unit}") // "-3.1 %" val longTerm2 = connection.run(FuelTrimCommand(FuelTrimCommand.FuelTrimBank.LONG_TERM_BANK_2)) println("${longTerm2.value} ${longTerm2.unit}") // "1.5 %" // FuelTrimBank values: SHORT_TERM_BANK_1, SHORT_TERM_BANK_2, LONG_TERM_BANK_1, LONG_TERM_BANK_2 // Commanded equivalence ratio val commandedRatio = connection.run(CommandedEquivalenceRatioCommand()) println("${commandedRatio.value} ${commandedRatio.unit}") // "1.00 F/A" // Per-sensor fuel-air equivalence ratio val o2Ratio = connection.run(FuelAirEquivalenceRatioCommand(FuelAirEquivalenceRatioCommand.OxygenSensor.OXYGEN_SENSOR_1)) println("${o2Ratio.value} ${o2Ratio.unit}") // "0.98 F/A" // OxygenSensor values: OXYGEN_SENSOR_1 through OXYGEN_SENSOR_8 ``` -------------------------------- ### Pressure Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Commands for barometric, intake manifold, fuel line, fuel rail, and fuel rail gauge pressures. All values are returned in kPa. ```APIDOC ## Pressure Commands Pressure commands cover barometric, intake manifold, fuel line, fuel rail, and fuel rail gauge pressures. All values are returned in kPa. ```kotlin import com.github.eltonvs.obd.command.pressure.* val barometric = connection.run(BarometricPressureCommand()) println("${barometric.value} ${barometric.unit}") // "101 kPa" val intakeManifold = connection.run(IntakeManifoldPressureCommand()) println("${intakeManifold.value} ${intakeManifold.unit}") // "97 kPa" val fuelPressure = connection.run(FuelPressureCommand()) println("${fuelPressure.value} ${fuelPressure.unit}") // "270 kPa" val fuelRailPressure = connection.run(FuelRailPressureCommand()) println("${fuelRailPressure.value} ${fuelRailPressure.unit}") // "35.123 kPa" val fuelRailGauge = connection.run(FuelRailGaugePressureCommand()) println("${fuelRailGauge.value} ${fuelRailGauge.unit}") // "3500 kPa" ``` ``` -------------------------------- ### Monitor Readiness Status Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Parse OBD monitor readiness bitmaps into a structured `SensorStatusData` object. This provides details on MIL status, DTC count, and individual monitor availability/completion. ```kotlin import com.github.eltonvs.obd.command.control.* import com.github.eltonvs.obd.command.Monitors val monitorCmd = MonitorStatusSinceCodesClearedCommand() connection.run(monitorCmd) val status = monitorCmd.data if (status != null) { println("MIL on: ${status.milOn}") // true/false println("DTC count: ${status.dtcCount}") // 2 println("Spark ignition: ${status.isSpark}") // true for petrol, false for diesel // Per-monitor availability and completion status.items.forEach { (monitor, sensorStatus) -> println("${monitor.name}: available=${sensorStatus.available}, complete=${sensorStatus.complete}") } // Output example: // MISFIRE: available=true, complete=true // CATALYST: available=true, complete=false // OXYGEN_SENSOR: available=true, complete=true } // Monitors enum covers: MISFIRE, FUEL_SYSTEM, COMPREHENSIVE_COMPONENT, // CATALYST, HEATED_CATALYST, EVAPORATIVE_SYSTEM, SECONDARY_AIR_SYSTEM, // AC_REFRIGERANT, OXYGEN_SENSOR, OXYGEN_SENSOR_HEATER, EGR_SYSTEM (spark), // NMHC_CATALYST, NOX_SCR_MONITOR, BOOST_PRESSURE, EXHAUST_GAS_SENSOR, // PM_FILTER, EGR_VVT_SYSTEM (compression) ``` -------------------------------- ### Retrieve Temperature Data Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt These commands retrieve engine and ambient temperature readings. All values are returned in degrees Celsius with a -40°C offset applied as per OBD-II specifications. ```kotlin import com.github.eltonvs.obd.command.temperature.* val coolant = connection.run(EngineCoolantTemperatureCommand()) println("${coolant.value} ${coolant.unit}") // "90.0 °C" val intakeAir = connection.run(AirIntakeTemperatureCommand()) println("${intakeAir.value} ${intakeAir.unit}") // "35.0 °C" val ambientAir = connection.run(AmbientAirTemperatureCommand()) println("${ambientAir.value} ${ambientAir.unit}") // "22.0 °C" val oilTemp = connection.run(OilTemperatureCommand()) println("${oilTemp.value} ${oilTemp.unit}") // "95.0 °C" ``` -------------------------------- ### Execute OBD-II Command Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Use this suspend function to run OBD-II commands. It supports caching, custom delays, and retries. Commands are serialized per connection instance. ```kotlin suspend fun run( command: ObdCommand, useCache: Boolean = false, delayTime: Long = 0, maxRetries: Int = 5, ): ObdResponse ``` -------------------------------- ### Handle OBD API Errors in Kotlin Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Safely read data from an OBD adapter by catching specific exceptions like NoDataException, UnableToConnectException, and BadResponseException. Ensure proper error handling for unsupported PIDs, connection issues, and unrecognized commands. ```kotlin import com.github.eltonvs.obd.command.* import com.github.eltonvs.obd.command.engine.RPMCommand import kotlinx.coroutines.delay suspend fun safeRead(connection: com.github.eltonvs.obd.connection.ObdDeviceConnection) { try { val rpm = connection.run(RPMCommand()) println("RPM: ${rpm.value}") } catch (e: NoDataException) { // Adapter replied "NO DATA" — PID may be unsupported or engine off println("No data: $e") } catch (e: UnableToConnectException) { // Adapter cannot connect to vehicle bus println("Connection failed: $e") } catch (e: BusInitException) { // Bus initialization error (BUSERROR / BUSINIT) println("Bus init error: $e") } catch (e: MisunderstoodCommandException) { // Adapter replied "?" — command not recognized println("Command not understood: $e") } catch (e: StoppedException) { // Adapter replied "STOPPED" println("Stopped: $e") } catch (e: UnknownErrorException) { // Adapter replied generic "ERROR" println("Unknown error: $e") } catch (e: UnSupportedCommandException) { // Response contains only zeros — command not supported by vehicle println("Unsupported command: $e") } catch (e: NonNumericResponseException) { // Response did not contain expected hex digits println("Non-numeric response: $e") } catch (e: BadResponseException) { // Catch-all for any bad response println("Bad response: $e") } } ``` -------------------------------- ### Monitor Status Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Check the status of OBD monitors, including readiness and completion, since codes were cleared or for the current drive cycle. ```APIDOC ## Monitor Status Commands `MonitorStatusSinceCodesClearedCommand` (PID 01) and `MonitorStatusCurrentDriveCycleCommand` (PID 41) parse the OBD monitor readiness bitmap into a structured `SensorStatusData` object, accessible via the `data` property on the command instance. ```kotlin import com.github.eltonvs.obd.command.control.* import com.github.eltonvs.obd.command.Monitors val monitorCmd = MonitorStatusSinceCodesClearedCommand() connection.run(monitorCmd) val status = monitorCmd.data if (status != null) { println("MIL on: ${status.milOn}") // true/false println("DTC count: ${status.dtcCount}") // 2 println("Spark ignition: ${status.isSpark}") // true for petrol, false for diesel // Per-monitor availability and completion status.items.forEach { (monitor, sensorStatus) -> println("${monitor.name}: available=${sensorStatus.available}, complete=${sensorStatus.complete}") } // Output example: // MISFIRE: available=true, complete=true // CATALYST: available=true, complete=false // OXYGEN_SENSOR: available=true, complete=true } // Monitors enum covers: MISFIRE, FUEL_SYSTEM, COMPREHENSIVE_COMPONENT, // CATALYST, HEATED_CATALYST, EVAPORATIVE_SYSTEM, SECONDARY_AIR_SYSTEM, // AC_REFRIGERANT, OXYGEN_SENSOR, OXYGEN_SENSOR_HEATER, EGR_SYSTEM (spark), // NMHC_CATALYST, NOX_SCR_MONITOR, BOOST_PRESSURE, EXHAUST_GAS_SENSOR, // PM_FILTER, EGR_VVT_SYSTEM (compression) ``` ``` -------------------------------- ### Execute OBD Command Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Executes an OBD command on a connected device. Supports caching, delays, and retries. ```APIDOC ## `run` ### Description Executes an OBD command and returns the response. This method is suspendable and handles command serialization internally. ### Method Signature ```kotlin suspend fun run( command: ObdCommand, useCache: Boolean = false, delayTime: Long = 0, maxRetries: Int = 5, ): ObdResponse ``` ### Parameters - **command** (`ObdCommand`) - The OBD command to execute. - **useCache** (`Boolean`, optional) - If true, the result will be cached if available. Defaults to `false`. - **delayTime** (`Long`, optional) - A delay in milliseconds before executing the command. Defaults to `0`. - **maxRetries** (`Int`, optional) - The maximum number of retries for the command execution. Defaults to `5`. ### Returns - **`ObdResponse`** - The response from the executed command. ``` -------------------------------- ### Engine Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Engine commands retrieve data such as RPM, speed, throttle position, mass air flow, engine load, and runtime. These commands use Mode 01 and return parsed numeric values with appropriate units. ```APIDOC ## Engine Commands Engine commands cover RPM, speed, throttle, MAF, engine load, and runtime. All use Mode 01 and return parsed numeric values with appropriate units. ### RPM Command Retrieves the engine's Revolutions Per Minute. ```kotlin val rpm = connection.run(RPMCommand()) println("${rpm.value} ${rpm.unit}") // "1500 RPM" ``` ### Speed Command Retrieves the vehicle's speed. ```kotlin val speed = connection.run(SpeedCommand()) println("${speed.value} ${speed.unit}") // "80 Km/h" ``` ### Throttle Position Command Retrieves the current throttle position. ```kotlin val throttle = connection.run(ThrottlePositionCommand()) println("${throttle.value} ${throttle.unit}") // "25.5 %" ``` ### Relative Throttle Position Command Retrieves the relative throttle position. ```kotlin val relativeThrottle = connection.run(RelativeThrottlePositionCommand()) println("${relativeThrottle.value} ${relativeThrottle.unit}") // "12.2 %" ``` ### Mass Air Flow Command Retrieves the Mass Air Flow rate. ```kotlin val maf = connection.run(MassAirFlowCommand()) println("${maf.value} ${maf.unit}") // "14.23 g/s" ``` ### Load Command Retrieves the engine load. ```kotlin val load = connection.run(LoadCommand()) println("${load.value} ${load.unit}") // "42.0 %" ``` ### Absolute Load Command Retrieves the absolute engine load. ```kotlin val absLoad = connection.run(AbsoluteLoadCommand()) println("${absLoad.value} ${absLoad.unit}") // "38.5 %" ``` ### Runtime Command Retrieves the engine runtime since last start. ```kotlin val runtime = connection.run(RuntimeCommand()) println(runtime.value) // "00:12:34" (hh:mm:ss) ``` ``` -------------------------------- ### EGR Commands in Kotlin Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Monitor the Exhaust Gas Recirculation (EGR) system by retrieving the commanded position and measured error percentage. Negative error indicates less EGR than commanded. ```kotlin import com.github.eltonvs.obd.command.egr.* val commandedEgr = connection.run(CommandedEgrCommand()) println("${commandedEgr.value} ${commandedEgr.unit}") // "30.2 %" val egrError = connection.run(EgrErrorCommand()) println("${egrError.value} ${egrError.unit}") // "-5.5 %" // Negative values = less EGR than commanded; positive = more than commanded ``` -------------------------------- ### Fuel Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Commands related to fuel level, type, consumption rate, ethanol content, fuel trim, and air/fuel equivalence ratios. ```APIDOC ## Fuel Commands Fuel commands cover level, type, consumption rate, ethanol content, fuel trim, and air/fuel equivalence ratios. `FuelTrimCommand` and `FuelAirEquivalenceRatioCommand` accept enum selectors for bank/sensor targeting. ```kotlin import com.github.eltonvs.obd.command.fuel.* val fuelLevel = connection.run(FuelLevelCommand()) println("${fuelLevel.value} ${fuelLevel.unit}") // "72.5 %" val fuelType = connection.run(FuelTypeCommand()) println(fuelType.value) // "Gasoline" // Other values: "Diesel", "Ethanol", "Electric", "Hybrid Gasoline", "Hybrid Diesel", etc. val consumptionRate = connection.run(FuelConsumptionRateCommand()) println("${consumptionRate.value} ${consumptionRate.unit}") // "8.5 L/h" val ethanolLevel = connection.run(EthanolLevelCommand()) println("${ethanolLevel.value} ${ethanolLevel.unit}") // "10.0 %" // Fuel trim — select bank with FuelTrimBank enum val shortTerm1 = connection.run(FuelTrimCommand(FuelTrimCommand.FuelTrimBank.SHORT_TERM_BANK_1)) println("${shortTerm1.value} ${shortTerm1.unit}") // "-3.1 %" val longTerm2 = connection.run(FuelTrimCommand(FuelTrimCommand.FuelTrimBank.LONG_TERM_BANK_2)) println("${longTerm2.value} ${longTerm2.unit}") // "1.5 %" // FuelTrimBank values: SHORT_TERM_BANK_1, SHORT_TERM_BANK_2, LONG_TERM_BANK_1, LONG_TERM_BANK_2 // Commanded equivalence ratio val commandedRatio = connection.run(CommandedEquivalenceRatioCommand()) println("${commandedRatio.value} ${commandedRatio.unit}") // "1.00 F/A" // Per-sensor fuel-air equivalence ratio val o2Ratio = connection.run(FuelAirEquivalenceRatioCommand(FuelAirEquivalenceRatioCommand.OxygenSensor.OXYGEN_SENSOR_1)) println("${o2Ratio.value} ${o2Ratio.unit}") // "0.98 F/A" // OxygenSensor values: OXYGEN_SENSOR_1 through OXYGEN_SENSOR_8 ``` ``` -------------------------------- ### Read VIN with Caching Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Read the Vehicle Identification Number (VIN) and enable caching to avoid redundant requests. This is useful for data that rarely changes. ```kotlin val vin = obdConnection.run(VINCommand(), useCache = true) ``` -------------------------------- ### Read Live Telemetry Data Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Continuously read live vehicle telemetry data such as RPM and speed. Ensure commands are run from a background coroutine context. ```kotlin val rpm = obdConnection.run(RPMCommand()) val speed = obdConnection.run(SpeedCommand()) ``` -------------------------------- ### Temperature Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Temperature commands report engine and ambient thermal data. All return values in degrees Celsius with a -40°C offset applied per OBD-II spec. ```APIDOC ## Temperature Commands Temperature commands report engine and ambient thermal data. All return values in degrees Celsius with a -40°C offset applied per OBD-II spec. ### Engine Coolant Temperature Command Retrieves the engine coolant temperature. ```kotlin val coolant = connection.run(EngineCoolantTemperatureCommand()) println("${coolant.value} ${coolant.unit}") // "90.0 °C" ``` ### Air Intake Temperature Command Retrieves the air intake temperature. ```kotlin val intakeAir = connection.run(AirIntakeTemperatureCommand()) println("${intakeAir.value} ${intakeAir.unit}") // "35.0 °C" ``` ### Ambient Air Temperature Command Retrieves the ambient air temperature. ```kotlin val ambientAir = connection.run(AmbientAirTemperatureCommand()) println("${ambientAir.value} ${ambientAir.unit}") // "22.0 °C" ``` ### Oil Temperature Command Retrieves the engine oil temperature. ```kotlin val oilTemp = connection.run(OilTemperatureCommand()) println("${oilTemp.value} ${oilTemp.unit}") // "95.0 °C" ``` ``` -------------------------------- ### Control / Diagnostic Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Execute control commands to retrieve vehicle information like VIN, MIL status, timing advance, module voltage, DTC count, distances/times since events, and available PIDs. ```APIDOC ## Control / Diagnostic Commands Control commands cover VIN, MIL status, timing advance, module voltage, DTC count, distances/times since events, and available PIDs. ```kotlin import com.github.eltonvs.obd.command.control.* // VIN — cache it to avoid repeated multi-frame reads val vin = connection.run(VINCommand(), useCache = true) println(vin.value) // "1HGCM82633A123456" // MIL (check engine light) state val mil = connection.run(MILOnCommand()) println(mil.value) // "true" or "false" println(mil.formattedValue) // "MIL is ON" or "MIL is OFF" val distanceMilOn = connection.run(DistanceMILOnCommand()) println("${distanceMilOn.value} ${distanceMilOn.unit}") // "120 Km" val timeMilOn = connection.run(TimeSinceMILOnCommand()) println("${timeMilOn.value} ${timeMilOn.unit}") // "45 min" // Timing advance val timingAdvance = connection.run(TimingAdvanceCommand()) println("${timingAdvance.value} ${timingAdvance.unit}") // "14.00 °" // Control module voltage val voltage = connection.run(ModuleVoltageCommand()) println("${voltage.value} ${voltage.unit}") // "12.35 V" // DTC count val dtcNumber = connection.run(DTCNumberCommand()) println("${dtcNumber.value} ${dtcNumber.unit}") // "2 codes" // Distance / time since codes cleared val distCleared = connection.run(DistanceSinceCodesClearedCommand()) println("${distCleared.value} ${distCleared.unit}") // "340 Km" val timeCleared = connection.run(TimeSinceCodesClearedCommand()) println("${timeCleared.value} ${timeCleared.unit}") // "1200 min" // Available PIDs in a range val availablePids = connection.run(AvailablePIDsCommand(AvailablePIDsCommand.AvailablePIDsRanges.PIDS_01_TO_20)) println(availablePids.value) // "04,05,0C,0D,0E,0F,10,11,1F" // Ranges: PIDS_01_TO_20, PIDS_21_TO_40, PIDS_41_TO_60, PIDS_61_TO_80, PIDS_81_TO_A0 ``` ``` -------------------------------- ### ObdResponse Structure Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Details the structure of the response received after executing an OBD command. ```APIDOC ## `ObdResponse` Data Class ### Description Represents the structured response from an OBD command execution. ### Fields - **`command`** (`ObdCommand`) - The command that was executed. - **`rawResponse`** (`ObdRawResponse`) - The raw, unprocessed response from the device. - **`value`** (`String`) - The processed and human-readable value of the response. - **`unit`** (`String`) - The unit of measurement for the response value (e.g., "RPM", "km/h"). ``` -------------------------------- ### Trouble Codes Commands Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Retrieve and clear Diagnostic Trouble Codes (DTCs) using commands for current, pending, and permanent codes, as well as a command to reset them. ```APIDOC ## Trouble Codes Commands `TroubleCodesCommand` (Mode 03), `PendingTroubleCodesCommand` (Mode 07), and `PermanentTroubleCodesCommand` (Mode 0A) all extend `BaseTroubleCodesCommand`. The parsed `value` is a comma-separated DTC string; the typed `troubleCodesList` property exposes individual codes. `ResetTroubleCodesCommand` (Mode 04) clears all stored codes. ```kotlin import com.github.eltonvs.obd.command.control.* // Current (confirmed) DTCs val current = connection.run(TroubleCodesCommand()) as TroubleCodesCommand // cast to access typed list // Or via the command reference in ObdResponse: val currentCmd = TroubleCodesCommand() connection.run(currentCmd) println(currentCmd.troubleCodesList) // ["P0300", "P0420"] println(currentCmd.value) // "P0300,P0420" (or "" if none) // Pending DTCs (detected but not yet confirmed) val pendingCmd = PendingTroubleCodesCommand() connection.run(pendingCmd) println(pendingCmd.troubleCodesList) // ["P0171"] // Permanent DTCs (require drive cycle to clear) val permanentCmd = PermanentTroubleCodesCommand() connection.run(permanentCmd) println(permanentCmd.troubleCodesList) // [] // Clear all DTCs connection.run(ResetTroubleCodesCommand()) ``` ``` -------------------------------- ### Read and Clear Trouble Codes (DTCs) Source: https://context7.com/eltonvs/kotlin-obd-api/llms.txt Retrieve current, pending, and permanent Diagnostic Trouble Codes (DTCs). Use `ResetTroubleCodesCommand` to clear all stored codes. ```kotlin import com.github.eltonvs.obd.command.control.* // Current (confirmed) DTCs val current = connection.run(TroubleCodesCommand()) as TroubleCodesCommand // cast to access typed list // Or via the command reference in ObdResponse: val currentCmd = TroubleCodesCommand() connection.run(currentCmd) println(currentCmd.troubleCodesList) // ["P0300", "P0420"] println(currentCmd.value) // "P0300,P0420" (or "" if none) // Pending DTCs (detected but not yet confirmed) val pendingCmd = PendingTroubleCodesCommand() connection.run(pendingCmd) println(pendingCmd.troubleCodesList) // ["P0171"] // Permanent DTCs (require drive cycle to clear) val permanentCmd = PermanentTroubleCodesCommand() connection.run(permanentCmd) println(permanentCmd.troubleCodesList) // [] // Clear all DTCs connection.run(ResetTroubleCodesCommand()) ``` -------------------------------- ### ObdRawResponse Structure Source: https://github.com/eltonvs/kotlin-obd-api/blob/master/LLM_CONTEXT.md Details the structure of the raw response from the OBD device. ```APIDOC ## `ObdRawResponse` Data Class ### Description Contains the raw data and timing information from the OBD device. ### Fields - **`value`** (`String`) - The raw string value received from the device. - **`elapsedTime`** (`Long`) - The time in milliseconds it took to receive the raw response. - **`processedValue`** (`String`) - A potentially further processed version of the raw value. - **`bufferedValue`** (`IntArray`) - An integer array representation of the raw response, useful for complex data decoding. ```