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.util.Log
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.util.*
import java.util.concurrent.SynchronousQueue
@ -45,46 +51,29 @@ class Garmin(
send(ManeuverMapper.apply(maneuver))
}
fun send(incoming: eu.ztsh.garmin.State) {
fun send(incoming: eu.ztsh.garmin.data.State) {
if (stateCache.distance != incoming.distance) {
setDistance(incoming)
}
if (stateCache.direction != incoming.direction) {
setDirection(stateCache.direction)
setDirection(stateCache)
}
stateCache = incoming
}
private fun setDistance(state: eu.ztsh.garmin.State) {
connection.enqueue(intArrayOf(
0x03, asDigit(state.distance / 1000), asDigit(state.distance / 100), asDigit(state.distance / 10),
0x00, asDigit(state.distance), state.unit.value
))
private fun setLines(state: eu.ztsh.garmin.data.State) {
}
private fun setDirection(direction: Direction) {
val param1: Int = when (direction.angle) {
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 setDistance(state: eu.ztsh.garmin.data.State) {
connection.enqueue(GarminMapper.setDistance(state))
}
private fun asDigit(n: Int): Int {
if (n == 0) {
return 0
}
val m = n % 10
return if (m == 0) 10 else m
private fun setDirection(direction: eu.ztsh.garmin.data.State) {
connection.enqueue(GarminMapper.setDirection(direction))
}
}
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
@ -43,7 +43,8 @@ class ManeuverMapper {
state.unit = when (this[1]) {
"m" -> Unit.Metres
"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) {
@ -54,8 +54,8 @@ enum class Lane(val value: Int) {
class State {
var lineArrows: Int = 0
var lineOutlines: Int = 0
var lineArrows: List<Lane> = listOf()
var lineOutlines: List<Lane> = listOf()
var direction = Direction()
var distance: Int = 0
var unit: Unit = Unit.Any