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

@ -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

@ -0,0 +1,60 @@
package eu.ztsh.garmin.data
import com.mapbox.navigation.ui.maneuver.model.Maneuver
class ManeuverMapper {
companion object {
fun apply(maneuver: Maneuver): State {
val state = State()
maneuver.apply {
this.primary.apply {
when (this.type) {
"roundabout" -> {
state.direction.out = OutType.RightRoundabout
}
"arrive" -> {
state.flag = true
}
}
when (this.modifier) {
"right" -> {
when (this.type) {
"turn" -> state.direction.angle = OutAngle.Right
"roundabout" -> {
when (this.degrees) {
137.0 -> state.direction.angle = OutAngle.EasyRight
}
}
}
}
"left" -> {
when (this.type) {
"turn" -> state.direction.angle = OutAngle.Left
}
}
}
}
this.stepDistance.apply {
this.distanceRemaining?.apply {
distanceFormatter.formatDistance(distanceRemaining!!).split(" ").apply {
state.distance = this[0].toInt()
state.unit = when (this[1]) {
"m" -> Unit.Metres
"km" -> Unit.Kilometres
else -> {
Unit.Any}
}
}
}
}
}
return state
}
}
}

View file

@ -0,0 +1,96 @@
package eu.ztsh.garmin.data
enum class OutType(val value: Int) {
Off(0x00),
Lane(0x01),
LongerLane(0x02),
LeftRoundabout(0x04),
RightRoundabout(0x08),
Flag(0x40),
ArrowOnly(0x80);
}
enum class OutAngle(val value: Int) {
Down(0x01),
SharpRight(0x02),
Right(0x04),
EasyRight(0x08),
Straight(0x10),
EasyLeft(0x20),
Left(0x40),
SharpLeft(0x80),
LeftDown(0x81),
RightDown(0x82),
AsDirection(0x00)
}
enum class Unit(val value: Int) {
Any(0),
Metres(1),
Kilometres(3),
Miles(5),
Foot(8)
}
enum class Lane(val value: Int) {
DotsRight(0x01),
OuterRight(0x02),
MiddleRight(0x04),
InnerRight(0x08),
InnerLeft(0x10),
MiddleLeft(0x20),
OuterLeft(0x40),
DotsLeft(0x80)
}
class State {
var lineArrows: List<Lane> = listOf()
var lineOutlines: List<Lane> = listOf()
var direction = Direction()
var distance: Int = 0
var unit: Unit = Unit.Any
var speed: Int = 0
var limit: Int = 0
var hours: Int = 0
var minutes: Int = 0
var traffic: Boolean = false
var flag: Boolean = false
var control: Boolean = false
}
class Direction {
var angle: OutAngle = OutAngle.AsDirection
var out: OutType = OutType.Lane
var roundabout: OutAngle = OutAngle.AsDirection
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Direction
if (angle != other.angle) return false
if (out != other.out) return false
if (roundabout != other.roundabout) return false
return true
}
override fun hashCode(): Int {
var result = angle.hashCode()
result = 31 * result + out.hashCode()
result = 31 * result + roundabout.hashCode()
return result
}
}