重构移动utils文件夹

This commit is contained in:
xinzhu.yin
2026-04-20 11:48:38 +08:00
parent b6c1c2ab93
commit 2e92b48496
27 changed files with 2866 additions and 3085 deletions

423
drivers/tvSerail.py Normal file
View File

@@ -0,0 +1,423 @@
# -*- coding: UTF-8 -*-
import zlib
from xmlrpc.client import Boolean
from drivers.baseSerail import BaseSerial
import binascii
import drivers.baseSerail as baseSerail
# 包头码(包引导码)
PHeader = {
"TV_Debug": 0xAA,
"TV_Return": 0xAB,
"TV_Panel_Debug": 0xAC,
"TV_Panel_Return": 0xAD,
"TV_Debug_Other": 0xAE,
"TV_Other_Return": 0xAF,
}
# 命令结果码;
RCode = {
"RC_OK": 0x0A, # 命令执行通过;
"RC_ERR": 0x0E, # 命令错误或无法执行;
"RC_LOSE": 0x0F, # 命令丢失(链路层出错);
}
# 命令的封装与解析;
class TvParse():
def __init__(self):
# 头引导码(默认1字节,0x86命令二字节);
self.Header = [PHeader['TV_Debug']]
# 包长(默认1字节,0x86长度二字节);
self.Length = [0x00]
# 命令码,1字节(int类型);
self.Command = [0x00]
# 子命令参数;
self.SubCommand = []
# 数据,bytearray格式;
self.Data = []
# crch,1字节;
self.CRCH = 0xFF
# crcl,1字节;
self.CRCL = 0xFF
# 是否是特殊命令;
self.FEFlag = False
# 是否是多参数命令;(同一个Command有多个含义的参数)
self.isMultipleParams = False
# 正确执行后的结果值bytearray格式的二维数组;
self.successData = []
def parseCommand(self, head: int, command: list[int], subCommand: list[int] = [], data: bytearray = bytearray(), isMultipleParams=False, FEFlag=False):
self.Header[0] = head
self.Command = command
self.SubCommand = subCommand
self.Data = data
self.FEFlag = FEFlag
self.isMultipleParams = isMultipleParams
if FEFlag:
self.Header.append(0xFE)
# 注意4 = crch + crcl + lenh + lenl
length = 4 + self.Header.__len__() + self.Data.__len__() + self.Command.__len__() + self.SubCommand.__len__()
# 高字节;
self.Length[0] = length >> 8
# 低字节;
self.Length.append(length & 0xFF)
else:
# 注意3 = crch + crcl + len
self.Length[0] = 3 + self.Header.__len__() + self.Data.__len__() + self.Command.__len__() + self.SubCommand.__len__()
# 生成package;
package = bytearray(self.Header + self.Length + self.Command + self.SubCommand) + self.Data
self.calculateCRC(package)
# 形成最终的命令;
package = bytearray(self.Header + self.Length + self.Command + self.SubCommand) + self.Data + bytearray([self.CRCH, self.CRCL])
# 打印最终命令的十六进制形式,每两个字符之间加一个空格
# hex_string = ' '.join(f'{byte:02X}' for byte in package)
# print("最终命令的十六进制形式:", hex_string)
return package
def calculateCRC(self, data: bytearray):
crc = baseSerail.crc16(data, data.__len__())
# 高字节;
self.CRCH = crc >> 8
# 低字节;
self.CRCL = crc & 0xFF
def parseCommandFc(self, head: int, command: list[int], subCommand: list[int] = [], data: bytearray = bytearray(), isMultipleParams=False):
self.Header[0] = head
self.Command = command
self.SubCommand = subCommand
self.Data = data
self.isMultipleParams = isMultipleParams
self.Length[0] = 3 + self.Header.__len__() + self.Data.__len__() + self.Command.__len__() + self.SubCommand.__len__()
package = bytearray(self.Header + self.Length + self.Command + self.SubCommand) + self.Data
self.calculateCRC(package)
package = bytearray(self.Header + self.Length + self.Command + self.SubCommand) + self.Data + bytearray([self.CRCH]) + bytearray([self.CRCL])
return package
# 成功返回AB 08 FC 08 EC 80 CR1 CR2
# 失败返回AB 08 FC 08 EC 00 CR1 CR2
def parseResultFc(self,data):
data = bytearray(data)
return False
def parseResult(self, data):
data = bytearray(data)
if data.__len__() < 5:
return False
retCode = 0
if self.Header[0] == PHeader['TV_Debug']:
retCode = PHeader['TV_Return']
elif self.Header[0] == PHeader['TV_Panel_Debug']:
retCode = PHeader['TV_Panel_Return']
elif self.Header[0] == PHeader['TV_Debug_Other']:
retCode = PHeader['TV_Other_Return']
if retCode != data[0]:
return False
package = []
tooken_len = 0
return True
def parseString(self, data):
data = bytearray(data)
if data.__len__() < 5:
return False
retCode = 0
if self.Header[0] == PHeader['TV_Debug']:
retCode = PHeader['TV_Return']
elif self.Header[0] == PHeader['TV_Panel_Debug']:
retCode = PHeader['TV_Panel_Return']
elif self.Header[0] == PHeader['TV_Debug_Other']:
retCode = PHeader['TV_Other_Return']
if retCode != data[0]:
return False
package = []
tooken_len = 0
while True:
if tooken_len >= data.__len__():
break
if self.FEFlag:
package_len = data[tooken_len + 1] << 8 + data[tooken_len + 2]
else:
package_len = data[tooken_len + 1]
package = data[tooken_len:tooken_len + package_len]
if package[0] != retCode:
print('Incorrect package head!\n')
return False
crc = crc16(package, package_len - 2)
CRCH = crc >> 8
CRCL = crc & 0xFF
if CRCH != package[-2] and CRCL != package[-1]:
return False
if tooken_len == 0:
if package[2] != RCode['RC_OK']:
return False
else:
if self.Command[0] == 0xFC:
pass
else:
if package[2] - 1 != self.Command[0]:
return False
if package[2] == 0xFE:
self.successData.append(package[5:-2])
else:
self.successData.append(package[3:-2])
tooken_len += package_len
# print('successData:', binascii.b2a_hex(bytearray(self.Command)), self.successData)
return self.successData
class tvSerial(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: list[int]):
self.write(bytearray(cmd))
return self.read()
'''协议模式发送命令'''
def sendcmdEx(self, head: int, command: list[int], subCommand: list[int] = [], data: bytearray = bytearray(), FEFlag: Boolean = False, returnParam: Boolean = False):
cmd = TvParse()
package = cmd.parseCommand(head, command, subCommand, data, returnParam, FEFlag)
if self.write(package):
package = self.read()
return cmd.parseResult(package)
return False
def sendcmdEx_string_return(self, head: int, command: list[int], subCommand: list[int] = [], data: bytearray = bytearray(), FEFlag: Boolean = False, returnParam: Boolean = False):
cmd = TvParse()
package = cmd.parseCommand(head, command, subCommand, data, returnParam, FEFlag)
if self.write(package):
package = self.read()
return cmd.parseString(package)
return ""
def sendcmdFc(self, head: int, command: list[int], subCommand: list[int] = [], data: bytearray = bytearray(), FEFlag: Boolean = False, returnParam: Boolean = False):
cmd = TvParse()
package = cmd.parseCommand(head, command, subCommand, data, returnParam, FEFlag)
if self.write(package):
package = self.read()
return cmd.parseResult(package)
return False
def gen_zzip(selfe,gm_file,save_file):
with open(gm_file, 'rb') as f:
data = f.read()
compressed_data = zlib.compress(data)
with open(save_file, 'wb') as f:
f.write(compressed_data)
'''发送pattern'''
def send_parttern(self, rgb: list[int]):
cmd = TvParse()
package = cmd.parseCommand(0xAA, [0x28], [], bytearray(rgb))
if self.write(package):
package = self.read()
return cmd.parseResult(package)
return False
# '''发送10bit-pattern'''
# def send_10_bit_parttern(self, rgb: list[int]):
# cmd = MokaParse()
# rgb16 = convert_rgb16(rgb)
# package = cmd.parseCommandFc(0xAA, [0xFC,0x07,0x06], [0xEC,0x01,0x86,0x00], rgb16)
# if self.write(package):
# package = self.read()
# return cmd.parseResult(package)
# return False
'''发送12bit-pattern'''
def send_12_bit_parttern(self, rgb: list[int]):
cmd = TvParse()
rgb16 = baseSerail.convert_rgb16(rgb)
package = cmd.parseCommand(0xAA, [0x28], [], rgb16)
if self.write(package):
package = self.read()
return cmd.parseResult(package)
return False
'''发送gamma文件'''
def send_gamma(self, file_path: str):
fp = open(file_path, 'rb')
cmd = TvParse()
data = fp.read()
# 生成命令包
package = cmd.parseCommand(0xAA, [0xE9], [0x02], data, False, True)
# 将命令包写入临时文件
if self.write(package):
package = self.read()
print(cmd.parseResult(package))
return cmd.parseResult(package)
'''激活gamma文件'''
def send_gamma_active(self, ini_file: str):
ini_fp = open(ini_file, 'rb')
ind_data = ini_fp.read()
ini_fp.close()
# 计算crc
crc = crc16(ind_data, ind_data.__len__())
CRC_GM = [crc >> 8, crc & 0xFF]
cmd = TvParse()
package = cmd.parseCommand(0xAA, [0x99], [0x06], bytearray(CRC_GM))
if self.write(package):
package = self.read()
print("---------------------")
print(cmd.parseResult(package))
return cmd.parseResult(package)
'''激活gamma文件-12bit版本'''
def send_gamma_active_12bit(self, ini_file: str):
ini_fp = open(ini_file, 'rb')
ind_data = ini_fp.read()
ini_fp.close()
# 计算crc
crc = baseSerail.crc16(ind_data, ind_data.__len__())
CRC_GM = [crc >> 8, crc & 0xFF]
cmd = TvParse()
package = cmd.parseCommandFc(0xAA, [0xFC,0x07], [0x0E], bytearray(CRC_GM))
if self.write(package):
package = self.read()
print("---------------------")
print(cmd.parseResult(package))
return cmd.parseResult(package)
'''进工厂模式'''
def enterFactory(self):
return self.sendcmdEx(0xAA, [0x10], [0x01])
'''白平衡初始化'''
def initWhiteBalance(self):
return self.sendcmdEx(0xAA, [0x16], [0x01])
'''关闭localdimming'''
def closeLocaldimming(self):
return self.sendcmdEx(0xAA, [0x9F,0x07], [0x00])
'''打开内置pattern'''
def openBuiltInPattern(self):
return self.sendcmdEx(0xAA, [0x27], [0x01])
'''关闭内置pattern'''
def closeBuiltInPattern(self):
return self.sendcmdEx(0xAA, [0x27], [0x00])
'''切换标准色温'''
def switchStdColorTemperature(self):
return self.sendcmdEx(0xAA, [0x31], [0x01])
'''切换冷色温'''
def switchColdColorTemperature(self):
return self.sendcmdEx(0xAA, [0x31], [0x02])
'''切换暖色温'''
def switchWarmColorTemperature(self):
return self.sendcmdEx(0xAA, [0x31], [0x03])
'''切换暖2色温'''
def switchWarm2ColorTemperature(self):
return self.sendcmdEx(0xAA, [0x31], [0x04])
'''初始化gamma'''
def initGamma(self):
return self.sendcmdEx(0xAA, [0x9F,0x09], [0x01])
'''进老化模式'''
def enterAgingMode(self):
return self.sendcmdEx(0xAA, [0x13], [0x01])
'''退出老化模式'''
def exitAgingMode(self):
return self.sendcmdEx(0xAA, [0x13], [0x00])
'''软件版本查询'''
def sendSoftwareVersionQuery(self):
return self.sendcmdEx_string_return(0xAA, [0x57], [0x00])
'''PID查询'''
def sendPIDQuery(self):
return self.sendcmdEx_string_return(0xAA, [0x84], [0x00])
def switchHDMI1(self):
"""切换到HDMI1信源"""
return self.sendcmdEx(0xAA, [0x25], [0x01])
def switchHDMI2(self):
"""切换到HDMI2信源"""
return self.sendcmdEx(0xAA, [0x25], [0x02])
def switchHDMI3(self):
"""切换到HDMI3信源"""
return self.sendcmdEx(0xAA, [0x25], [0x03])
def switchVGA(self):
"""切换到VGA信源"""
return self.sendcmdEx(0xAA, [0x24], [0x01])
def switchAV1(self):
"""切换到AV1信源"""
return self.sendcmdEx(0xAA, [0x22], [0x01])
def switchAV2(self):
"""切换到AV2信源"""
return self.sendcmdEx(0xAA, [0x22], [0x02])
def switchAV3(self):
"""切换到AV3信源"""
return self.sendcmdEx(0xAA, [0x22], [0x03])
def switchDisplayMode(self, mode="natural"):
"""切换图像预设模式 """
if mode == "natural":
return self.sendcmdEx(0xAA, [0x30], [0x01])
elif mode == "soft":
return self.sendcmdEx(0xAA, [0x30], [0x02])
elif mode == "bright":
return self.sendcmdEx(0xAA, [0x30], [0x03])
elif mode == "personal":
return self.sendcmdEx(0xAA, [0x30], [0x04])
elif mode == "cinematic":
return self.sendcmdEx(0xAA, [0x30], [0x05])
else:
raise ValueError("Invalid display mode. Use 'natural', 'soft', 'bright', 'personal', or 'cinematic'.")
if __name__ == "__main__":
pass