BxCmdFileWrite.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import struct
  2. import time
  3. from .BxCmd import baseBxCmd
  4. from .BxCmdCode import CMD_WRITE_FILE, CMD_START_WRITE_FILE
  5. from .BxUtils import CRC16, Uint2BCD
  6. class bxFile:
  7. """普通文本文件"""
  8. def __init__(self, fileName, diedLine, areas):
  9. self.type_ = 0x00 # 默认0x00
  10. self.name = fileName # 4字节ASCII
  11. self.len = 0
  12. self.content = ""
  13. self.Priority = 0xff
  14. self.DisplayType = 0 # 播放方式节目播放方式,0——顺序播放,其他——定长播放的 时间,单位为秒
  15. self.PlayTimes = 1
  16. self.ProgramLife = diedLine # 节目生命周期
  17. self.ProgramWeek = 1 # 节目的星期属性
  18. self.ProgramTime = 0 # 定时节目位 0 非定时
  19. self.PlayPeriodGrpNum = 0 # 节目播放时段组数
  20. self.Areas = areas if areas else [] # 区域列表
  21. def NewCmdWriteFile(self):
  22. """创建文件写入命令"""
  23. return CmdWriteFile(self)
  24. def encodeProgramLife(self):
  25. """编码节目生命周期"""
  26. if self.ProgramLife == "":
  27. return bytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
  28. now = time.localtime()
  29. y = Uint2BCD(now.tm_year, False)
  30. m = Uint2BCD(now.tm_mon, False)
  31. d = Uint2BCD(now.tm_mday, False)
  32. result = bytearray()
  33. result.append(y)
  34. result.append(m)
  35. result.append(d)
  36. try:
  37. # 解析过期时间
  38. end = time.strptime(self.ProgramLife, "%Y-%m-%d")
  39. endY = Uint2BCD(end.tm_year, False)
  40. endM = Uint2BCD(end.tm_mon, False)
  41. endD = Uint2BCD(end.tm_mday, False)
  42. result.append(endY)
  43. result.append(endM)
  44. result.append(endD)
  45. except Exception as e:
  46. print(f"时间解析错误: {e}")
  47. return bytes([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])
  48. return bytes(result)
  49. class CmdWriteFile(baseBxCmd):
  50. """文件写入命令"""
  51. def __init__(self, file):
  52. super().__init__(CMD_WRITE_FILE.group, CMD_WRITE_FILE.code)
  53. self.state = 0
  54. self.file = file
  55. self.LastBlockFlag = 0x01 # 是否是最后一包,0x00——不是最后一包 0x01——最后一包
  56. self.BlockNum = 0x00 # 包号,如果是单包发送,则默认为 0x00
  57. self.BlockLen = 0 # 包长,若是单包发送,此处为文件长度
  58. self.BlockAddr = 0 # 本包数据在文件中的起始位置,如果是单包发送,此处默认为 0
  59. self.temp = []
  60. def Build(self):
  61. """构建命令数据"""
  62. if self.state == 0:
  63. # 先计算区域数据及长度
  64. w0 = bytearray()
  65. for v in self.file.Areas:
  66. b = v.Build()
  67. w0.extend(struct.pack('<I', len(b) + 4))
  68. w0.extend(b)
  69. l = len(w0) + 27
  70. self.BlockLen = l
  71. self.file.len = l
  72. # Write File
  73. w1 = bytearray()
  74. # 文件描述数据
  75. w1.append(self.Group())
  76. w1.append(self.Cmd())
  77. w1.append(0x01)
  78. w1.extend([0x00, 0x00])
  79. # 写入文件名(4字节ASCII)
  80. name_bytes = self.file.name.encode('ascii')[:4]
  81. name_bytes = name_bytes.ljust(4, b'\x00')
  82. w1.extend(name_bytes)
  83. w1.append(self.LastBlockFlag) # 是否是最后一包
  84. w1.extend(struct.pack('<H', self.BlockNum)) # 包号
  85. w1.extend(struct.pack('<H', self.BlockLen)) # 包长
  86. w1.extend(struct.pack('<I', self.BlockAddr)) # 偏移量
  87. # 文件内容数据
  88. w2 = bytearray()
  89. w2.append(self.file.type_)
  90. # 写入文件名(4字节ASCII)
  91. w2.extend(name_bytes)
  92. w2.extend(struct.pack('<I', self.file.len))
  93. w2.append(self.file.Priority)
  94. w2.extend(struct.pack('<H', self.file.DisplayType))
  95. w2.append(self.file.PlayTimes)
  96. w2.extend(self.file.encodeProgramLife())
  97. w2.append(self.file.ProgramWeek)
  98. w2.append(self.file.ProgramTime)
  99. w2.append(self.file.PlayPeriodGrpNum)
  100. w2.append(len(self.file.Areas))
  101. w2.extend(w0)
  102. b2 = bytes(w2)
  103. w1.extend(b2)
  104. crc16 = CRC16(b2, 0, len(b2))
  105. w1.extend(struct.pack('<H', crc16))
  106. self.temp = bytes(w1)
  107. # Start Write File "开始写文件",写文件前先检查内存是否够用
  108. w3 = bytearray()
  109. w3.append(CMD_START_WRITE_FILE.group)
  110. w3.append(CMD_START_WRITE_FILE.code)
  111. w3.append(0x01)
  112. w3.extend([0x00, 0x00])
  113. w3.append(0x01) # 同名是否覆盖,0不覆盖,1覆盖
  114. w3.extend(name_bytes) # 写入文件名(4字节ASCII)
  115. w3.extend(struct.pack('<I', self.file.len))
  116. self.state = 1
  117. return bytes(w3)
  118. else:
  119. return self.temp
  120. class cmdFileBeginWrite(baseBxCmd):
  121. """开始写文件命令"""
  122. def __init__(self):
  123. super().__init__(CMD_START_WRITE_FILE.group, CMD_START_WRITE_FILE.code)
  124. # 创建bxFile实例的函数
  125. def NewBxFile(fileName, diedLine, areas):
  126. """创建bxFile实例"""
  127. return bxFile(fileName, diedLine, areas)