# -*- coding: UTF-8 -*-
import re
import time
from baseSerail import BaseSerial

class CASerail(BaseSerial):
    def __init__(self):
        BaseSerial.__init__(self)
    
    def __del__(self):
        self.close()
    
    # 用于发命令前,检测串口是否打开;
    def checkport(self):
        if not self.ser.is_open:
            self.reOpen()
        
        return self.ser.is_open
    
    def sendcmd(self, cmd:str):
        self.write(cmd.encode('utf-8'))
        return self.read()
    
    '''开启通讯'''
    def startCommunication(self):
        self.sendcmd('COM,1\r')

    '''结束通讯'''
    def endCommunication(self):
        self.sendcmd('COM,0\r')

    '''设置用于测量的校准通道'''
    def setChannel(self, channel:str):
        self.sendcmd('MCH,%s\r'%(channel))

    '''
    设置显示模式
    mode:0-8
    0: x,y,Lv
    1: Tcp,duv,Lv
    5: u',v',Lv
    6: Flicker mode
    7: X,Y,Z
    8: λd,Pe,Lv
    '''
    def setDisplayMode(self, mode:int):
        return self.sendcmd('MDS,%d\r'%(mode))

    
    def set_XYZ_Display(self):
        return self.sendcmd('MDS,%d\r'%(7))


    def set_xyLv_Display(self):
        return self.sendcmd('MDS,%d\r'%(0))

    '''
    设置同步模式和同步频率
    mode:同步模式,0-5
        0：NTSC
        1:PAL
        2: EXTERNAL
        3: UNIVERSAL
        4: INTERNAL
        5: MANUAL
    freq:同步频率,1-6;
    '''
    def setSynchMode(self, mode: int, freq: int = None):
        if freq == None:
            return self.sendcmd('SCS,%d\r'%(mode))
        else:
            return self.sendcmd('SCS,%d,%d\r'%(mode,freq))

    '''
    设置测量速度
    speed: 0-3
        0: SLOW
        1: FAST
        2: LTD.AUTO
        3: AUTO
    '''
    def setMeasureSpeed(self, speed: int):
        return self.sendcmd('FSC,%d\r'%(speed))
    

    '''执行零点校准'''
    def setZeroCalibration(self):
        return self.sendcmd('ZRC\r')

    def readDisplay(self):
        data = self.sendcmd('MES\r')
        return self.__get_display_data(data.decode('utf-8'))

    def __readxyLv2(self):
        return self.sendcmd('MES,1\r')

    def __readXYZ(self):
        data = self.sendcmd('MES,2\r')
        # bytearray转str:使用decode。
        result, des, X,Y,Z = self.__get_XYZ_data(data.decode('utf-8'))
        return X,Y,Z


    def __get_display_data(self, data):
        # 正则表达式;
        # OK00,P1 3716;3956;.0091\r
        p = re.compile(r"(\D*)(\d+),P1 (.*);(.*);(.*)", re.DOTALL)
        mo = p.search(data)
        if mo is None:
            print("无匹配正则")
            pw = re.compile(r"(\D*)(\d+)", re.DOTALL)
            mo = pw.search(data)
            if mo is None:
                # print("短匹配失败")
                return None, None, None
            else:
                return None, None, None
        else:
            print(mo.group(1), mo.group(2), mo.group(3), mo.group(4), mo.group(5))
            return mo.group(3), mo.group(4), mo.group(5)


    def __get_XYZ_data(self, data):
        # 正则表达式;
        # 'OK00,P1,0,0.2265919,0.1769892,0.0437458,-0.03,-99999999,0.0560060,0.0437458,0.1474149\r'
        p = re.compile(r"(\D*)(\d+),P1,(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*)\r", re.DOTALL)
        mo = p.search(data)
        if mo is None:
            print("无匹配正则")
            pw = re.compile(r"(\D*)(\d+)", re.DOTALL)
            mo = pw.search(data)
            if mo is None:
                # print("短匹配失败")
                return False, u"异常", None, None, None,
            else:
                return False, mo.group(2), None, None, None
        else:
            print(mo.group(1), mo.group(2), mo.group(3), mo.group(4), mo.group(5), mo.group(6), mo.group(7), mo.group(8), mo.group(9), mo.group(10), mo.group(11))
            return True, mo.group(1), mo.group(9), mo.group(10), mo.group(11)


def xyY_to_XYZ( x, y, Y):
    X = x * Y / y
    Z = (1 - x - y) * Y / y
    return X, Y, Z


def test_ca410():
    print('\r\rtest ca410\r\r')
    ca = CASerail()
    ca.open("COM8", 19200, 7, 'E', 2)
    ca.startCommunication()
    ca.set_XYZ_Display()
    ca.setSynchMode(3)
    ca.setMeasureSpeed(2)
    ca.setZeroCalibration()
    ca.setChannel('01')
    X,Y,Z=ca.readDisplay()
    print("\rthe XYZ = ",float(X), float(Y), float(Z))
    ca.endCommunication()


def test_ca310():
    print('\r\rtest ca310\r\r')
    ca = CASerail()
    ca.open("COM6", 19200, 7, 'E', 2)
    ca.startCommunication()
    ca.setChannel('01')
    ca.setSynchMode(3)
    ca.setMeasureSpeed(2)
    #ca.set_xyLv_Display()
    ca.set_XYZ_Display()
    X,Y,Z=ca.readDisplay()
    print("\rthe XYZ = ",float(X), float(Y), float(Z))
    ca.endCommunication()


if __name__ == "__main__":
    test_ca410()
    test_ca310()
    X,Y,Z = xyY_to_XYZ(0.226, 0.171, 0.040)
    print("xyLv=(%f,%f,%f), XYZ=(%f,%f,%f)"%(0.226, 0.171, 0.04, X,Y,Z))