Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ android {
applicationId "com.openvehicles.OVMS"
minSdk 21
targetSdk 36
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
</activity>
<activity
android:name=".ui.MainActivity"
android:theme="@style/Theme.App.WithActionBar"
android:configChanges="orientation|keyboardHidden"
android:exported="false">
</activity>
Expand All @@ -72,6 +73,7 @@

<activity
android:name=".ui.BaseFragmentActivity"
android:theme="@style/Theme.App.WithActionBar"
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/com/openvehicles/OVMS/BaseApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import com.maltaisn.icondialog.pack.IconPack
import com.maltaisn.icondialog.pack.IconPackLoader
import com.maltaisn.iconpack.defaultpack.createDefaultIconPack
import com.openvehicles.OVMS.ui2.misc.ThemeMode

class BaseApp : Application() {

Expand All @@ -16,6 +17,8 @@ class BaseApp : Application() {
app = this
context = applicationContext

ThemeMode.apply(this)

loadIconPack()
}

Expand Down
13 changes: 8 additions & 5 deletions app/src/main/java/com/openvehicles/OVMS/api/ApiTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import javax.net.ssl.SSLSocket
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

import java.nio.charset.StandardCharsets

class ApiTask(

private var context: Context,
Expand Down Expand Up @@ -120,8 +122,8 @@ class ApiTask(
// Read & decrypt message:
line = inputstream!!.readLine()
if (line == null) throw IOException("Connection lost")
rx = line.trim { it <= ' ' }
msg = String(rxCipher.update(Base64.decode(rx, 0))).trim { it <= ' ' }
rx = line!!.trim { it <= ' ' }
msg = String(rxCipher.update(Base64.decode(rx, 0)), StandardCharsets.UTF_8).trim { it <= ' ' }
Log.d(TAG, String.format("RX: %s (%s)", msg, rx))

// Process message:
Expand Down Expand Up @@ -219,7 +221,7 @@ class ApiTask(
Log.i(TAG, "TX: $message")
outputstream!!.println(
Base64.encodeToString(
txCipher.update(message.toByteArray()),
txCipher.update(message.toByteArray(StandardCharsets.UTF_8)),
Base64.NO_WRAP
)
)
Expand Down Expand Up @@ -302,11 +304,12 @@ class ApiTask(
outputstream = PrintWriter(
BufferedWriter(
OutputStreamWriter(
socket!!.getOutputStream()
socket!!.getOutputStream(),
StandardCharsets.UTF_8
)
), true
)
inputstream = BufferedReader(InputStreamReader(socket!!.getInputStream()))
inputstream = BufferedReader(InputStreamReader(socket!!.getInputStream(), StandardCharsets.UTF_8))
outputLock = Semaphore(1)

// Encrypt password:
Expand Down
41 changes: 29 additions & 12 deletions app/src/main/java/com/openvehicles/OVMS/entities/AuxBatteryData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import java.io.BufferedReader
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone

/**
Expand All @@ -32,7 +34,7 @@ class AuxBatteryData {
val json = gson.toJson(this)
return try {
outputStream = context!!.openFileOutput(filename, Context.MODE_PRIVATE)
outputStream.write(json.toByteArray())
outputStream.write(json.toByteArray(StandardCharsets.UTF_8))
outputStream.close()
true
} catch (e: Exception) {
Expand All @@ -46,7 +48,7 @@ class AuxBatteryData {
var recCnt: Int
var recType: String
var timeStamp: Date
val serverTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val serverTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
serverTime.timeZone = TimeZone.getTimeZone("UTC")
var packStatus: PackStatus? = null
var doors: Int
Expand All @@ -65,22 +67,37 @@ class AuxBatteryData {
recNr = result[2].toInt()
recCnt = result[3].toInt()
recType = result[4]
timeStamp = serverTime.parse(result[5])

// Robust timestamp parsing:
var shift = 0
try {
timeStamp = serverTime.parse(result[5])!!
} catch (e: Exception) {
// try combined with next part if next part looks like time:
try {
timeStamp = serverTime.parse(result[5].trim() + " " + result[6].trim())!!
shift = 1
} catch (e2: Exception) {
Log.w(TAG, "failed to parse timestamp: " + result[5])
continue
}
}

Log.v(TAG, "processing recType $recType entryNr $recNr/$recCnt")
if (recType == "D") {
try {
// create record:
packStatus = PackStatus()
packStatus.timeStamp = timeStamp
packStatus.volt = result[21].toFloat()
if (result.size > 23) packStatus.voltRef = result[23].toFloat()
if (result.size > 26) packStatus.current = result[26].toFloat()
packStatus.tempAmbient = result[17].toFloat()
if (result.size > 25) packStatus.tempCharger = result[25].toFloat()
doors = result[18].toInt() // doors3
packStatus.volt = result[21 + shift].toFloat()
if (result.size > 23 + shift) packStatus.voltRef = result[23 + shift].toFloat()
if (result.size > 26 + shift) packStatus.current = result[26 + shift].toFloat()
packStatus.tempAmbient = result[17 + shift].toFloat()
if (result.size > 25 + shift) packStatus.tempCharger = result[25 + shift].toFloat()
doors = result[18 + shift].toInt() // doors3
packStatus.isCarAwake = doors and 0x01 != 0
if (result.size > 24) {
doors = result[24].toInt() // doors5
if (result.size > 24 + shift) {
doors = result[24 + shift].toInt() // doors5
packStatus.isCharging12V = doors and 0x10 != 0
}

Expand Down Expand Up @@ -125,7 +142,7 @@ class AuxBatteryData {
Log.v(TAG, "loading from file: $filename")
return try {
inputStream = context!!.openFileInput(filename)
val isr = InputStreamReader(inputStream)
val isr = InputStreamReader(inputStream, StandardCharsets.UTF_8)
val bufferedReader = BufferedReader(isr)
val sb = StringBuilder()
var line: String?
Expand Down
77 changes: 47 additions & 30 deletions app/src/main/java/com/openvehicles/OVMS/entities/BatteryData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import java.io.BufferedReader
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStreamReader
import java.nio.charset.StandardCharsets
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone

/**
Expand All @@ -32,7 +34,7 @@ class BatteryData {
val json = gson.toJson(this)
return try {
outputStream = context!!.openFileOutput(filename, Context.MODE_PRIVATE)
outputStream.write(json.toByteArray())
outputStream.write(json.toByteArray(StandardCharsets.UTF_8))
outputStream.close()
true
} catch (e: Exception) {
Expand All @@ -46,7 +48,7 @@ class BatteryData {
var recCnt: Int
var recType: String
var timeStamp: Date
val serverTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val serverTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
serverTime.timeZone = TimeZone.getTimeZone("UTC")
var packStatus: PackStatus? = null
var cells: ArrayList<CellStatus?>? = null
Expand Down Expand Up @@ -83,28 +85,43 @@ class BatteryData {
recNr = result[2].toInt()
recCnt = result[3].toInt()
recType = result[4]
timeStamp = serverTime.parse(result[5])

// Robust timestamp parsing:
var shift = 0
try {
timeStamp = serverTime.parse(result[5])!!
} catch (e: Exception) {
// try combined with next part if next part looks like time:
try {
timeStamp = serverTime.parse(result[5].trim() + " " + result[6].trim())!!
shift = 1
} catch (e2: Exception) {
Log.w(TAG, "failed to parse timestamp: " + result[5])
continue
}
}

Log.v(TAG, "processing recType $recType entryNr $recNr/$recCnt")
if (recType == "RT-BAT-P") {
try {
// create record:
packStatus = PackStatus()
packStatus.timeStamp = timeStamp
packStatus.voltAlert = result[7].toInt()
packStatus.tempAlert = result[8].toInt()
packStatus.soc = result[9].toInt().toFloat() / 100
packStatus.socMin = result[10].toInt().toFloat() / 100
packStatus.socMax = result[11].toInt().toFloat() / 100
packStatus.volt = result[12].toInt().toFloat() / 10
packStatus.voltMin = result[13].toInt().toFloat() / 10
packStatus.voltMax = result[14].toInt().toFloat() / 10
packStatus.temp = result[15].toFloat()
packStatus.tempMin = result[16].toFloat()
packStatus.tempMax = result[17].toFloat()
packStatus.voltDevMax = result[18].toInt().toFloat() / 100
packStatus.tempDevMax = result[19].toFloat()
packStatus.maxDrivePwr = (result[20].toInt() * 100).toLong()
packStatus.maxRecupPwr = (result[21].toInt() * 100).toLong()
packStatus.voltAlert = result[7 + shift].toInt()
packStatus.tempAlert = result[8 + shift].toInt()
packStatus.soc = result[9 + shift].toInt().toFloat() / 100
packStatus.socMin = result[10 + shift].toInt().toFloat() / 100
packStatus.socMax = result[11 + shift].toInt().toFloat() / 100
packStatus.volt = result[12 + shift].toInt().toFloat() / 10
packStatus.voltMin = result[13 + shift].toInt().toFloat() / 10
packStatus.voltMax = result[14 + shift].toInt().toFloat() / 10
packStatus.temp = result[15 + shift].toFloat()
packStatus.tempMin = result[16 + shift].toFloat()
packStatus.tempMax = result[17 + shift].toFloat()
packStatus.voltDevMax = result[18 + shift].toInt().toFloat() / 100
packStatus.tempDevMax = result[19 + shift].toFloat()
packStatus.maxDrivePwr = (result[20 + shift].toInt() * 100).toLong()
packStatus.maxRecupPwr = (result[21 + shift].toInt() * 100).toLong()

// store record:
if (packStatus.volt > 0) packHistory.add(packStatus)
Expand All @@ -114,7 +131,7 @@ class BatteryData {
}
} else if (recType == "RT-BAT-C") {
try {
nrCell = result[6].toInt()
nrCell = result[6 + shift].toInt()
if (nrCell > cellCount) cellCount = nrCell

// Pack record(s) complete?
Expand All @@ -136,16 +153,16 @@ class BatteryData {

// create new record:
cellStatus = CellStatus()
cellStatus.voltAlert = result[7].toInt()
cellStatus.tempAlert = result[8].toInt()
cellStatus.volt = result[9].toInt().toFloat() / 1000
cellStatus.voltMin = result[10].toInt().toFloat() / 1000
cellStatus.voltMax = result[11].toInt().toFloat() / 1000
cellStatus.voltDevMax = result[12].toInt().toFloat() / 1000
cellStatus.temp = result[13].toFloat()
cellStatus.tempMin = result[14].toFloat()
cellStatus.tempMax = result[15].toFloat()
cellStatus.tempDevMax = result[16].toFloat()
cellStatus.voltAlert = result[7 + shift].toInt()
cellStatus.tempAlert = result[8 + shift].toInt()
cellStatus.volt = result[9 + shift].toInt().toFloat() / 1000
cellStatus.voltMin = result[10 + shift].toInt().toFloat() / 1000
cellStatus.voltMax = result[11 + shift].toInt().toFloat() / 1000
cellStatus.voltDevMax = result[12 + shift].toInt().toFloat() / 1000
cellStatus.temp = result[13 + shift].toFloat()
cellStatus.tempMin = result[14 + shift].toFloat()
cellStatus.tempMax = result[15 + shift].toFloat()
cellStatus.tempDevMax = result[16 + shift].toFloat()

// store record:
cells!![nrCell - 1] = cellStatus
Expand Down Expand Up @@ -201,7 +218,7 @@ class BatteryData {
Log.v(TAG, "loading from file: $filename")
return try {
inputStream = context!!.openFileInput(filename)
val isr = InputStreamReader(inputStream)
val isr = InputStreamReader(inputStream, StandardCharsets.UTF_8)
val bufferedReader = BufferedReader(isr)
val sb = StringBuilder()
var line: String?
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/openvehicles/OVMS/entities/CarData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class CarData : Serializable {
@JvmField
var sel_vehicle_image = "" // The vehicle image (on disk)
@JvmField
var sel_vehicle_image_ol = "" // The vehicle top-view image (on disk)
@JvmField
var sel_vehicle_image_map = "" // The vehicle map icon image (on disk)
@JvmField
var car_lastupdated: Date? = null
var server_carsconnected = 0

Expand Down
Loading