# -*- coding: UTF-8 -*-
import serial
import time
import binascii

# CRC16矩阵表;
CRC_TABLE = [
    0x0000, 0x1021, 0x2042, 0x3063,
    0x4084, 0x50A5, 0x60C6, 0x70E7,
    0x8108, 0x9129, 0xA14A, 0xB16B,
    0xC18C, 0xD1AD, 0xE1CE, 0xF1EF ]


# 计算CRC16值;
def crc16(bys, bysLen):
    uwCRC, ucTemp = 0xFFFF, 0x00
    index = 0
    while index < bysLen:
        ucTemp = (uwCRC >> 0x0C) & 0xFF
        uwCRC <<= 4
        uwCRC ^= CRC_TABLE[ucTemp ^ ((bys[index]) >> 0x04)]
        uwCRC &= 0xFFFF
        ucTemp = (uwCRC >> 0x0C) & 0xFF
        uwCRC <<= 4
        uwCRC ^= CRC_TABLE[ucTemp ^ (bys[index] & 0x0F)]
        uwCRC &= 0xFFFF
        index += 1
    return uwCRC

def convert_rgb16(rgb16_values):
    data = bytearray()
    for value in rgb16_values:
        high_byte = (value & 0xFF00) >> 8
        low_byte = value & 0x00FF
        
        data.append(high_byte)
        data.append(low_byte)

    return data

class BaseSerial():
    def __init__(self):
        self.exception = None
        self.ser = serial.Serial()

    def open(self, port, baudrate=115200, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=3,
             writeTimeout=3):
        if type(port) == type(0):
            self.ser.port = "COM" + str(port)
        else:
            self.ser.port = port
        # 波特率;
        self.ser.baudrate = baudrate
        # 数据位;
        self.ser.bytesize = bytesize
        # 校验码;
        self.ser.parity = parity  # PARITY_NONE=0
        # 停止位;
        self.ser.stopbits = stopbits
        # 串口读超时值
        self.ser.timeout = timeout
        # 串口写超时值
        self.ser.write_timeout = writeTimeout
        try:
            self.ser.open()
            return self.ser.is_open
        except Exception as e:
            self.exception = e
            print('打开串口异常', str(e))
            return False

    def reOpen(self):
        self.exception = None
        self.ser.close()
        try:
            self.ser.open()
            return self.ser.is_open
        except Exception as e:
            self.exception = e
            return False

    def close(self):
        self.ser.close()

    def write(self, cmd: bytearray):
        try:
            self.exception = None
            writelen = self.ser.write(cmd)
            self.ser.flush()
            # print("writehex:" + str(binascii.b2a_hex(cmd)) + " writelen=" + str(writelen))
            return True if writelen == len(cmd) else False
        except Exception as e:
            self.exception = e
            print('写串口异常', str(e))
            return False

    def read(self, size=0):
        try:
            self.exception = None
            bys = self.ser.read(1)
            for i in range(0, 3):
                while self.ser.in_waiting > 0:
                    d = self.ser.read(1)
                    bys = bys + d
                time.sleep(0.01)

            if bys.__len__() < size:
                time.sleep(0.1)
                if self.ser.in_waiting > 0:
                    d = self.ser.read(self.ser.in_waiting)
                    bys = bys + d
            # print("readhex:" + str(binascii.hexlify(bys)) + " readlen=" + str(bys.__len__()))
            return bys
        except Exception as e:
            self.exception = e
            print('读串口异常', str(e))
            return None