Skip to content

Commit

Permalink
API Revamp (#1)
Browse files Browse the repository at this point in the history
* Convert modules into packages

* Fix ObdDeviceConnection class

* Remove unneeded mavenCentral()

* Fix VIN command

* Fix AT commands

* Fix trouble codes command

* Change version number
  • Loading branch information
eltonvs committed Feb 7, 2020
1 parent 606d5ae commit a38fa6b
Show file tree
Hide file tree
Showing 33 changed files with 46 additions and 66 deletions.
11 changes: 7 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
kotlin("jvm") version "1.3.21"
kotlin("jvm") version "1.3.61"
}

group = "com.github.eltonvs.obd"
version = "0.0.1"
version = "1.0.0"

repositories {
mavenCentral()
jcenter()
}

dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("stdlib"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3")
testImplementation(kotlin("test"))
testImplementation(kotlin("test-junit"))
}

tasks.withType<KotlinCompile> {
Expand Down
22 changes: 0 additions & 22 deletions command/build.gradle.kts

This file was deleted.

22 changes: 0 additions & 22 deletions connection/build.gradle.kts

This file was deleted.

1 change: 0 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
rootProject.name = "kotlin-obd-api"
include("command", "connection")
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ package com.github.eltonvs.obd.command

abstract class ATCommand : ObdCommand() {
override val mode = "AT"
override val skipDigitCheck = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ abstract class BadResponseException(private val command: ObdCommand, private val
throw UnknownErrorException(command, response)
matches(UNSUPPORTED_COMMAND_MESSAGE_PATTERN.toRegex()) ->
throw UnSupportedCommandException(command, response)
!matches(DIGITS_LETTERS_PATTERN.toRegex()) ->
!command.skipDigitCheck && !matches(DIGITS_LETTERS_PATTERN.toRegex()) ->
throw NonNumericResponseException(command, response)
else -> response
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ abstract class ObdCommand {
abstract val pid: String

open val defaultUnit: String = ""
open val skipDigitCheck: Boolean = false
open val handler: (ObdRawResponse) -> String = { it.value }

val rawCommand: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ object RegexPatterns {

fun removeAll(pattern: Pattern, input: String): String {
return pattern.matcher(input).replaceAll("")
}
}

fun removeAll(input: String, vararg patterns: Pattern) =
patterns.fold(input) { acc, pattern -> removeAll(pattern, acc) }
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package com.github.eltonvs.obd.command.control

import com.github.eltonvs.obd.command.ObdCommand
import com.github.eltonvs.obd.command.ObdRawResponse
import com.github.eltonvs.obd.command.RegexPatterns.BUS_INIT_PATTERN
import com.github.eltonvs.obd.command.RegexPatterns.STARTS_WITH_ALPHANUM_PATTERN
import com.github.eltonvs.obd.command.RegexPatterns.WHITESPACE_PATTERN
import com.github.eltonvs.obd.command.bytesToInt
import com.github.eltonvs.obd.command.removeAll


class ModuleVoltageCommand : ObdCommand() {
Expand Down Expand Up @@ -33,7 +36,7 @@ class VINCommand : ObdCommand() {
override val pid = "02"

override val defaultUnit = ""
override val handler = { it: ObdRawResponse -> parseVIN(it.value) }
override val handler = { it: ObdRawResponse -> parseVIN(removeAll(it.value, WHITESPACE_PATTERN, BUS_INIT_PATTERN)) }

private fun parseVIN(rawValue: String): String {
val workingData =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.github.eltonvs.obd.command.ObdCommand
import com.github.eltonvs.obd.command.ObdRawResponse
import com.github.eltonvs.obd.command.RegexPatterns.CARRIAGE_COLON_PATTERN
import com.github.eltonvs.obd.command.RegexPatterns.CARRIAGE_PATTERN
import com.github.eltonvs.obd.command.RegexPatterns.WHITESPACE_PATTERN
import com.github.eltonvs.obd.command.bytesToInt
import com.github.eltonvs.obd.command.removeAll
import java.util.regex.Pattern
Expand Down Expand Up @@ -57,8 +58,11 @@ abstract class BaseTroubleCodesCommand : ObdCommand() {

abstract val carriageNumberPattern: Pattern

var troubleCodesList = listOf<String>()
private set

private fun parseTroubleCodesList(rawValue: String): List<String> {
val canOneFrame: String = removeAll(CARRIAGE_PATTERN, rawValue)
val canOneFrame: String = removeAll(rawValue, CARRIAGE_PATTERN, WHITESPACE_PATTERN)
val canOneFrameLength: Int = canOneFrame.length

val workingData =
Expand All @@ -70,7 +74,7 @@ abstract class BaseTroubleCodesCommand : ObdCommand() {
Header is xxx43yy, xxx is bytes of information to follow, yy showing the number of data items. */
rawValue.contains(":") -> removeAll(CARRIAGE_COLON_PATTERN, rawValue).drop(7)
// ISO9141-2, KWP2000 Fast and KWP2000 5Kbps (ISO15031) protocols.
else -> removeAll(carriageNumberPattern, rawValue)
else -> removeAll(rawValue, carriageNumberPattern, WHITESPACE_PATTERN)
}

/* For each chunk of 4 chars:
Expand All @@ -88,7 +92,9 @@ abstract class BaseTroubleCodesCommand : ObdCommand() {
}

val idx = troubleCodesList.indexOf("P0000")
return if (idx < 0) troubleCodesList else troubleCodesList.take(idx)
return (if (idx < 0) troubleCodesList else troubleCodesList.take(idx)).also {
this.troubleCodesList = it
}
}

protected companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,37 @@ import com.github.eltonvs.obd.command.ObdResponse
import com.github.eltonvs.obd.command.RegexPatterns.SEARCHING_PATTERN
import com.github.eltonvs.obd.command.removeAll
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import java.io.InputStream
import java.io.OutputStream
import java.lang.Thread.sleep
import kotlin.system.measureTimeMillis


class ObdDeviceConnection(private val inputStream: InputStream, private val outputStream: OutputStream) {
private val responseCache = mutableMapOf<ObdCommand, ObdRawResponse>()

suspend fun run(command: ObdCommand, useCache: Boolean = false, delayTime: Long = 0): ObdResponse {
@Synchronized
suspend fun run(
command: ObdCommand,
useCache: Boolean = false,
delayTime: Long = 0
): ObdResponse = withContext(Dispatchers.IO) {
val obdRawResponse =
if (useCache && responseCache[command] != null) {
responseCache.getValue(command)
} else {
runCommand(command, delayTime).also {
// Save response to cache
responseCache[command] = it
if (useCache) {
responseCache[command] = it
}
}
}
return command.handleResponse(obdRawResponse)
command.handleResponse(obdRawResponse)
}

private suspend fun runCommand(command: ObdCommand, delayTime: Long): ObdRawResponse {
private fun runCommand(command: ObdCommand, delayTime: Long): ObdRawResponse {
var rawData = ""
val elapsedTime = measureTimeMillis {
sendCommand(command, delayTime)
Expand All @@ -38,21 +45,21 @@ class ObdDeviceConnection(private val inputStream: InputStream, private val outp
return ObdRawResponse(rawData, elapsedTime)
}

private suspend fun sendCommand(command: ObdCommand, delayTime: Long = 0) = withContext(Dispatchers.IO) {
private fun sendCommand(command: ObdCommand, delayTime: Long = 0) {
outputStream.write("${command.rawCommand}\r".toByteArray())
outputStream.flush()
if (delayTime > 0) {
delay(delayTime)
sleep(delayTime)
}
}

private suspend fun readRawData(): String = withContext(Dispatchers.IO) {
private fun readRawData(): String {
var b: Byte
var c: Char
val res = StringBuffer()

// read until '>' arrives OR end of stream reached (-1)
while (true) {
while (inputStream.available() > 0) {
b = inputStream.read().toByte()
if (b < 0) {
break
Expand All @@ -64,6 +71,6 @@ class ObdDeviceConnection(private val inputStream: InputStream, private val outp
res.append(c)
}

removeAll(SEARCHING_PATTERN, res.toString()).trim()
return removeAll(SEARCHING_PATTERN, res.toString()).trim()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class VINCommandParameterizedTests(private val rawValue: String, private val exp
arrayOf("0140:4902015750301:5A5A5A39395A542:53333932313234", "WP0ZZZ99ZTS392124"),
// ISO9141-2, KWP2000 Fast and KWP2000 5Kbps (ISO15031) format
arrayOf("490201000000394902023359425349020352375248490204454A323949020538313136", "93YBSR7RHEJ298116"),
arrayOf("4902010000005749020250305A5A4902035A39395A4902045453333949020532313234", "WP0ZZZ99ZTS392124")
arrayOf("4902010000005749020250305A5A4902035A39395A4902045453333949020532313234", "WP0ZZZ99ZTS392124"),
arrayOf("014 0: 49 02 01 39 42 47 1: 4B 54 34 38 56 30 4A 2: 47 31 34 31 38 30 39", "9BGKT48V0JG141809")
)
}

Expand Down

0 comments on commit a38fa6b

Please sign in to comment.