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

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

    '''
    设置显示模式
    '''
    def setDisplayMode(self, mode:int):
        return self.sendcmd('MDS,%d\r'%(mode))

    '''设置显示模式为XYZ'''
    def set_XYZ_Display(self):
        return self.sendcmd('MDS,%d\r'%(7))

    '''设置显示模式为xyLv'''
    def set_xyLv_Display(self):
        return self.sendcmd('MDS,%d\r'%(0))

    '''设置显示模式为xyLv'''
    def set_all_Display(self):
        return self.sendcmd('MDS,%d\r'%(0))

    def set_Display(self, mode:int):
        '''
        0: x,y,LV
        1: Tcp,duv,LV
        5: u’,v’,LV
        7: X,Y,Z
        8: λd,Pe,LV
        '''
        return self.sendcmd('MDS,%d\r'%(mode))
    

    '''
    设置同步模式和同步频率
    '''
    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))

    '''
    设置测量速度
    '''
    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')
        x,y,z = self.__get_display_data(data.decode('utf-8'))
        return float(x), float(y), float(z)

    '''获取当前显示模式值'''
    def __get_display_data(self, data):
        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 readAllDisplay(self):
        data = self.sendcmd('MES,2\r')
        x,y,lv,X,Y,Z = self.__get_all_display_data(data.decode('utf-8'))
        return float(x), float(y), float(lv), float(X), float(Y), float(Z)

    '''获取所有显示模式值'''
    def __get_all_display_data(self, data):
        p = re.compile(r"(\D*)(\d+),P1,(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*),(.*)", re.DOTALL)
        mo = p.search(data)
        if mo is None:
            return None, None, None, None, None, None
        else:
            return mo.group(4), mo.group(5), mo.group(6), 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 XYZ_to_lambda_pe(XYZ, illuminant='D65'):
    xy = colour.XYZ_to_xy(XYZ)
    white = colour.CCS_ILLUMINANTS['CIE 1931 2 Degree Standard Observer'][illuminant]
    λd, comp, xy_intersection = colour.dominant_wavelength(xy, white)
    Pe = colour.excitation_purity(xy, white)
    return xy, λd, comp, Pe


def test_ca410():
    print('\r\rtest ca410\r\r')
    ca = CASerail()
    ca.open("COM3", 19200, 7, 'E', 2)
    ca.startCommunication()
    ca.setSynchMode(3)
    ca.setMeasureSpeed(2)
    ca.setZeroCalibration()
    ca.setChannel('01')

    ca.set_Display(0)
    xyYXYZ = ca.readAllDisplay()
    print(f"xyYXYZ: {xyYXYZ}")
    XYZ = xyYXYZ[3], xyYXYZ[4], xyYXYZ[5]
    xy = colour.XYZ_to_xy(XYZ)
    print(f"xy: {xy}")

    ca.set_Display(1)
    tcpduvlvXYZ = ca.readAllDisplay()
    print(f"tcpduvlvXYZ: {tcpduvlvXYZ}")
    XYZ = tcpduvlvXYZ[3], tcpduvlvXYZ[4], tcpduvlvXYZ[5]
    xy = colour.XYZ_to_xy(XYZ)
    TCP = colour.temperature.xy_to_CCT(xy, 'Hernandez 1999')
    print(f"TCP: {TCP}K")

    ca.set_Display(5)
    uvlvXYZ = ca.readAllDisplay()
    print(f"uvlvXYZ: {uvlvXYZ}")
    XYZ = uvlvXYZ[3], uvlvXYZ[4], uvlvXYZ[5]
    xy = colour.XYZ_to_xy(XYZ)
    u_prime, v_prime, _ = colour.XYZ_to_CIE1976UCS(XYZ)
    print(f"u': {u_prime}, v': {v_prime}")


    ca.set_Display(8)
    lambdaPeXYZ = ca.readAllDisplay()
    print(f"lambdaPeXYZ: {lambdaPeXYZ}")
    XYZ = lambdaPeXYZ[3], lambdaPeXYZ[4], lambdaPeXYZ[5]
    xy, λd, isComplementary, Pe = XYZ_to_lambda_pe(XYZ)
    print(f"xy: {xy}, λd: {λd}, isComplementary: {isComplementary}, Pe: {Pe}")


    ca.endCommunication()

# test_ca410()