from app_tools_zxw.SDK_硬件读写.串口_网口_通讯封装.串口读写 import serial串口读写设备
from configs import led_总指示屏端口


class _led文字控制(serial串口读写设备):
    # 覆写 - 参数配置
    波特率 = 9600  # 57600
    读取字节长度 = 8

    # 覆写 - 定义返回数据格式（re）
    def _接受校验(self, d: str) -> bool:
        return True

    # 覆写 - 数据提取与转换
    def _提取数据(self, origin16Data: str):
        return origin16Data


class 修改LED显示屏文字:
    """
    为确保串口通信安全，仅能使用 with ... as ... 语法
    """
    led: _led文字控制

    def __enter__(self):
        self.led = _led文字控制(端口=led_总指示屏端口, 是否持续接受消息=False, timeout=2)
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        try:
            self.led.COM.DColsePort()
        except:
            print("修改LED显示屏文字 -> __exit__ -> 串口关闭失败")
            # 退出时删除变量
            # 删除串口变量时，默认关闭串口() ： 串口读写 -> app应用级封装 -> __del__

    def send更改命令(self, text: str, 行号=1, 显示方式=1, 刷新速度=1):
        # 生成命令
        cmd_Int = self._生成命令(行号, 显示方式, 刷新速度, color=0, text=text)
        # 发送命令
        try:
            re = self.led.写入数据_整数列表命令(cmd_Int)
            return re
        except:
            print("错误, LED串口命令发送失败")
            return 0

    def 修改ip地址(self):
        cmd = [0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xFE, 0xFF, 0x00, 0x8000, 0x00, 0x00, 0x00, 0x00, 0x00,
               0xFE, 0x02, 0x31, 0x00,
               0xA4, 0x05, 0x01, 0x00, 0x00,  # 命令
               0x02,  # 控制器连接模式:02 = 手动设置IP
               0xC0, 0xA8, 0x00, 0xEB,  # IP地址:192.168.0.235
               0xFF, 0xFF, 0xFF, 0x00,  # 子网掩码:255.255.255.0
               0xC0, 0xA8, 0x00, 0x01,  # 默认网关:192.168.0.1
               0x8D, 0x13,  # 端口号
               0x00,  # 服务器模式是否能使用：0禁止，1可以
               0xC0, 0xA8, 0x00, 0x01,  # 服务器IP
               0x71, 0x17,  # 服务器端口
               0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,  # 服务器访问密码
               0x14, 0x00,  # 心跳时间间隔（秒）
               0x42, 0x58, 0x2D, 0x4E, 0x45, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31,  # 控制网络ID
               0x69, 0x06, 0x5A]
        re = self.led.写入数据_整数列表命令(cmd)
        print(re)
        return re

    def 修改mac地址(self):
        cmd = [0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xFE, 0xFF, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
               0x00, 0xFE, 0x02, 0x0B, 0x00,
               0xA4, 0x06, 0x01, 0x00, 0x00,
               0x00, 0xFF, 0xFE, 0x83, 0xA8, 0x56,  # MAC地址
               0x1C, 0x2C, 0x5A]
        re = self.led.写入数据_整数列表命令(cmd)
        print(re)
        return re

    @classmethod
    def __check_sum(cls, data):
        a = 0x00
        for byte in data:
            a += byte
        return a & 0xff

    @classmethod
    def _生成命令(cls, 行号, 刷新速度, color, text):
        """
        显示方式: 01 静止  02 左移   文字一行显示不完全则左移 （显示方式一位将无效）
        刷新速度:  0-250 数值越大移动慢
        行号取值为: 第一行：0x01，第二行：0x02，第三行：0x03）
        颜色取值为: 红：0x00，绿：0x01，蓝：0x02）
        效验位：   所有数据（除效验位）累加）
        """
        data = []
        st_list = text.encode('gb2312')

        # 包头
        data = data + [0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5]
        data.append(0x01)
        data.append(0x00)  # 屏地址
        data.append(行号)  # 屏地址
        data.append(0x8000)  # 源地址
        data += [0x00, 0x00, 0x00, 0x00, 0x00]  # 最后一个为设备类型
        data += [0xFE, 0x02, 0x32, 0x00]

        # 命令
        data += [0xA3, 0x06, 0x01, 0x2D, 0x00]  # 发送实时显示信息
        # 要删除的区域个数（此值为 0 则下一个参数“删除的区域 ID 号”不发送。此值在以下情况下使
        # 用：动态区域个数有变化或者区域位置有变动时。用于删除之前的动态区。默认为0）
        data += [0x00]
        data += [0x01, 0x29, 0x00]  # 动态区数据长度
        # 区域数据格式
        data += [0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
                 0x00, 0x02, 0x02, 0x03, 0x00, 0x04, 0x05, 0x0E, 0x00, 0x00, 0x00]
        # 显示信息“012345QRSTTV’B”
        st_list = [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x51, 0x52, 0x53, 0x54, 0x54, 0x56, 0x27, 0x42]
        for x in st_list:
            data.append(x)
        #
        data.append(cls.__check_sum(data))
        data.append(0x5A)

        demo命令 = [0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0x01, 0x00, 0x00, 0x8000, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0xFE, 0x02, 0x32, 0x00, 0xA3, 0x06, 0x01, 0x2D, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03,
                  0x00, 0x04, 0x05, 0x0E, 0x00, 0x00, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x51, 0x52, 0x53, 0x54,
                  0x54, 0x56, 0x27, 0x42, 0xA8, 0x7D, 0x5A]

        return data


if __name__ == '__main__':
    import random

    while True:
        with 修改LED显示屏文字() as x:
            x.send更改命令(f"first line: {random.randint(0, 100)}", 行号=1)
            x.send更改命令(f"second line: {random.randint(0, 100)}", 行号=2)
            # x.led.COM.DColsePort()
        # time.sleep(0.1)
