State to IntArray mapper

This commit is contained in:
Piotr Dec 2023-08-24 00:23:40 +02:00
parent 2b0746f6c4
commit ff2e163983
No known key found for this signature in database
GPG key ID: ABD6CB83D6110D27
4 changed files with 173 additions and 32 deletions

View file

@ -6,6 +6,12 @@ import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket import android.bluetooth.BluetoothSocket
import android.util.Log import android.util.Log
import com.mapbox.navigation.ui.maneuver.model.Maneuver import com.mapbox.navigation.ui.maneuver.model.Maneuver
import eu.ztsh.garmin.data.Direction
import eu.ztsh.garmin.data.GarminMapper
import eu.ztsh.garmin.data.ManeuverMapper
import eu.ztsh.garmin.data.OutAngle
import eu.ztsh.garmin.data.OutType
import eu.ztsh.garmin.data.State
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
import java.util.concurrent.SynchronousQueue import java.util.concurrent.SynchronousQueue
@ -45,46 +51,29 @@ class Garmin(
send(ManeuverMapper.apply(maneuver)) send(ManeuverMapper.apply(maneuver))
} }
fun send(incoming: eu.ztsh.garmin.State) { fun send(incoming: eu.ztsh.garmin.data.State) {
if (stateCache.distance != incoming.distance) { if (stateCache.distance != incoming.distance) {
setDistance(incoming) setDistance(incoming)
} }
if (stateCache.direction != incoming.direction) { if (stateCache.direction != incoming.direction) {
setDirection(stateCache.direction) setDirection(stateCache)
} }
stateCache = incoming stateCache = incoming
} }
private fun setDistance(state: eu.ztsh.garmin.State) {
connection.enqueue(intArrayOf( private fun setLines(state: eu.ztsh.garmin.data.State) {
0x03, asDigit(state.distance / 1000), asDigit(state.distance / 100), asDigit(state.distance / 10),
0x00, asDigit(state.distance), state.unit.value
))
} }
private fun setDirection(direction: Direction) { private fun setDistance(state: eu.ztsh.garmin.data.State) {
val param1: Int = when (direction.angle) { connection.enqueue(GarminMapper.setDistance(state))
OutAngle.LeftDown -> 0x10
OutAngle.RightDown -> 0x20
else -> direction.out.value
}
val param2: Int = if (direction.out == OutType.RightRoundabout
|| direction.out == OutType.LeftRoundabout) {
if (direction.roundabout == OutAngle.AsDirection) direction.angle.value else direction.roundabout.value
} else {
0x00
}
val param3: Int = if (direction.angle == OutAngle.LeftDown || direction.angle == OutAngle.RightDown) 0x00 else direction.angle.value
connection.enqueue(intArrayOf(0x01, param1, param2, param3))
} }
private fun asDigit(n: Int): Int { private fun setDirection(direction: eu.ztsh.garmin.data.State) {
if (n == 0) { connection.enqueue(GarminMapper.setDirection(direction))
return 0
}
val m = n % 10
return if (m == 0) 10 else m
} }
} }
private inner class ConnectThread : Thread() { private inner class ConnectThread : Thread() {

View file

@ -0,0 +1,151 @@
package eu.ztsh.garmin.data
class GarminMapper {
companion object {
fun setLines(state: State): IntArray {
return intArrayOf(0x02, state.lineOutlines.sumOf { it.value }, state.lineArrows.sumOf { it.value })
}
fun setDirection(state: State): IntArray {
return setDirection(state.direction.angle, state.direction.out, state.direction.roundabout)
}
fun setDistance(state: State): IntArray {
return setDistance(state.distance, state.unit)
}
fun setSpeed(state: State): IntArray {
return setSpeed(state.speed, state.limit, state.speed > state.limit)
}
fun setSpeedFreeRide(state: State): Pair<IntArray, IntArray> {
return Pair(setDistance(state.speed), setSpeed(state.limit, limitWarning = state.speed > state.limit))
}
fun setTime(hours: Int, minutes: Int, traffic: Boolean = false, flag: Boolean = false): IntArray {
val trafficChar = asChar(traffic)
val flagChar = asChar(flag)
return if (hours > 99) {
intArrayOf(
0x05,
trafficChar,
asDigit(hours / 1000),
asDigit(hours / 100),
0x00,
asDigit(hours / 10),
asDigit(hours),
0xff,
flagChar
)
} else {
intArrayOf(
0x05,
trafficChar,
asDigit(hours / 10),
asDigit(hours),
0xff,
asDigit(minutes / 10),
asDigit(minutes),
0x00,
flagChar
)
}
}
fun setSpeedControl(state: State): IntArray {
return intArrayOf(0x04, if (state.control) 0x01 else 0x02)
}
fun setCompass(state: State): IntArray {
// TODO: Implement
return setDirection(OutAngle.Straight, OutType.ArrowOnly)
}
fun cleanDistance(): IntArray {
return intArrayOf(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
}
private fun setDirection(
angle: OutAngle,
out: OutType = OutType.Lane,
roundabout: OutAngle = OutAngle.AsDirection
): IntArray {
val param1: Int = when (angle) {
OutAngle.LeftDown -> 0x10
OutAngle.RightDown -> 0x20
else -> out.value
}
val param2: Int = if (out == OutType.RightRoundabout
|| out == OutType.LeftRoundabout
) {
if (roundabout == OutAngle.AsDirection) angle.value else roundabout.value
} else {
0x00
}
val param3: Int =
if (angle == OutAngle.LeftDown || angle == OutAngle.RightDown) 0x00 else angle.value
return intArrayOf(0x01, param1, param2, param3)
}
private fun setDistance(distance: Int, unit: Unit = Unit.Any): IntArray {
return intArrayOf(
0x03, asDigit(distance / 1000), asDigit(distance / 100), asDigit(distance / 10),
0x00, asDigit(distance), unit.value
)
}
private fun setSpeed(
speed: Int,
limit: Int = 0,
limitWarning: Boolean = false,
acc: Boolean = false
): IntArray {
// TODO: car connection
val accChar = asChar(acc)
val limitWarningChar = asChar(limitWarning)
return if (limit > 0) {
intArrayOf(
0x06,
asDigit(speed / 100),
asDigit(speed / 10),
asDigit(speed),
0xff,
asDigit(limit / 100),
asDigit(limit / 10),
asDigit(limit),
limitWarningChar,
accChar
)
} else {
intArrayOf(
0x06,
0x00,
0x00,
0x00,
0x00,
asDigit(speed / 100),
asDigit(speed / 10),
asDigit(speed),
limitWarningChar,
accChar
)
}
}
private fun asDigit(n: Int): Int {
if (n == 0) {
return 0
}
val m = n % 10
return if (m == 0) 10 else m
}
private fun asChar(boolean: Boolean): Int {
return if (boolean) 0xff else 0x00
}
}
}

View file

@ -1,4 +1,4 @@
package eu.ztsh.garmin package eu.ztsh.garmin.data
import com.mapbox.navigation.ui.maneuver.model.Maneuver import com.mapbox.navigation.ui.maneuver.model.Maneuver
@ -43,7 +43,8 @@ class ManeuverMapper {
state.unit = when (this[1]) { state.unit = when (this[1]) {
"m" -> Unit.Metres "m" -> Unit.Metres
"km" -> Unit.Kilometres "km" -> Unit.Kilometres
else -> {Unit.Any} else -> {
Unit.Any}
} }
} }

View file

@ -1,4 +1,4 @@
package eu.ztsh.garmin package eu.ztsh.garmin.data
enum class OutType(val value: Int) { enum class OutType(val value: Int) {
@ -54,8 +54,8 @@ enum class Lane(val value: Int) {
class State { class State {
var lineArrows: Int = 0 var lineArrows: List<Lane> = listOf()
var lineOutlines: Int = 0 var lineOutlines: List<Lane> = listOf()
var direction = Direction() var direction = Direction()
var distance: Int = 0 var distance: Int = 0
var unit: Unit = Unit.Any var unit: Unit = Unit.Any