From 7636428d77db45bd599c3456f26cb6ae932c3a68 Mon Sep 17 00:00:00 2001
From: Trishun <piotr_dec@msn.com>
Date: Wed, 16 Aug 2023 02:47:06 +0200
Subject: [PATCH] WIP: WIP

---
 app/main.py | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 app/test.py |  31 ++++++++
 2 files changed, 237 insertions(+)
 create mode 100644 app/main.py
 create mode 100644 app/test.py

diff --git a/app/main.py b/app/main.py
new file mode 100644
index 0000000..62a2a7a
--- /dev/null
+++ b/app/main.py
@@ -0,0 +1,206 @@
+import time
+from enum import Enum
+
+import serial
+from numpy import uint8
+
+gps = False
+
+
+class OutType(Enum):
+    Off = 0x00
+    Lane = 0x01
+    LongerLane = 0x02
+    LeftRoundabout = 0x04
+    RightRoundabout = 0x08
+    Flag = 0x40
+    ArrowOnly = 0x80
+
+
+class OutAngle(Enum):
+    Down = 0x01
+    SharpRight = 0x02
+    Right = 0x04
+    EasyRight = 0x08
+    Straight = 0x10
+    EasyLeft = 0x20
+    Left = 0x40
+    SharpLeft = 0x80
+    LeftDown = 0x81
+    RightDown = 0x82
+    AsDirection = 0x00
+
+
+class Unit(Enum):
+    Any = 0
+    Metres = 1
+    Kilometres = 3
+    Miles = 5
+    Foot = 8
+
+
+class Lane(Enum):
+    DotsRight = 0x01
+    OuterRight = 0x02
+    MiddleRight = 0x04
+    InnerRight = 0x08
+    InnerLeft = 0x10
+    MiddleLeft = 0x20
+    OuterLeft = 0x40
+    DotsLeft = 0x80
+
+
+class Controller:
+
+    def __init__(self):
+        self.gps = False
+        self.ser = None#serial.Serial('COM9', 9600)
+        time.sleep(2)
+        # print(self.ser.read_all())
+
+    def clear(self):
+        self.send_hud([0x03, 0, 0, 0, 0x00, 0, 0])
+
+    def _as_dgt(self, n: int) -> int:
+        if n == 0:
+            return 0
+        n %= 10
+        return 10 if n == 0 else n
+
+    def set_lines(self, outlines: list, arrows: list):
+        self.send_hud([0x02, sum([lane.value for lane in outlines]), sum([lane.value for lane in arrows])])
+
+    def set_direction(self, angle: OutAngle, out: OutType = OutType.Lane, roundabout: OutAngle = OutAngle.AsDirection):
+        if angle == OutAngle.LeftDown:
+            param_1 = 0x10
+        elif angle == OutAngle.RightDown:
+            param_1 = 0x20
+        else:
+            param_1 = out.value
+
+        if out == OutType.RightRoundabout or out == OutType.LeftRoundabout:
+            param_2 = angle.value if roundabout == OutAngle.AsDirection else roundabout.value
+        else:
+            param_2 = 0x00
+
+        param_3 = 0x00 if angle == OutAngle.LeftDown or angle == OutAngle.RightDown else angle.value
+        arr = [0x01, param_1, param_2, param_3]
+        self.send_hud(arr)
+
+    def set_distance(self, distance, unit: Unit = Unit.Any):
+        arr = [0x03, self._as_dgt(distance // 1000), self._as_dgt(distance // 100), self._as_dgt(distance // 10), 0x00,
+               self._as_dgt(distance), unit.value]
+        self.send_hud(arr)
+
+    def set_speed(self, speed: int, limit: int = 0, acc: bool = False):
+        acc_char = 0xff if acc else 0x00
+        if not self.gps:
+            self.set_distance(speed)
+            self.send_hud([0x06, 0, 0, 0, 0, 0, 0, 0, 0, acc_char])
+            return
+        if limit > 0:
+            arr = [0x06, self._as_dgt(speed // 100), self._as_dgt(speed // 10), self._as_dgt(speed), 0xff,
+                   self._as_dgt(limit // 100), self._as_dgt(limit // 10), self._as_dgt(limit),
+                   0xff if speed > limit else 0x00, acc_char]
+        else:
+            arr = [0x06, 0x00, 0x00, 0x00, 0x00, self._as_dgt(speed // 100), self._as_dgt(speed // 10),
+                   self._as_dgt(speed), 0x00, acc_char]
+        self.send_hud(arr)
+
+    def set_time(self, hours: int, minutes: int, traffic: bool = False, flag: bool = False):
+        traffic_char = 0xff if traffic else 0x00
+        flag_char = 0xff if flag else 0x00
+        if hours > 99:
+            arr = [0x05, traffic_char, self._as_dgt(hours // 1000), self._as_dgt(hours // 100), 0x00,
+                   self._as_dgt(hours // 10), self._as_dgt(hours), 0xff, flag_char]
+        else:
+            arr = [0x05, traffic_char, self._as_dgt(hours // 10), self._as_dgt(hours), 0xff,
+                   self._as_dgt(minutes // 10), self._as_dgt(minutes), 0x00, flag_char]
+        self.send_hud(arr)
+
+    def set_gps(self, state: bool):
+        if state:
+            self.send_hud([0x07, 0x01])
+        self.gps = state
+
+    def set_speed_control(self):
+        self.send_hud([0x04, 0x01])
+
+    def set_compass(self, direction: float):
+        if direction > 337.5 or direction <= 22.5:
+            self.set_direction(OutAngle.Straight, OutType.ArrowOnly)
+        elif 22.5 < direction <= 67.5:
+            self.set_direction(OutAngle.EasyRight, OutType.ArrowOnly)
+        elif 67.5 < direction <= 112.5:
+            self.set_direction(OutAngle.Right, OutType.ArrowOnly)
+        elif 112.5 < direction <= 157.5:
+            self.set_direction(OutAngle.SharpRight, OutType.ArrowOnly)
+        elif 157.5 < direction <= 202.5:
+            self.set_direction(OutAngle.Down, OutType.ArrowOnly)
+        elif 202.5 < direction <= 247.5:
+            self.set_direction(OutAngle.SharpLeft, OutType.ArrowOnly)
+        elif 247.5 < direction <= 292.5:
+            self.set_direction(OutAngle.Left, OutType.ArrowOnly)
+        elif 292.5 < direction <= 337.5:
+            self.set_direction(OutAngle.EasyLeft, OutType.ArrowOnly)
+        self.clear()
+
+    def send_hud(self, buf: list):
+        print("buf", buf)
+        n = len(buf)
+        chars = []
+        crc = uint8(0xeb + n + n)
+        chars.append(0x10)
+        chars.append(0x7b)
+        chars.append(n + 6)
+        if n == 0xa:
+            chars.append(0x10)
+        chars.append(n)
+        chars.append(0x00)
+        chars.append(0x00)
+        chars.append(0x00)
+        chars.append(0x55)
+        chars.append(0x15)
+        for char in buf:
+            crc = uint8(crc + char)
+            chars.append(char)
+            if char == 0x10:
+                chars.append(0x10)
+        chars.append((-crc) & 0xff)
+        chars.append(0x10)
+        chars.append(0x03)
+        self.send_packet(chars)
+
+    def send_packet(self, buff):
+        print("raw", buff)
+        encoded = [bytes(chr(char), 'raw_unicode_escape') for char in buff]
+        print("enc", encoded)
+        # for char in buff:
+        #     self.ser.write(bytes(chr(char), 'raw_unicode_escape'))
+        # time.sleep(0.2)
+        # print(self.ser.read_all())
+
+
+def test():
+    c.set_direction(OutAngle.Straight, OutType.Lane)
+    target = 100
+    for i in range(10):
+        c.set_distance(target, Unit.Kilometres)
+        time.sleep(0.5)
+        target -= 1
+    c.set_speed_control()
+    time.sleep(0.5)
+    for i in range(10):
+        c.set_distance(target, Unit.Kilometres)
+        time.sleep(0.5)
+        target -= 1
+    c.set_direction(OutAngle.Right, OutType.LongerLane)
+    for i in range(10):
+        c.set_distance(target, Unit.Kilometres)
+        time.sleep(0.5)
+        target -= 1
+
+
+if __name__ == '__main__':
+    c = Controller()
+    test()
diff --git a/app/test.py b/app/test.py
new file mode 100644
index 0000000..10388cc
--- /dev/null
+++ b/app/test.py
@@ -0,0 +1,31 @@
+from numpy import uint8
+
+
+def send_hud(buf: list):
+    n = len(buf)
+    chars = []
+    crc = uint8(0xeb + n + n)
+    chars.append(0x10)
+    chars.append(0x7b)
+    chars.append(n + 6)
+    if n == 0xa:
+        chars.append(0x10)
+    chars.append(n)
+    chars.append(0x00)
+    chars.append(0x00)
+    chars.append(0x00)
+    chars.append(0x55)
+    chars.append(0x15)
+    for char in buf:
+        crc = uint8(crc + char)
+        chars.append(char)
+        if char == 0x10:
+            chars.append(0x10)
+    chars.append((-crc) & 0xff)
+    chars.append(0x10)
+    chars.append(0x03)
+    print(chars)
+    print([bytes(chr(char), 'raw_unicode_escape') for char in chars])
+
+
+send_hud([0x04, 0x01])