2026-03-02 14:29:58 +08:00
|
|
|
from datetime import datetime
|
2026-04-16 14:23:37 +08:00
|
|
|
import re, yaml, os
|
|
|
|
|
import xlwings as xw
|
2026-03-02 14:29:58 +08:00
|
|
|
|
|
|
|
|
def wordData2HexStr(data):
|
2026-04-16 14:23:37 +08:00
|
|
|
if data:
|
|
|
|
|
ret = ' '.join(data[i:i+2].hex() for i in range(0, len(data), 2))
|
|
|
|
|
else:
|
|
|
|
|
ret = ''
|
2026-03-02 14:29:58 +08:00
|
|
|
return ret.upper()
|
|
|
|
|
|
|
|
|
|
def nowStr():
|
|
|
|
|
now = datetime.now()
|
|
|
|
|
ret = now.strftime('%Y/%m/%d %H:%M:%S.') + f"{now.microsecond // 1000:03d}"
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
def nowStr1():
|
|
|
|
|
now = datetime.now()
|
|
|
|
|
ret = now.strftime('%Y%m%d%H%M%S')
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
def checkValue(data: bytes) -> int:
|
|
|
|
|
crc = 0xFFFF
|
|
|
|
|
length = len(data)
|
|
|
|
|
if length % 2 != 0:
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
for i in range(0, length, 2):
|
|
|
|
|
val = data[i] * 256 + data[i + 1]
|
|
|
|
|
crc = crc ^ val
|
|
|
|
|
return crc
|
|
|
|
|
|
2026-04-16 14:23:37 +08:00
|
|
|
def add8(datas):
|
|
|
|
|
crc = 0x00
|
|
|
|
|
for i in range(len(datas)):
|
|
|
|
|
crc = crc + datas[i]
|
|
|
|
|
return crc&0xFF
|
|
|
|
|
|
2026-03-02 14:29:58 +08:00
|
|
|
def params_to_int(params: str) -> int:
|
|
|
|
|
binary_list = params.split(',')
|
|
|
|
|
binary_string = ''.join(binary_list)
|
|
|
|
|
decimal = int(binary_string, 2)
|
|
|
|
|
return decimal
|
|
|
|
|
|
|
|
|
|
def decompressBySection(val):
|
|
|
|
|
if val < 21:
|
|
|
|
|
ret = val*2
|
|
|
|
|
elif val < 181:
|
|
|
|
|
ret = val + 20
|
|
|
|
|
elif val < 256:
|
|
|
|
|
ret = (val-180)*3 + 200
|
|
|
|
|
else:
|
|
|
|
|
ret = 425
|
|
|
|
|
return ret
|
|
|
|
|
|
2026-04-16 14:23:37 +08:00
|
|
|
# 定义一个递归修改字典的函数
|
|
|
|
|
def recursive_dict_modify(d, sheet):
|
|
|
|
|
# 遍历字典中的键值对
|
|
|
|
|
for key, value in list(d.items()):
|
|
|
|
|
# 如果值是字典,则递归调用函数
|
|
|
|
|
if isinstance(value, dict):
|
|
|
|
|
recursive_dict_modify(value, sheet)
|
|
|
|
|
# 如果值是列表或元组,则遍历列表或元组中的元素
|
|
|
|
|
elif isinstance(value, (list, tuple)):
|
|
|
|
|
for i, item in enumerate(value):
|
|
|
|
|
# 如果元素是字典,则递归调用函数
|
|
|
|
|
if isinstance(item, dict):
|
|
|
|
|
recursive_dict_modify(item, sheet)
|
|
|
|
|
else:
|
|
|
|
|
# 将列表或元组中的元素进行修改
|
|
|
|
|
if is_valid_excel_cell(item):
|
|
|
|
|
value[i] = sheet.range(item).value
|
|
|
|
|
d[key] = value
|
|
|
|
|
# 如果值不是字典或列表或元组,则直接进行修改
|
|
|
|
|
else:
|
|
|
|
|
if is_valid_excel_cell(value):
|
|
|
|
|
d[key] = sheet.range(value).value
|
|
|
|
|
|
|
|
|
|
def is_valid_excel_cell(cell_str):
|
|
|
|
|
# 使用正则表达式拆分字母和数字部分
|
|
|
|
|
match = re.fullmatch(r'^([A-Za-z]+)(\d+)$', cell_str)
|
|
|
|
|
if not match:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
col_letters, row_num = match.groups()
|
|
|
|
|
|
|
|
|
|
# 验证行号
|
|
|
|
|
try:
|
|
|
|
|
row = int(row_num)
|
|
|
|
|
if row < 1 or row > 1048576: # Excel最大行数
|
|
|
|
|
return False
|
|
|
|
|
except ValueError:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# 验证列字母
|
|
|
|
|
col_letters = col_letters.upper()
|
|
|
|
|
if len(col_letters) > 3: # Excel最大列是XFD(3个字母)
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# 计算列号
|
|
|
|
|
col_num = 0
|
|
|
|
|
for i, c in enumerate(reversed(col_letters)):
|
|
|
|
|
col_num += (ord(c) - ord('A') + 1) * (26 ** i)
|
|
|
|
|
|
|
|
|
|
return 1 <= col_num <= 16384 # Excel最大列数
|
2026-03-02 14:29:58 +08:00
|
|
|
|
2026-04-16 14:23:37 +08:00
|
|
|
def read_excel_by_config(configDict, excelFilePath):
|
|
|
|
|
try:
|
|
|
|
|
if not isinstance(configDict, dict):
|
|
|
|
|
raise ValueError("config must be a dictionary.")
|
|
|
|
|
if not os.path.exists(excelFilePath):
|
|
|
|
|
raise ValueError("Excel file does not exist.")
|
|
|
|
|
if 'sheetName' not in configDict:
|
|
|
|
|
raise ValueError("sheetName not in config.")
|
|
|
|
|
|
|
|
|
|
app = xw.App(visible=False)
|
|
|
|
|
wb = app.books.open(excelFilePath)
|
|
|
|
|
sheet = wb.sheets[f"{configDict['sheetName']}"]
|
|
|
|
|
recursive_dict_modify(configDict, sheet)
|
|
|
|
|
wb.close()
|
|
|
|
|
app.quit()
|
|
|
|
|
|
|
|
|
|
return configDict
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
raise Exception(f"error in read_excel_by_config(), {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getGValue(nestedKey):
|
|
|
|
|
if nestedKey.count('.') > 0:
|
|
|
|
|
ret = getGValue(nestedKey[0:nestedKey.rfind('.')])
|
|
|
|
|
if not ret or not isinstance(ret, dict):
|
|
|
|
|
# raise Exception(f"Doesn't exist {nestedKey} in _G or {nestedKey} isn't a dict.")
|
|
|
|
|
return False
|
|
|
|
|
if nestedKey[nestedKey.rfind('.')+1:] in ret:
|
|
|
|
|
return ret[nestedKey[nestedKey.rfind('.')+1:]]
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
ret = _G.get(nestedKey)
|
|
|
|
|
if not ret:
|
|
|
|
|
# raise Exception(f"Doesn't exist {nestedKey} in _G.")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setGValue(nestedKey, value):
|
|
|
|
|
if nestedKey.count('.') > 0:
|
|
|
|
|
upLevelData = getGValue(nestedKey[0:nestedKey.rfind('.')])
|
|
|
|
|
if not upLevelData or not isinstance(upLevelData, dict):
|
|
|
|
|
upLevelData = {}
|
|
|
|
|
upLevelData[nestedKey[nestedKey.rfind('.')+1:]] = value
|
|
|
|
|
setGValue(nestedKey[0:nestedKey.rfind('.')], upLevelData)
|
|
|
|
|
else:
|
|
|
|
|
_G.set(nestedKey, value)
|