fix init codes

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2026-01-11 18:11:05 +01:00
padre 1883aeca0e
commit 5332809c40
Se han modificado 3 ficheros con 99 adiciones y 14 borrados

Ver fichero

@@ -85,6 +85,7 @@ class BluetoothService {
/** /**
* Initialize ELM327 with default commands * Initialize ELM327 with default commands
* Based on standard ELM327 initialization sequence
*/ */
private suspend fun initializeElm327() { private suspend fun initializeElm327() {
// Reset device // Reset device
@@ -99,13 +100,23 @@ class BluetoothService {
sendCommand("ATL0") sendCommand("ATL0")
kotlinx.coroutines.delay(100) kotlinx.coroutines.delay(100)
// Set spaces off // Set spaces off (faster parsing)
sendCommand("ATS0") sendCommand("ATS0")
kotlinx.coroutines.delay(100) kotlinx.coroutines.delay(100)
// Turn off headers (shorter responses)
sendCommand("ATH0")
kotlinx.coroutines.delay(100)
// Set adaptive timing to mode 2 (aggressive learning for faster responses)
sendCommand("ATAT2")
kotlinx.coroutines.delay(100)
// Set protocol to automatic // Set protocol to automatic
sendCommand("ATSP0") sendCommand("ATSP0")
kotlinx.coroutines.delay(100) kotlinx.coroutines.delay(100)
Log.d(TAG, "ELM327 initialized successfully")
} }
/** /**
@@ -117,8 +128,15 @@ class BluetoothService {
} }
try { try {
Log.d(TAG, "Preparing to send command: '$command'")
Log.d(TAG, "Command type: ${command::class.java.simpleName}, length: ${command.length}")
val commandWithCR = "$command\r" val commandWithCR = "$command\r"
outputStream?.write(commandWithCR.toByteArray()) val bytes = commandWithCR.toByteArray()
Log.d(TAG, "Sending bytes: ${bytes.joinToString(" ") { "0x%02X".format(it) }}")
outputStream?.write(bytes)
outputStream?.flush() outputStream?.flush()
Log.d(TAG, "Sent: $command") Log.d(TAG, "Sent: $command")
@@ -130,7 +148,7 @@ class BluetoothService {
Log.d(TAG, "Received: $response") Log.d(TAG, "Received: $response")
Result.success(response) Result.success(response)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Send command error", e) Log.e(TAG, "Send command error: ${e.message}", e)
Result.failure(e) Result.failure(e)
} }
} }

Ver fichero

@@ -18,6 +18,54 @@ import com.manalejandro.odb2bluetooth.ui.components.WarningDialog
import com.manalejandro.odb2bluetooth.ui.viewmodel.MainViewModel import com.manalejandro.odb2bluetooth.ui.viewmodel.MainViewModel
import com.manalejandro.odb2bluetooth.ui.viewmodel.VehicleViewModel import com.manalejandro.odb2bluetooth.ui.viewmodel.VehicleViewModel
/**
* Parse command string that may be in JSON format
* Examples:
* - "010C" -> "010C"
* - "{\"22\": \"2203\"}" -> "2203"
* - "{\"header\": \"7E0\", \"command\": \"2203\"}" -> "2203"
*/
private fun parseCommandString(commandStr: String?): String? {
if (commandStr.isNullOrBlank()) return null
// If it doesn't start with {, it's already a plain command
if (!commandStr.trim().startsWith("{")) {
return commandStr.trim()
}
// Try to parse as JSON-like format
try {
// Remove { } and split by comma
val content = commandStr.trim().removeSurrounding("{", "}")
val pairs = content.split(",")
for (pair in pairs) {
val parts = pair.split(":")
if (parts.size == 2) {
val key = parts[0].trim().removeSurrounding("\"")
val value = parts[1].trim().removeSurrounding("\"")
// Look for common command keys
if (key.equals("command", ignoreCase = true) ||
key.matches(Regex("\\d+"))) { // numeric key like "22"
return value
}
}
}
// If no specific key found, return the first value
val firstPair = pairs.firstOrNull()?.split(":")
if (firstPair?.size == 2) {
return firstPair[1].trim().removeSurrounding("\"")
}
} catch (e: Exception) {
android.util.Log.e("VehicleSelection", "Error parsing command: $commandStr", e)
}
// Fallback: return original if parsing fails
return commandStr
}
/** /**
* Vehicle selection screen - Browse vehicles and their OBD signals * Vehicle selection screen - Browse vehicles and their OBD signals
*/ */
@@ -40,6 +88,8 @@ fun VehicleSelectionScreen(
var selectedSignal by remember { mutableStateOf<SignalDto?>(null) } var selectedSignal by remember { mutableStateOf<SignalDto?>(null) }
if (showWarning && selectedSignal != null) { if (showWarning && selectedSignal != null) {
val parsedCommand = parseCommandString(selectedSignal?.command)
WarningDialog( WarningDialog(
onDismiss = { onDismiss = {
showWarning = false showWarning = false
@@ -47,7 +97,9 @@ fun VehicleSelectionScreen(
}, },
onAccept = { onAccept = {
showWarning = false showWarning = false
selectedSignal?.command?.let { command -> parsedCommand?.let { command ->
android.util.Log.d("VehicleSelection", "Original: ${selectedSignal?.command}")
android.util.Log.d("VehicleSelection", "Parsed command: $command")
mainViewModel.sendCommand(command) mainViewModel.sendCommand(command)
} }
selectedSignal = null selectedSignal = null
@@ -55,7 +107,8 @@ fun VehicleSelectionScreen(
title = "Send OBD Command", title = "Send OBD Command",
message = "You are about to send this command:\n\n" + message = "You are about to send this command:\n\n" +
"Signal: ${selectedSignal?.signalName}\n" + "Signal: ${selectedSignal?.signalName}\n" +
"Command: ${selectedSignal?.command}\n" + "Raw: ${selectedSignal?.command}\n" +
"Command to send: $parsedCommand\n" +
"Description: ${selectedSignal?.description ?: "N/A"}\n\n" + "Description: ${selectedSignal?.description ?: "N/A"}\n\n" +
"⚠️ Warning: Sending commands can potentially affect your vehicle. " + "⚠️ Warning: Sending commands can potentially affect your vehicle. " +
"Make sure you understand what this command does.\n\n" + "Make sure you understand what this command does.\n\n" +
@@ -320,6 +373,8 @@ private fun SignalCard(
signal: SignalDto, signal: SignalDto,
onSend: () -> Unit onSend: () -> Unit
) { ) {
val parsedCommand = parseCommandString(signal.command)
ElevatedCard( ElevatedCard(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
@@ -349,7 +404,7 @@ private fun SignalCard(
} }
Button( Button(
onClick = onSend, onClick = onSend,
enabled = signal.command != null enabled = parsedCommand != null
) { ) {
Icon( Icon(
imageVector = Icons.Default.Send, imageVector = Icons.Default.Send,
@@ -369,18 +424,26 @@ private fun SignalCard(
Divider() Divider()
Row( // Use FlowRow to wrap chips properly
Column(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(16.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
signal.command?.let { Row(
InfoChip("Command", it) modifier = Modifier.fillMaxWidth(),
} horizontalArrangement = Arrangement.spacedBy(8.dp)
signal.unit?.let { ) {
InfoChip("Unit", it) parsedCommand?.let {
InfoChip("Command", it)
}
signal.unit?.let {
InfoChip("Unit", it)
}
} }
signal.frequency?.let { signal.frequency?.let {
InfoChip("Freq", "${it}Hz") Row {
InfoChip("Frequency", "${it}Hz")
}
} }
} }
} }

Ver fichero

@@ -87,16 +87,20 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
* Send a command to the OBD device * Send a command to the OBD device
*/ */
fun sendCommand(command: String) { fun sendCommand(command: String) {
android.util.Log.d("OBD2_COMMAND", "Sending command: '$command' (type: ${command::class.simpleName})")
viewModelScope.launch { viewModelScope.launch {
_isLoading.value = true _isLoading.value = true
bluetoothService.sendCommand(command).fold( bluetoothService.sendCommand(command).fold(
onSuccess = { response -> onSuccess = { response ->
android.util.Log.d("OBD2_COMMAND", "Command sent successfully. Response: $response")
val parsed = ObdCommands.parseResponse(command, response) ?: response val parsed = ObdCommands.parseResponse(command, response) ?: response
addCommandToHistory(command, response, parsed) addCommandToHistory(command, response, parsed)
_errorMessage.value = null _errorMessage.value = null
}, },
onFailure = { error -> onFailure = { error ->
android.util.Log.e("OBD2_COMMAND", "Command failed: ${error.message}")
_errorMessage.value = "Command failed: ${error.message}" _errorMessage.value = "Command failed: ${error.message}"
addCommandToHistory(command, "", "Error: ${error.message}") addCommandToHistory(command, "", "Error: ${error.message}")
} }