| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import struct
- import time
- from .BxCmd import baseBxCmd
- from .BxCmdCode import CMD_WRITE_FILE, CMD_START_WRITE_FILE
- from .BxUtils import CRC16, Uint2BCD
- class bxFile:
- """普通文本文件"""
- def __init__(self, fileName, diedLine, areas):
- self.type_ = 0x00 # 默认0x00
- self.name = fileName # 4字节ASCII
- self.len = 0
- self.content = ""
- self.Priority = 0xff
- self.DisplayType = 0 # 播放方式节目播放方式,0——顺序播放,其他——定长播放的 时间,单位为秒
- self.PlayTimes = 1
- self.ProgramLife = diedLine # 节目生命周期
- self.ProgramWeek = 1 # 节目的星期属性
- self.ProgramTime = 0 # 定时节目位 0 非定时
- self.PlayPeriodGrpNum = 0 # 节目播放时段组数
- self.Areas = areas if areas else [] # 区域列表
- def NewCmdWriteFile(self):
- """创建文件写入命令"""
- return CmdWriteFile(self)
- def encodeProgramLife(self):
- """编码节目生命周期"""
- if self.ProgramLife == "":
- return bytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
-
- now = time.localtime()
- y = Uint2BCD(now.tm_year, False)
- m = Uint2BCD(now.tm_mon, False)
- d = Uint2BCD(now.tm_mday, False)
-
- result = bytearray()
- result.append(y)
- result.append(m)
- result.append(d)
-
- try:
- # 解析过期时间
- end = time.strptime(self.ProgramLife, "%Y-%m-%d")
- endY = Uint2BCD(end.tm_year, False)
- endM = Uint2BCD(end.tm_mon, False)
- endD = Uint2BCD(end.tm_mday, False)
- result.append(endY)
- result.append(endM)
- result.append(endD)
- except Exception as e:
- print(f"时间解析错误: {e}")
- return bytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
-
- return bytes(result)
- class CmdWriteFile(baseBxCmd):
- """文件写入命令"""
- def __init__(self, file):
- super().__init__(CMD_WRITE_FILE.group, CMD_WRITE_FILE.code)
- self.state = 0
- self.file = file
- self.LastBlockFlag = 0x01 # 是否是最后一包,0x00——不是最后一包 0x01——最后一包
- self.BlockNum = 0x00 # 包号,如果是单包发送,则默认为 0x00
- self.BlockLen = 0 # 包长,若是单包发送,此处为文件长度
- self.BlockAddr = 0 # 本包数据在文件中的起始位置,如果是单包发送,此处默认为 0
- self.temp = []
- def Build(self):
- """构建命令数据"""
- if self.state == 0:
- # 先计算区域数据及长度
- w0 = bytearray()
- for v in self.file.Areas:
- b = v.Build()
- w0.extend(struct.pack('<I', len(b) + 4))
- w0.extend(b)
-
- l = len(w0) + 27
- self.BlockLen = l
- self.file.len = l
-
- # Write File
- w1 = bytearray()
- # 文件描述数据
- w1.append(self.Group())
- w1.append(self.Cmd())
- w1.append(0x01)
- w1.extend([0x00, 0x00])
- # 写入文件名(4字节ASCII)
- name_bytes = self.file.name.encode('ascii')[:4]
- name_bytes = name_bytes.ljust(4, b'\x00')
- w1.extend(name_bytes)
- w1.append(self.LastBlockFlag) # 是否是最后一包
- w1.extend(struct.pack('<H', self.BlockNum)) # 包号
- w1.extend(struct.pack('<H', self.BlockLen)) # 包长
- w1.extend(struct.pack('<I', self.BlockAddr)) # 偏移量
-
- # 文件内容数据
- w2 = bytearray()
- w2.append(self.file.type_)
- # 写入文件名(4字节ASCII)
- w2.extend(name_bytes)
- w2.extend(struct.pack('<I', self.file.len))
- w2.append(self.file.Priority)
- w2.extend(struct.pack('<H', self.file.DisplayType))
- w2.append(self.file.PlayTimes)
- w2.extend(self.file.encodeProgramLife())
- w2.append(self.file.ProgramWeek)
- w2.append(self.file.ProgramTime)
- w2.append(self.file.PlayPeriodGrpNum)
- w2.append(len(self.file.Areas))
- w2.extend(w0)
-
- b2 = bytes(w2)
- w1.extend(b2)
- crc16 = CRC16(b2, 0, len(b2))
- w1.extend(struct.pack('<H', crc16))
-
- self.temp = bytes(w1)
-
- # Start Write File "开始写文件",写文件前先检查内存是否够用
- w3 = bytearray()
- w3.append(CMD_START_WRITE_FILE.group)
- w3.append(CMD_START_WRITE_FILE.code)
- w3.append(0x01)
- w3.extend([0x00, 0x00])
- w3.append(0x01) # 同名是否覆盖,0不覆盖,1覆盖
- w3.extend(name_bytes) # 写入文件名(4字节ASCII)
- w3.extend(struct.pack('<I', self.file.len))
-
- self.state = 1
- return bytes(w3)
- else:
- return self.temp
- class cmdFileBeginWrite(baseBxCmd):
- """开始写文件命令"""
- def __init__(self):
- super().__init__(CMD_START_WRITE_FILE.group, CMD_START_WRITE_FILE.code)
- # 创建bxFile实例的函数
- def NewBxFile(fileName, diedLine, areas):
- """创建bxFile实例"""
- return bxFile(fileName, diedLine, areas)
|