Files
MenuPython_QT/PythonMenu_T03.py

1384 lines
72 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import struct
import os
#import crcmod
#import menu_pump as menu
#import MenuDesc as menu
import menu_pump_ver_wolong as menu
#import menu_pump_hor_panda as menu
#import menu_mine as menu
import re
import time
import sys
import zlib
import menu_utils as utils
from device_conf import class_comm_device_config
from enum import Enum
from print_color import *
from NameConvert import get_variable_name
import pypinyin
from pypinyin import pinyin
from pypinyin import lazy_pinyin, Style
from datetime import datetime
current_time = datetime.now()
print(current_time)
DEFAULT_EMPTY_STR = " "
DEFAULT_FORMAT_STR = "%5d"
MENU_ITEM_NORMAL = 0
MENU_ITEM_ALIAS = 1
MENU_ITEM_SUB_MENU = 2
def DebugPrint(object) :
#print(object)
return
#定义字典管理类:
class DictsManager():
def __init__(self) -> None:
#--Dict----------------------------------------------------------------------------------------------------------------------------
#-全局别名字典-
self.MenuAliasDict = {} #<alias>字段字典
self.MenuAliasIndex = 0 #<alias>字段字典索引
self.MenuCommDict = {}
self.MenuCommTable = []
self.MenuCommTableIndex = 0
# 全局菜单项
self.MenuItemList = []
self.config : class_comm_device_config= menu.comm_device_config
self.encode_type = 'utf-8'
if hasattr(self.config, "is_gb2312") :
if self.config.is_gb2312() :
self.encode_type = 'gb2312'
self.alias_table = self.config.get_alias_table()
self.menu_top = self.config.get_menu_top()
self.menu_description = self.config.get_menu_caption_info()
self.MenuDescriptionTable = []
self.comm_table, self.func_comm_table_trigger_check = self.config.get_comm_table()
#-全局字符串字典-
self.MenuStringDict = {} #菜单字符串表
self.MenuStringOffset = 0 #菜单字符串表索引
#-<xx>字段字典->Format,Unit,Action
self.MenuScaleFormatDict = {} #<format>字段字典
self.MenuScaleFormatIndex = 0 #<format>字段字典索引
self.MenuScaleFormatTable = []
self.MenuUnitDict = {} #<unit>字段字典
self.MenuUnitIndex = 0 #<unit>字段字典索引
self.MenuActionDict = {} #<action>字段字典
self.MenuActionIndex = 0 #<action>字段字典索引
#--Table---------------------------------------------------------------------------------
#-根据MenuAliasDict字典创建的MenuAliasTable
#-别名表
self.MenuAliasTable = [] #一级别名表
self.MenuAliasTableIndex = 0 #一级表索引
self.MenuAliasTable2 = [] #二级别名表
self.MenuAliasTable2Index = 0 #二级表索引
self.MenuLimitDict = {}
self.MenuLimitTable = []
self.MenuLimitIndex = 0
self.MenuRegAddrDict = {}
self.MenuRegAddrTable = []
self.MenuRegAddrIndex = 0
self.MenuSubMenuDict = {}
#菜单表
self.MenuMenuTable = [] #一级菜单表
self.MenuMenuTableIndex = 0
self.MenuMenuTable2 = [] #二级菜单表
self.MenuMenuTable2Index = 0
self.MenuTopIndex = 0
self.MenuProcessedList = [] #已经完成处理的菜单项,防止递归电压
#self.MenuJsonDict
#--PackedTable---------------------------------------------------------------------------------
#-全局字符串字典MenuStringDict打包后的字符表
self.Packed_MenuStringTable = bytes()
#-<Unit>字典MenuUnitTable打包后的字符表
self.Packed_MenuUnitTable = bytes()
#-<Format>字典MenuScaleFormatTable打包后的字符表
self.Packed_MenuScaleFormatTable = bytes()
#-<Action>字典MenuActionTable打包后的字符表
self.Packed_MenuActionTable = bytes()
#-<Limit>字典MenuLimitTable打包后的字符表
self.Packed_MenuLimitTable = bytes()
#-<Comm>字典MenuCommTable打包后的字符表
self.Packed_MenuCommTable = bytes()
#--Buf---------------------------------------------------------------------------------
self.Packed_AliasBuf = bytes()
self.Packed_AliasBuf2 = bytes()
self.Packed_MenuBuf = bytes()
self.Packed_MenuBuf2 = bytes()
self.Packed_MenuDescription = bytes()
#-
#字符串打包时设置的编码格式
pass
#--内部API-----------------------------------------------------------------------------------------------------------------------------
#从列表中获取字典------------------
def GetDict_Alias(self,alias_str): #从列表alias_table中获取参数alias_str指定的字典
for item in self.alias_table: #[1]遍历列表中的所有字典
if alias_str in item.keys(): #[2]判断alias_str指定的字典是否存在
return item #[3]字典存在,将其返回<string,<int,string>>,存储字典的字典
return None #[4]列表遍历完毕后字典未找到返回None
#填充MenuStringDict---------------
def AddKeyTo_MenuStringDict(self,info_str) : #填充<Menu_StringDict>:将字符串及其对应的序号填入
if self.MenuStringOffset == 0:
self.MenuStringDict[DEFAULT_EMPTY_STR] = self.MenuStringOffset
self.MenuStringOffset += len(DEFAULT_EMPTY_STR.encode(self.encode_type)) + 1
if info_str not in self.MenuStringDict.keys(): #首先判断要添加的info_str是否已经存在
self.MenuStringDict[info_str] = self.MenuStringOffset #添加键值对儿:<info_str - Menu_StringOffset>
self.MenuStringOffset += len(info_str.encode(self.encode_type)) + 1 #序号自增:字符串索引的长度+1 以0分割
#查询MenuStringDict---------------
def GetOffsetFrom_MenuStringDict(self,info_str): #从<Menu_StringDict>中查询info_str对应的偏移值
offset = 0
if info_str in self.MenuStringDict.keys(): #[1]首先判断要查询的info_str是否存在
offset = self.MenuStringDict[info_str] #[2]返回字典中的记录info_str对应的偏移值
return offset
def GetStringFromOffset(self, offset) :
my_list = (list(filter(lambda k1: self.MenuStringDict[k1] == offset, self.MenuStringDict)))
if (len(my_list)== 1) :
return my_list[0]
return None
def menu_get_str_key(self, str1, str2) :
return str1 + "," + str2
#填充MenuScaleFormatDict---------------
def AddKeyTo_MenuScaleFormatDict(self, scale_str, format_str) : #填充<Menu_FormatDict>:将字符串及其对应的序号填入
str_key = self.menu_get_str_key(scale_str, format_str)
if self.MenuScaleFormatIndex == 0 :
self.MenuScaleFormatDict[DEFAULT_EMPTY_STR] = self.MenuScaleFormatIndex
self.MenuScaleFormatTable.append([0, 0])
self.MenuScaleFormatIndex += 1 #序号自增1
self.AddKeyTo_MenuStringDict(scale_str) #将<scale>字段值存储到 Menu_StringDict
self.AddKeyTo_MenuStringDict(format_str) #将<format>字段值存储到 Menu_StringDict
if str_key not in self.MenuScaleFormatDict.keys(): #首先判断要添加的info_str是否已经存在了
self.MenuScaleFormatDict[str_key] = self.MenuScaleFormatIndex #添加键值对儿:<info_str - Menu_FormatIndex>
scale_str_off = self.GetOffsetFrom_MenuStringDict(scale_str)
format_str_off = self.GetOffsetFrom_MenuStringDict(format_str)
self.MenuScaleFormatTable.append([scale_str_off, format_str_off])
self.MenuScaleFormatIndex += 1 #序号自增1
def Get_ScaleFormatTableIndex(self, scale, format) :
index = 0
str_key = self.menu_get_str_key(scale, format)
if str_key in self.MenuScaleFormatDict.keys():
index = self.MenuScaleFormatDict[str_key]
return index
#填充MenuUnitDict-----------------
def AddKeyTo_MenuUnitDict(self,info_str) : #填充<Menu_UnitDict>:将字符串及其对应的序号填入
if self.MenuUnitIndex == 0 :
self.MenuUnitDict[DEFAULT_EMPTY_STR] = self.MenuUnitIndex
self.MenuUnitIndex += 1
if info_str not in self.MenuUnitDict.keys(): #首先判断要添加的info_str是否已经添加了
self.MenuUnitDict[info_str] = self.MenuUnitIndex #添加键值对儿:<info_str - Menu_UnitIndex>
self.MenuUnitIndex += 1 #序号自增1
def AddKeyTo_MenuAddrDict(self, reg_addr_str) :
if self.MenuRegAddrIndex == 0:
self.MenuRegAddrDict[DEFAULT_EMPTY_STR] = self.MenuRegAddrIndex
self.MenuRegAddrIndex += 1
if reg_addr_str not in self.MenuRegAddrDict.keys() :
self.MenuRegAddrDict[reg_addr_str] = self.MenuRegAddrIndex
self.MenuRegAddrIndex += 1
#填充MenuLimitDict-----------------
def AddKeyTo_LimitDict(self, min_str, max_str) : #填充<Menu_UnitDict>:将字符串及其对应的序号填入
if self.MenuLimitIndex == 0 :
self.MenuLimitIndex += 1
self.MenuLimitTable.append([0, 0])
self.AddKeyTo_MenuStringDict(min_str)
self.AddKeyTo_MenuStringDict(max_str)
str_key = self.menu_get_str_key(min_str, max_str)
if str_key not in self.MenuLimitDict.keys() :
self.MenuLimitDict[str_key] = self.MenuLimitIndex
min_str_off = self.GetOffsetFrom_MenuStringDict(min_str)
max_str_off = self.GetOffsetFrom_MenuStringDict(max_str)
self.MenuLimitTable.append([min_str_off, max_str_off])
self.MenuLimitIndex += 1
def Get_LimitTableIndex(self, min_str, max_str) :
index = 0
key_str = self.menu_get_str_key(min_str, max_str)
if key_str in self.MenuLimitDict.keys() :
index = self.MenuLimitDict[key_str]
return index
#填充MenuActionDict---------------
def AddKeyTo_MenuActionDict(self,info_str) : #构造<Menu_ActionDict>:将字符串及其对应的序号填入
if self.MenuActionIndex == 0:
self.MenuActionDict[DEFAULT_EMPTY_STR] = self.MenuActionIndex
self.MenuActionIndex += 1
if info_str not in self.MenuActionDict.keys(): #首先判断要添加的info_str是否已经添加了
self.MenuActionDict[info_str] = self.MenuActionIndex #添加键值对儿:<info_str - Menu_ActionIndex>
self.MenuActionIndex += 1 #序号自增1
#别名字典alias_dict填充Menu_StringDict----------
def StuffDict_MenuStringDict_ByAliasDict(self): #把别名表中的最底层字典的Value所有别名存储到Menu_StringDict
for alias_dict in self.alias_table :
for alias_name, value_dict in alias_dict.items():
if isinstance(alias_name, Enum):
alias_name = alias_name.name
self.AddKeyTo_MenuStringDict(alias_name)
for alias_dict in self.alias_table : #遍历alias_table表
for alias_name, value_dict in alias_dict.items() : #遍历alias_table表中的每个字典
for key, value_str in value_dict.items() : #遍历字典中的字典
self.AddKeyTo_MenuStringDict(value_str) #将所有别名值存入Menu_StringDict
DebugPrint("<Dict>MenuStringDict->")
DebugPrint(self.MenuStringDict)
#--CreateTable-----------------------------------------------------------------------------------------------------------------------------
def menu_get_min_max_index(self, min_value_str, max_value_str) :
index = 0
str_key = self.menu_get_str_key(min_value_str, max_value_str)
if str_key in self.MenuLimitDict.keys() :
index = self.MenuLimitDict[str_key]
return index
def menu_item_get_reg_addr_str(self, menu_item) :
reg_addr_str = DEFAULT_EMPTY_STR
reg_addr = None
if "addr" in menu_item.keys() :
reg_addr = menu_item["addr"]
if isinstance(reg_addr, float) :
reg_addr_str = str(reg_addr)
elif isinstance(reg_addr, int) :
reg_addr_str = str(reg_addr)
elif isinstance(reg_addr, str) :
reg_addr_str = reg_addr
return reg_addr_str
def menu_item_remap_addr(self, menu_item) :
remap_addr = utils.dict_or_object_get_attr(menu_item, "remap_addr", 0)
return remap_addr
def menu_item_get_min_max_str(self, menu_item) :
min_value_str = DEFAULT_EMPTY_STR
max_value_str = DEFAULT_EMPTY_STR
min_value = utils.dict_or_object_get_attr(menu_item, "min", None)
max_value = utils.dict_or_object_get_attr(menu_item, "max", None)
format_str = utils.dict_or_object_get_attr(menu_item, "format", "%05.0f")
if isinstance(min_value, float) :
min_value_str = format_str%(min_value)
elif isinstance(min_value, int) :
min_value = min_value * 1.0
min_value_str = format_str%(min_value)
elif isinstance(min_value, str) :
min_value_str = min_value
if isinstance(max_value, float) :
max_value_str = format_str%(max_value)
elif isinstance(max_value, int) :
max_value = max_value * 1.0
max_value_str = format_str%(max_value)
elif isinstance(max_value, str) :
max_value_str = max_value
return min_value_str, max_value_str
def menu_item_get_scale_format(self, menu_item) :
scale_str = str(1.0)
format_str = DEFAULT_EMPTY_STR
format_value = None
scale_value = None
if "format" in menu_item.keys() :
format_value = menu_item["format"]
if "scale" in menu_item.keys() :
scale_value = menu_item["scale"]
if isinstance(format_value, float) :
format_str = str(format_value)
elif isinstance(format_value, str) :
format_str = format_value
if isinstance(scale_value, float) :
scale_str = str(scale_value)
elif isinstance(scale_value, str) :
scale_str = scale_value
return scale_str, format_str
#根据菜单内容,填充各个字段字典->MenuUnitDict,MenuScaleFormatDict,MenuActionDict---
def StuffDict_MenuDict(self,menu, lead): #填充一个菜单对应的各个字典menu:指定的菜单lead:要添加信息的各个属性字段字典
if menu == None :
return
for menu_item in menu : #遍历菜单的各个菜单项
if lead == "scale_format" : #处理<scale format>字段:
scale_str, format_str = self.menu_item_get_scale_format(menu_item)
self.AddKeyTo_MenuScaleFormatDict(scale_str, format_str) #将<scale format>字段值存储到 Menu_FormatDict
if lead == "min_max" :
min_value_str, max_value_str = self.menu_item_get_min_max_str(menu_item)
self.AddKeyTo_LimitDict(min_value_str, max_value_str)
if lead == "remap_addr" :
remap_addr = self.menu_item_remap_addr(menu_item)
if lead == "addr":
reg_addr_key_str = self.menu_item_get_reg_addr_str(menu_item)
self.AddKeyTo_MenuStringDict(reg_addr_key_str)
self.AddKeyTo_MenuAddrDict (reg_addr_key_str)
if lead in menu_item.keys() : #检测菜单项是否包含lead指定的字段
if lead == "name" : #处理<name>字段:
self.AddKeyTo_MenuStringDict(menu_item["name"]) #将<name>字段值存储到 Menu_StringDict
if lead == "unit" : #处理<unit>字段:
self.AddKeyTo_MenuStringDict(menu_item["unit"]) #将<unit>字段值存储到 Menu_StringDict
self.AddKeyTo_MenuUnitDict(menu_item["unit"]) #将<unit>字段值存储到 Menu_UnitDict
if lead == "action" : #处理<action>字段:
self.AddKeyTo_MenuStringDict(menu_item["action"]) #将<action>字段值存储到 Menu_StringDict
self.AddKeyTo_MenuActionDict(menu_item["action"]) #将<action>字段值存储到 Menu_ActionDict
if lead == "default" :
default_str = "%s"%(menu_item["default"])
self.AddKeyTo_MenuStringDict(default_str)
def Create_MenuInfo(self) :
for item_dict in self.menu_description :
menu_object = utils.dict_or_object_get_attr(item_dict, "menu", None)
if menu_object != None :
self.StuffDict_MenuDict(menu_object, "addr") #处理<addr>字段
self.StuffDict_MenuDict(menu_object, "unit") #处理<unit>字段
self.StuffDict_MenuDict(menu_object, "scale_format") #处理<scale_format>字段
self.StuffDict_MenuDict(menu_object, "action") #处理<action>字段
self.StuffDict_MenuDict(menu_object, "name") #处理<name>字段
self.StuffDict_MenuDict(menu_object, "min_max") #处理<最小最大值>字段
self.StuffDict_MenuDict(menu_object, "remap_addr") #处理重映射字段
self.StuffDict_MenuDict(menu_object, "default") #处理重映射字段
#填充<别名字典>,创建2张别名表------
def Create_MenuAliasTables(self):
self.StuffDict_MenuStringDict_ByAliasDict() #首先把别名表数值填充到Menu_StringDict字典中
DebugPrint("MenuStringDict->" + str(self.MenuStringDict))
DebugPrint("MenuAliasDict->" + str(self.alias_table))
for alias_dict in self.alias_table : #遍历别名字典表alias_table
for alias_name, value_dict in alias_dict.items(): #遍历表中单独的一个字典alias_dict
if isinstance(alias_name, Enum):
alias_name = alias_name.name
if alias_name not in self.MenuAliasDict.keys() : #因为是空字典,所以会执行
self.MenuAliasDict[alias_name] = self.MenuAliasTableIndex #填充Menu_AliasDict将alias_name存储<alias_bool:0,alias_voltage:1,alias_enable:2,..>
DebugPrint("Dict:"+ alias_name + " GetIndex->" + str(self.MenuAliasTableIndex))
self.MenuAliasTable.append([self.MenuAliasTable2Index, len(value_dict)]) #构造一级别名表:将[2级表索引,字典长度]存储
DebugPrint("MenuAliasDict-> [地址偏移,字典大小]->" + str(self.MenuAliasTable)) #[起始地址,内容长度]
self.MenuAliasTableIndex += 1 #索引+1
sorted_list_turple = sorted(value_dict.items(), key=lambda x: x[0] if isinstance(x[0], Enum) == False else x[0].value[0])
for each in sorted_list_turple:
if isinstance(each[0], Enum) :
key_value = each[0].value[0]
else :
key_value = each[0]
key_string = each[1]
key_string_offset = self.GetOffsetFrom_MenuStringDict(key_string) #查询Menu_StringDict,找到对应的偏移值:'关闭'->
self.MenuAliasTable2.append([key_value, key_string_offset]) #构造二级别名表:
self.MenuAliasTable2Index += 1 #索引+1
DebugPrint("MenuAliasDict2->[数值,别名偏移]->" + str(self.MenuAliasTable2)) #[别名索引,在字符串表中偏移]
#for key_value, key_string in value_dict.items(): #遍历字典值:别名内容 {0: '关闭', 1: '打开'} #{'alias_bool': {0: '关闭', 1: '打开'}},
# key_string_offset = self.GetOffsetFrom_MenuStringDict(key_string) #查询Menu_StringDict,找到对应的偏移值:'关闭'->
# self.MenuAliasTable2.append([key_value, key_string_offset]) #构造二级别名表:
# self.MenuAliasTable2Index += 1 #索引+1
# DebugPrint("MenuAliasDict2->[数值,别名偏移]->" + str(self.MenuAliasTable2)) #[别名索引,在字符串表中偏移]
#第一个表Menu_AliasTable存储的是 [字典1的起始地址,字典1大小][字典2的起始地址,字典2大小][字典3的起始地址,字典3大小].
#第二个表Menu_AliasTable2存储的是 [别名索引,在字符串表中偏移][别名索引,在字符串表中偏移][别名索引,在字符串表中偏移].
def Create_MenuCommTables(self) :
if self.MenuCommTableIndex == 0 :
self.MenuCommTable.append([0, 0, 0, 0])
self.MenuCommTableIndex += 1
for comm_dict in self.comm_table : #遍历通讯表comm_table
comm_group_name = utils.dict_or_object_get_attr(comm_dict, "name", None)
if comm_group_name not in self.MenuCommDict.keys() :
self.MenuCommDict[comm_group_name] = self.MenuCommTableIndex
DebugPrint("Dict:"+ comm_group_name + " GetIndex->" + str(self.MenuCommTableIndex))
reg_addr = utils.dict_or_object_get_attr(comm_dict, "reg_addr", 0)
reg_count = utils.dict_or_object_get_attr(comm_dict, "reg_count", 0)
cycle = utils.dict_or_object_get_attr(comm_dict, "cycle", 0)
mqtt_pack_object = utils.dict_or_object_get_attr(comm_dict, "mqtt_pack", None)
mqtt_pack_name = self.get_menu_object_name(mqtt_pack_object)
mqtt_menu_index = utils.dict_or_object_get_attr(self.MenuSubMenuDict, mqtt_pack_name, 0)
self.MenuCommTable.append([reg_addr, reg_count, cycle, mqtt_menu_index])
self.MenuCommTableIndex += 1 #索引+1
DebugPrint("MenuCommDict2->[寄存器, 数量, 周期, 菜单索引]->" + str(self.MenuCommTable)) #[别名索引,在字符串表中偏移]
def get_menu_object_name(self, menu_object) :
for item_dict in self.menu_description :
object = utils.dict_or_object_get_attr(item_dict, "menu", None)
if object == menu_object :
return utils.dict_or_object_get_attr(item_dict, "name", None)
return None
def Create_MenuNameDict(self):
menu_index = 0
self.MenuSubMenuDict[DEFAULT_EMPTY_STR] = menu_index
menu_index += 1
has_same_name = False
for item_dict in self.menu_description :
action_name = utils.dict_or_object_get_attr(item_dict, "action", None)
if action_name != None:
self.AddKeyTo_MenuStringDict(action_name) #将<action>字段值存储到 Menu_StringDict
self.AddKeyTo_MenuActionDict(action_name) #将<action>字段值存储到 Menu_ActionDict
menu_name = utils.dict_or_object_get_attr(item_dict, "name", None)
if menu_name != None :
if menu_name not in self.MenuSubMenuDict.keys() :
self.MenuSubMenuDict[menu_name] = menu_index
else :
has_same_name = True
print_error_msg("有相同的菜单名(%s)"%(menu_name))
menu_index += 1
if has_same_name :
exit(0)
menu_top = self.config.get_menu_top()
menu_top_name = self.config.get_menu_name(menu_top)
self.MenuTopIndex = utils.dict_or_object_get_attr(self.MenuSubMenuDict, menu_top_name, 0)
def Create_MenuDescriptionTable(self) :
self.MenuDescriptionTable.append([0, 0, 0, 0, 0, 0, 0, 0, 0])
for item_dict in self.menu_description :
menu_name = utils.dict_or_object_get_attr(item_dict, "name", None)
prev_menu_object = utils.dict_or_object_get_attr(item_dict, "prev", None)
prev_menu_name = self.get_menu_object_name(prev_menu_object)
if prev_menu_name == None :
prev_menu_name = menu_name
else :
DebugPrint(prev_menu_name)
next_menu_object = utils.dict_or_object_get_attr(item_dict, "next", None)
next_menu_name = self.get_menu_object_name(next_menu_object)
if next_menu_name == None :
next_menu_name = menu_name
else :
DebugPrint(next_menu_name)
display_menu_object = utils.dict_or_object_get_attr(item_dict, "display", None)
display_menu_name = self.get_menu_object_name(display_menu_object)
caption_name = utils.dict_or_object_get_attr(item_dict, "caption", DEFAULT_EMPTY_STR)
display_page = utils.dict_or_object_get_attr(item_dict, "page", 0)
max_menu_item = utils.dict_or_object_get_attr(item_dict, "max_items", 0)
active_index = 0
'''
action_name = utils.dict_or_object_get_attr(item_dict, "action", None)
if action_name == None :
active_index = 0
else :
active_index = utils.dict_or_object_get_attr(self.MenuActionDict, action_name, 0)
'''
self.AddKeyTo_MenuStringDict(menu_name)
self.AddKeyTo_MenuStringDict(caption_name)
menu_index = utils.dict_or_object_get_attr(self.MenuSubMenuDict, menu_name, 0)
prev_menu_index = utils.dict_or_object_get_attr(self.MenuSubMenuDict, prev_menu_name, 0)
next_menu_index = utils.dict_or_object_get_attr(self.MenuSubMenuDict, next_menu_name, 0)
display_menu_index = utils.dict_or_object_get_attr(self.MenuSubMenuDict, display_menu_name, 0)
menu_name_str_off = self.GetOffsetFrom_MenuStringDict(menu_name)
caption_str_off = self.GetOffsetFrom_MenuStringDict(caption_name)
self.MenuDescriptionTable.append([menu_index, display_menu_index, next_menu_index, prev_menu_index, display_page, max_menu_item, active_index, menu_name_str_off, caption_str_off])
#创建2张菜单表create_menu_item_talbe(Menu_Top)
def Create_MenuItemTable(self, menu, self_menu_str) : #创建菜单表,菜单本身由字典列表描述
#自身菜单索引写入到菜单字典中
#self_menu_str = self.config.get_menu_name(menu)
self_menu_index = self.MenuSubMenuDict[self_menu_str]
start_index = self.MenuMenuTable2Index #设置起始索引
for menu_item_dict in menu : #遍历字典
alias_index = 0 #
unit_index = 0
name_offset = 0
is_alias = 0
action_index = 0
sub_menu_index = 0
comm_index = 0
min_value_str, max_value_str = self.menu_item_get_min_max_str(menu_item_dict)
limit_index = self.menu_get_min_max_index(min_value_str, max_value_str)
scale_str, format_str = self.menu_item_get_scale_format(menu_item_dict)
scale_format_index = self.Get_ScaleFormatTableIndex(scale_str, format_str)
remap_addr = utils.dict_or_object_get_attr(menu_item_dict, "remap_addr", 0)
menu_property = utils.dict_or_object_get_attr(menu_item_dict, "property", 1)
for key, value in menu_item_dict.items(): #遍历字典中的键值对 "name": "电流设置",
if key == "alias" : #
if isinstance(value, Enum) :
value = value.name
if value in self.MenuAliasDict.keys() :
alias_index = self.MenuAliasDict[value] #查询到对应的在别名表的偏移
is_alias = 1
else :
alias_index = 0
elif key == "unit" :
unit_index = self.MenuUnitDict[value]
elif key == "name" :
name_offset = self.GetOffsetFrom_MenuStringDict(value)
elif key == "action" :
action_index = self.MenuActionDict[value]
elif key == "comm" :
comm_index = self.MenuCommDict[value]
elif key == "sub_menu" :
sub_menu_str = value
if isinstance(sub_menu_str, Enum) :
sub_menu_str = sub_menu_str.name
sub_menu_index = utils.dict_or_object_get_attr(self.MenuSubMenuDict, sub_menu_str, 0)
reg_addr_key_str = self.menu_item_get_reg_addr_str(menu_item_dict)
reg_addr_key_index = self.GetOffsetFrom_MenuStringDict(reg_addr_key_str)
self.MenuMenuTable2Index += 1
self.MenuItemList.append([menu_item_dict, self.MenuMenuTable2Index])
self.MenuMenuTable2.append([reg_addr_key_index, name_offset, is_alias, unit_index, alias_index, scale_format_index, action_index, sub_menu_index, limit_index, comm_index, remap_addr, menu_property])
end_index = self.MenuMenuTable2Index
if len(self.MenuMenuTable) == 0 :
self.MenuMenuTable.insert(0, [0, 0])
self.MenuMenuTable.insert(self_menu_index, [start_index, end_index - start_index]) #MenuMenuTable表存储
DebugPrint("MenuMenuTable->" + str(self.MenuMenuTable)) #
DebugPrint("----") #
DebugPrint("MenuMenuTable2->" + str(self.MenuMenuTable2)) #
DebugPrint(" ") #
#第一个表Menu_MenuTable存储的是 [[0, 4], [4, 5], [9, 4]] :[起始地址,项数].
#第二个表MMenu_MenuTable2存储的是 [2000, 46, 0, 0, 0, 0, 0, 0], [2001, 59, 0, 1, 0, 1, 0, 0].
def Create_AllMenuItemTable(self) : #创建菜单表,菜单本身由字典列表描述
for item_dict in self.menu_description :
menu_object = utils.dict_or_object_get_attr(item_dict, "menu", None)
menu_name = utils.dict_or_object_get_attr(item_dict, "name", None)
if menu_object != None and menu_name != None:
self.Create_MenuItemTable(menu_object, menu_name)
#--Packing------------------------------------------------------------------------------------------------------------------------------------------------------
#对数据包补零处理------------------
#API_Align_PackBuf()
def Align_PackBuf(self,pack_buf) : #保证4字节对齐对不满足的进行补零操作
remain = len(pack_buf) % 4 #计算要补零的个数
if remain == 1 :
return pack_buf + struct.pack("BBB", 0, 0, 0) #补3个0
elif remain == 2 :
return pack_buf + struct.pack("BB", 0, 0) #补2个0
elif remain == 3 :
return pack_buf + struct.pack("B", 0) #补1个0
return pack_buf #返回补零处理后的包
#将MenuStringDict中的键打包--------------------
#API_Pack_MeunStringDict()
def Pack_MeunStringDict(self): #打包<字符串表>
for str_key in self.MenuStringDict.keys() : #遍历Menu_StringDict字典的索引
str_format = str(len(str_key.encode(self.encode_type)) + 1) + 's' #要打包的格式字符:每条索引的字符长度+1
self.Packed_MenuStringTable += struct.pack(str_format, str_key.encode(self.encode_type)) #将每个索引打包进Pack_StringTable
self.Packed_MenuStringTable = struct.pack("I", len(self.Packed_MenuStringTable)) + self.Packed_MenuStringTable
for str_key, str_off in self.MenuStringDict.items() : #遍历Menu_StringDict将存储的键值对<string,int>打印<额定电流 : 94>
object_str = "name=" + str_key + ": offset=" + str(str_off)
DebugPrint(object_str) #打印键值对:<额定电流 : 94>
DebugPrint("-----------------------------------")
DebugPrint("<Packed_Dict>Pack_MenuStringTable->")
DebugPrint(self.Packed_MenuStringTable)
#打包字典MenuUnitDict得到Menu_UnitTable :单位在字符表中的偏移--------------------------------------------------
def Pack_MenuUnitDict(self):
MenuUnitTurpleSort = sorted(self.MenuUnitDict.items(), key=lambda x:x[1], reverse=False) #先对Menu_UnitDict字典的索引排序
MenuUnitDictSort = dict(MenuUnitTurpleSort) #由排序好的tuple生成新的字典
self.Packed_MenuUnitTable = struct.pack("I", len(self.MenuUnitDict)) #打包长度
for key in MenuUnitDictSort.keys() : #遍历单位字典中所有项目
key_offset = self.GetOffsetFrom_MenuStringDict(key) #从字符串字典中 查询偏移值
self.Packed_MenuUnitTable += struct.pack("H", key_offset) #
self.Packed_MenuUnitTable = self.Align_PackBuf(self.Packed_MenuUnitTable) #打包
DebugPrint("Origin:MenuUnitDictSort->" + str(MenuUnitDictSort)) #
DebugPrint("Packed:Packed_MenuUnitTable->" + str(self.Packed_MenuUnitTable)) #
#打包字典MenuScaleFormatDict得到Packed_MenuScaleFormatTable:动作在字符表中的偏移----------------------------------------------------
def Pack_MenuScaleFormatDict(self):
self.Packed_MenuScaleFormatTable = struct.pack("I", len(self.MenuScaleFormatTable))
for item in self.MenuScaleFormatTable :
self.Packed_MenuScaleFormatTable += struct.pack("HH", item[0], item[1])
self.Packed_MenuScaleFormatTable = self.Align_PackBuf(self.Packed_MenuScaleFormatTable)
DebugPrint("Origin:MenuScaleFormatDict->" + str(self.MenuScaleFormatDict))
DebugPrint("Origin:MenuScaleFormatTable->" + str(self.MenuScaleFormatTable))
DebugPrint("Packed:MenuScaleFormatTable->" + str(self.Packed_MenuScaleFormatTable))
#打包字典MenuScaleFormatDict得到Packed_MenuScaleFormatTable:动作在字符表中的偏移----------------------------------------------------
def Pack_MenuCaptionInfoDict(self):
'''
struct TMenuDescriptionItem
{
uint16_t menu_index : 8;
uint16_t next_menu_index : 8;
uint16_t prev_menu_index : 8;
uint16_t display_page : 8;
uint16_t max_menu_item : 8;
uint16_t action_index : 8;
uint16_t menu_name_str_offset;
uint16_t description_str_off;
uint16_t display_menu_index : 8;
uint16_t rsv : 8;
};
'''
self.Packed_MenuDescription = struct.pack("I", len(self.MenuDescriptionTable))
for item in self.MenuDescriptionTable :
value = 0
value2 = 0
value |= item[0]
display_menu_index = item[1]
next_menu_index = item[2]
value |= (next_menu_index << 8)
prev_menu_index = item[3]
value |= (prev_menu_index << 16)
page = item[4]
value |= (page << 24)
max_items = item[5]
value2 |= (max_items << 0)
action_index = item[6]
value2 |= (action_index << 8)
menu_name_off = item[7]
caption_str_off = item[8]
self.Packed_MenuDescription += struct.pack("IHHHBB", value, value2, menu_name_off, caption_str_off, display_menu_index, 0)
self.Packed_MenuDescription = self.Align_PackBuf(self.Packed_MenuDescription)
#打包字典Pack_MenuActionDict得到Packed_MenuActionTable:动作在字符表中的偏移----------------------------------------------------
def Pack_MenuActionDict(self):
Menu_actionTurpleSort = sorted(self.MenuActionDict.items(), key=lambda x:x[1], reverse=False)
MenuactionDictSort = dict(Menu_actionTurpleSort)
self.Packed_MenuActionTable = struct.pack("I", len(self.MenuActionDict))
DebugPrint("01-Packed_MenuActionTable->" + str(self.Packed_MenuActionTable)) #
for key in MenuactionDictSort.keys() :
key_offset = self.GetOffsetFrom_MenuStringDict(key)
DebugPrint("02-offset->" + str(key_offset)) #
self.Packed_MenuActionTable += struct.pack("H", key_offset)
DebugPrint("02-Current:Packed_MenuActionTable->" + str(self.Packed_MenuActionTable)) #
self.Packed_MenuActionTable = self.Align_PackBuf(self.Packed_MenuActionTable)
DebugPrint("03-Current:MenuActionTable ->" + str(self.MenuActionDict)) #
DebugPrint("04-Sorted :MenuactionDictSort->" + str(MenuactionDictSort)) #
DebugPrint("05-Packed:Packed_MenuActionTable->" + str(self.Packed_MenuActionTable)) #
def Pack_MenuLimitDict(self):
self.Packed_MenuLimitTable = struct.pack("I", len(self.MenuLimitTable))
for item in self.MenuLimitTable:
self.Packed_MenuLimitTable += struct.pack("HH", item[0], item[1])
def Pack_MenuCommDict(self):
self.Packed_MenuCommTable = struct.pack("I", len(self.MenuCommTable))
for item in self.MenuCommTable:
self.Packed_MenuCommTable += struct.pack("IHHHH", item[0], item[1], item[2], item[3], 0)
#打包2张别名表Menu_AliasTable Menu_AliasTable2-------------------
def Pack_MenuAliasTables(self):
self.Packed_AliasBuf = struct.pack("I", len(self.MenuAliasTable)) #将Menu_AliasDict菜单别字典打包先将长度填充
for item in self.MenuAliasTable: #将Menu_AliasTable菜单别名表打包[[0, 2], [2, 3], [5, 2]]
self.Packed_AliasBuf += struct.pack("HH", item[0], item[1]) #[0,2] -> x00\x00\x02\x00 [2,3] -> x02\x00\x03\x00
self.Packed_AliasBuf = self.Align_PackBuf(self.Packed_AliasBuf) #补零处理
DebugPrint("Origin:MenuAliasTable->" + str(self.MenuAliasTable)) #
DebugPrint("Packed:MenuAliasDict->" + str(self.Packed_AliasBuf)) #
self.Packed_AliasBuf2 = struct.pack("I", len(self.MenuAliasTable2)) #[[0, 1], [1, 8], [0, 15], [1, 20], [2, 25], [0, 1], [1, 31]]打包填充长度占4个字节长度
for item in self.MenuAliasTable2: #遍历每一项[x,x]
if isinstance(item[0], Enum) :
value = item[0].value[0]
else :
value = item[0]
self.Packed_AliasBuf2 += struct.pack("HH", value, item[1]) #[0,1] -> x00\x00\x01\x00\ [1,8] -> x01\x00\x08\x00\
self.Packed_AliasBuf2 = self.Align_PackBuf(self.Packed_AliasBuf2) #补零处理
DebugPrint("Origin:MenuAliasTable2->" + str(self.MenuAliasTable2)) #
DebugPrint("Packed:MenuAliasDict->" + str(self.Packed_AliasBuf2)) #
'''
typedef enum EMenuItemInfoType
{
MENU_ITEM_NORMAL,
MENU_ITEM_ALIAS,
MENU_ITEM_SUB_MENU,
} EMenuItemInfoType;
typedef struct TMenuItemInfoTypeCommon
{
uint32_t type : 2;
uint32_t rsv : 22;
uint32_t action_index : 8;
} TMenuItemInfoTypeCommon;
typedef struct TMenuItemInfoTypeAlias
{
uint32_t type : 2;
uint32_t rsv : 14;
uint32_t alias_index : 8;
uint32_t action_index : 8;
} TMenuItemInfoTypeAlias;
typedef struct TMenuItemInfoTypeNormal
{
uint32_t type : 2;
uint32_t scale_format_index : 8;
uint32_t limit_index : 8;
uint32_t unit_index : 6;
uint32_t action_index : 8;
} TMenuItemInfoTypeNormal;
typedef struct TMenuItemInfoTypeSubMenu
{
uint32_t type : 2;
uint32_t rsv : 14;
uint32_t sub_menu_index : 8;
uint32_t action_index : 8;
} TMenuItemInfoTypeSubMenu;
typedef enum EMenuProperty
{
MENU_PROP_READ_ONLY = 0,
MENU_PRIO_USER,
MENU_PRIO_ENGINEER,
} EMenuProperty;
//每个菜单项12字节
struct TMenuItemInfo
{
uint16_t comm_str_offset;
uint16_t name_offset;
uint16_t comm_group_index : 8;
uint16_t menu_property : 8; //EMenuProperty
uint16_t remap_addr;
union {
TMenuItemInfoTypeCommon common;
TMenuItemInfoTypeAlias alias;
TMenuItemInfoTypeNormal normal;
TMenuItemInfoTypeSubMenu sub_menu;
} info;
};
'''
#打包菜单表MenuMenuTable :格式在字符表中的偏移
def Pack_MenuMenuTable(self):
self.Packed_MenuBuf = struct.pack("HH", len(self.MenuSubMenuDict), self.MenuTopIndex)
for item in self.MenuMenuTable:
self.Packed_MenuBuf += struct.pack("HH", item[0], item[1])
self.Packed_MenuBuf2 = struct.pack("I", len(self.MenuMenuTable2)) #菜单包2组包构造字节流首先添加长度信息
for item in self.MenuMenuTable2: #在一个循环中将各个信息流填入buf中
reg_addr_key_index = item[0]
name_offset = item[1]
is_alias = item[2]
unit_index = item[3]
alias_index = item[4]
scale_format_index = item[5]
action_index = item[6]
sub_menu_index = item[7]
limit_index = item[8]
comm_index = item[9]
remap_addr = item[10]
menu_property = item[11]
menu_item_prop = 0
menu_item_prop |= (action_index & 0xFF) << 24
if is_alias :
menu_item_prop |= (MENU_ITEM_ALIAS << 0)
menu_item_prop |= ((alias_index & 0xFF) << 16)
elif sub_menu_index > 0 :
menu_item_prop |= (MENU_ITEM_SUB_MENU << 0)
menu_item_prop |= ((sub_menu_index & 0xFF) << 16)
else :
menu_item_prop |= (MENU_ITEM_NORMAL << 0)
menu_item_prop |= ((scale_format_index & 0xFF) << 2)
menu_item_prop |= ((limit_index & 0xFF) << 10)
menu_item_prop |= ((unit_index & 0x3F) << 18)
self.Packed_MenuBuf2 += struct.pack("HHBBHI", reg_addr_key_index, name_offset, comm_index, menu_property, remap_addr, menu_item_prop)
self.Packed_MenuBuf = self.Align_PackBuf(self.Packed_MenuBuf)
self.Packed_MenuBuf2 = self.Align_PackBuf(self.Packed_MenuBuf2)
self.Packed_MenuDescription = self.Align_PackBuf(self.Packed_MenuDescription)
self.Packed_AliasBuf = self.Align_PackBuf(self.Packed_AliasBuf)
self.Packed_AliasBuf2 = self.Align_PackBuf(self.Packed_AliasBuf2)
self.Packed_MenuScaleFormatTable = self.Align_PackBuf(self.Packed_MenuScaleFormatTable)
self.Packed_MenuUnitTable = self.Align_PackBuf(self.Packed_MenuUnitTable)
self.Packed_MenuStringTable = self.Align_PackBuf(self.Packed_MenuStringTable)
self.Packed_MenuLimitTable = self.Align_PackBuf(self.Packed_MenuLimitTable)
self.Packed_MenuCommTable = self.Align_PackBuf(self.Packed_MenuCommTable)
self.Packed_MenuActionTable = self.Align_PackBuf(self.Packed_MenuActionTable)
DebugPrint("01-Origin:Menu_MenuTable->" + str(self.MenuMenuTable)) #
DebugPrint("<->") #
DebugPrint("01-Packed:Pack_MenuBuf->" + str(self.Packed_MenuBuf)) #
DebugPrint("...........................") #
DebugPrint("02-Origin:Menu_MenuTable2->" + str(self.MenuMenuTable2)) #
DebugPrint("<->") #
DebugPrint("02-Packed:Pack_MenuBuf2->" + str(self.Packed_MenuBuf2)) #
#打包整体
def Pack_All(self):
PackData = self.Packed_MenuBuf
PackData = PackData + self.Packed_MenuBuf2
PackData = PackData + self.Packed_MenuDescription
PackData = PackData + self.Packed_AliasBuf
PackData = PackData + self.Packed_AliasBuf2
PackData = PackData + self.Packed_MenuScaleFormatTable
PackData = PackData + self.Packed_MenuUnitTable
PackData = PackData + self.Packed_MenuLimitTable
PackData = PackData + self.Packed_MenuCommTable
PackData = PackData + self.Packed_MenuActionTable
PackData = PackData + self.Packed_MenuStringTable
#crc_function = crcmod.mkCrcFun(0x104c11db7, initCrc=0xFFFFFFFF, xorOut=0xFFFFFFFF) #获取计算CRC校验的函数->crc_function
#data_crc_value = crc_function(PackData)
data_crc_value = 0
data_crc_value = zlib.crc32(PackData, data_crc_value)
data_crc_value &= 0xFFFFFFFF
PackHeader = struct.pack("8s", "PackV0.1".encode(self.encode_type)) #将"PackV0.1"8个字符编码后填入buf中
header_size = 80
PackHeader += struct.pack("I", header_size) #文件头长度
pack_offset = 0 #菜单包1偏移 = 64
PackHeader += struct.pack("I", pack_offset)
DebugPrint("00-<菜单表1偏移>-menu_pack_offset ->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuBuf) #菜单包2偏移 = 菜单包1偏移 + 菜单包1长度
PackHeader += struct.pack("I", pack_offset)
DebugPrint("01-<菜单表2偏移>-menu_pack2_offset ->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuBuf2) #菜单包2偏移 = 菜单包1偏移 + 菜单包1长度
PackHeader += struct.pack("I", pack_offset)
DebugPrint("02-<菜单描述偏移>-menu_desc_offset ->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuDescription) #菜单包2偏移 = 菜单包1偏移 + 菜单包1长度
PackHeader += struct.pack("I", pack_offset)
DebugPrint("03-<别名表1偏移>-alias_pack_offset ->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_AliasBuf) #别名包1偏移 = 菜单包2偏移 + 菜单包2长度
PackHeader += struct.pack("I", pack_offset)
DebugPrint("04-<别名表2偏移>-alias_pack2_offset->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_AliasBuf2) #别名包2偏移 = 别名包1偏移 + 别名包1长度
PackHeader += struct.pack("I", pack_offset)
DebugPrint("05-<format表偏移>-format_table_offset->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuScaleFormatTable)
PackHeader += struct.pack("I", pack_offset)
DebugPrint("06-<unit表偏移>-unit_table_offset->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuUnitTable)
PackHeader += struct.pack("I", pack_offset)
DebugPrint("07-<limit表偏移>-limit_table_offset->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuLimitTable)
PackHeader += struct.pack("I", pack_offset)
DebugPrint("08-<Comm表偏移>-comm_table_offset->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuCommTable)
PackHeader += struct.pack("I", pack_offset)
DebugPrint("09-<Action表偏移>-action_table_offset->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuActionTable)
PackHeader += struct.pack("I", pack_offset)
DebugPrint("10-<string表偏移>-string_table_offset->" + str(pack_offset))
pack_offset = pack_offset + len(self.Packed_MenuStringTable)
PackHeader += struct.pack("III", 0, 0, 0) #保留
PackHeader += struct.pack("I", len(PackData))
PackHeader += struct.pack("I", data_crc_value)
#head_crc_value = crc_function(PackHeader)
head_crc_value = 0
head_crc_value = zlib.crc32(PackHeader, head_crc_value)
head_crc_value &= 0xFFFFFFFF
PackHeader += struct.pack("I", head_crc_value)
header_len = len(PackHeader)
DebugPrint("04-<文件头长度 >-PackHeaderLen ->" + str(header_len))
PackFile = PackHeader + PackData #文件 = 文件头 + 文件数据
file_len = len(PackFile)
DebugPrint("04-<文件总长度 >-PackFileLen ->" + str(file_len))
DebugPrint(" ")
DebugPrint("01-<文件头部>PackHeader->")
DebugPrint(repr(PackHeader))
DebugPrint(" ")
DebugPrint("03-<文件整体>PackFile->")
DebugPrint(len(PackFile))
DebugPrint(repr(PackFile))
DebugPrint(" ")
return PackFile
def PackSave(self, file_name, pack_file) :
with open(file_name,'wb') as file:
file.write(pack_file)
file.close()
def PackSaveC(self, file_name, pack_file) :
index = 0
with open(file_name,'w', encoding='utf-8') as file:
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
file.write("/" + "/" + file_name + " create date: " + current_time + "\n")
file.write("#include <stdint.h>\n")
file.write("__attribute__((aligned(4)))\n")
file.write("const char menu_data[] = {\n")
for each in pack_file :
if index == 0 :
file.write(" ")
index += 1
file.write("0x%02x, "%(each))
if index >= 16 :
index = 0
file.write("\n")
if index > 0 :
file.write("\n")
file.write("};\n")
file.write("const uint16_t menu_data_buf_size = sizeof(menu_data);\n")
file.close()
def get_comm_str_info(comm_str : str) :
splits = comm_str.split('#')
total_len = len(splits)
base = 0
bit = -1
sign = 1
if comm_str == DEFAULT_EMPTY_STR :
return base, bit, sign
if total_len >= 1 :
bit_splits = splits[0].split('.')
if len(bit_splits) == 2:
base = int(bit_splits[0])
bit = int(bit_splits[1])
else :
base = int(bit_splits[0])
return base, bit, sign
def caculate_comm_str_compare(comm_str : str) :
base, bit, sign = get_comm_str_info(comm_str)
if bit < 0:
return base * 16
else :
return base * 16 + bit
def get_variable_info(comm_str : str, name_str : str, alias_str : str = DEFAULT_EMPTY_STR) :
name = ""
is_float = "#f" in comm_str
is_sign = "#s" in comm_str
is_data_32 = "#2" in comm_str
base, bit, sign = get_comm_str_info(comm_str)
if alias_str != DEFAULT_EMPTY_STR:
type = alias_str
elif is_float :
type = "float"
elif bit >= 0:
type = "uint16_t"
elif is_sign :
type = "int32_t" if is_data_32 else "int16_t"
else :
type = "uint32_t" if is_data_32 else "uint16_t"
name = get_variable_name(name_str)
return type, name
COMM_STRUCT_PROP_STR_DEF = """
typedef struct TCommTable
{
uint32_t comm_addr;
uint16_t offset;
uint16_t default_str_off;
uint16_t is_measure : 1;
uint16_t menu_item_index : 12;
uint16_t data_size : 3;
} TCommTable; \n
"""
COMM_PARA_STRUCT_ITEM_INIT = """
{
//%s
.comm_addr= %d,
.offset = offsetof(TSystemPara, %s),
.is_measure = false,
.default_str_off = %d,
.menu_item_index = %d,
.data_size = sizeof(((TSystemPara *)0)->%s),
},"""
COMM_MEASURE_STRUCT_ITEM_INIT = """
{
//%s
.comm_addr= %d,
.offset = offsetof(TMeasureValue, %s),
.is_measure = true,
.default_str_off = %d,
.menu_item_index = %d,
.data_size = sizeof(((TMeasureValue *)0)->%s),
},"""
class CommTableCreate():
def __init__(self) -> None:
self.CommStringList = []
self.STRUCT_PROP_DEF = COMM_STRUCT_PROP_STR_DEF
def CommFileCreate(self, file_name, dictManager: DictsManager) :
for menu_item_info in dictManager.MenuItemList :
each_dict = menu_item_info[0]
menu_index = menu_item_info[1]
scale_str = utils.dict_or_object_get_attr(each_dict, "scale", "1.0")
format_str = utils.dict_or_object_get_attr(each_dict, "format", "%5.0f")
unit_str = utils.dict_or_object_get_attr(each_dict, "unit", DEFAULT_EMPTY_STR)
name_str = utils.dict_or_object_get_attr(each_dict, "name", DEFAULT_EMPTY_STR)
comm_str = utils.dict_or_object_get_attr(each_dict, "addr", DEFAULT_EMPTY_STR)
min_str = utils.dict_or_object_get_attr(each_dict, "min", DEFAULT_EMPTY_STR)
max_str = utils.dict_or_object_get_attr(each_dict, "max", DEFAULT_EMPTY_STR)
alias_str = utils.dict_or_object_get_attr(each_dict, "alias", DEFAULT_EMPTY_STR)
default_str = utils.dict_or_object_get_attr(each_dict, "default", DEFAULT_EMPTY_STR)
is_measure = utils.dict_or_object_get_attr(each_dict, "measure", False)
default_str = "%s"%(default_str)
if comm_str != DEFAULT_EMPTY_STR :
aleady_exist = False
for item_list in self.CommStringList :
if comm_str == item_list[0] :
aleady_exist = True
break
if aleady_exist == False:
self.CommStringList.append([comm_str, name_str, scale_str, format_str, unit_str, min_str, max_str, alias_str, menu_index, default_str, is_measure])
print ("Sorted Table: ")
sorted_comm_items = sorted(self.CommStringList, key=lambda x: caculate_comm_str_compare(x[0]))
file_name_h = file_name.replace(".c", ".h")
base_name: str = os.path.basename(file_name_h)
FILE_H_HEADER = base_name.replace(".h", "_H").upper()
with open(file_name_h,'w', encoding='utf-8') as file:
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
file.write("/" + "/" + file_name + " create date: " + current_time + "\n")
file.write("#ifndef %s\n"%(FILE_H_HEADER))
file.write("#define %s\n"%(FILE_H_HEADER))
file.write("\n#include <stdint.h>\n")
#定义别名枚举类型
for alias_dict in dictManager.alias_table :
for alias_name, value_dict in alias_dict.items():
if isinstance(alias_name, Enum):
alias_name = alias_name.name
enum_define = True
for key_value, value_str in value_dict.items() :
if isinstance(key_value, Enum):
enum_define = False
break
if enum_define :
file.write("\ntypedef enum %s { \n"%(alias_name))
for key_str, value_str in value_dict.items() :
enum_item_str = alias_name.upper() + "_" + get_variable_name(value_str).upper()
caption_str = value_str
main_str = "%s = %d,"%(enum_item_str, key_str)
write_str = " %-40s//%s\n"%(main_str, caption_str)
file.write(write_str)
file.write("} %s; \n"%(alias_name))
#创建.h文件
para_def_list = []
measure_def_list = []
for items in sorted_comm_items:
is_measure = items[10]
unit_str = "(%s)"%(items[4])
scale_format_str = "%s, %s"%(items[2], items[3])
if items[5] != DEFAULT_EMPTY_STR and items[6] != DEFAULT_EMPTY_STR:
min_max_str = "[%s, %s]"%(items[5], items[6])
else :
min_max_str = DEFAULT_EMPTY_STR
alias_str = items[7]
if isinstance(alias_str, Enum):
alias_str = alias_str.name
para_type, para_name = get_variable_info(items[0], items[1], alias_str)
para_name = para_name
caption = '//%-15s%-10s%-20s%-30s'%(scale_format_str, unit_str, min_max_str, items[1])
para_type_name = "%-20s %s;"%(para_type, para_name)
if is_measure :
measure_def_list.append(" %-50s %s"%(para_type_name, caption) + "\n")
else :
para_def_list.append(" %-50s %s"%(para_type_name, caption) + "\n")
sorted_para_def_list = sorted(para_def_list, key=lambda x: x, reverse=True)
sorted_measure_def_lit = sorted(measure_def_list, key=lambda x: x, reverse=True)
file.write("\ntypedef struct TSystemPara { \n")
for items in sorted_para_def_list:
file.write(items)
file.write("} TSystemPara; \n")
file.write("\ntypedef struct TMeasureValue { \n")
for items in sorted_measure_def_lit:
file.write(items)
file.write("} TMeasureValue; \n")
file.write("\n#endif //%s\n"%(FILE_H_HEADER))
file.close()
#创建.c文件
with open(file_name,'w', encoding='utf-8') as file:
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
file.write("/" + "/" + file_name + " create date: " + current_time + "\n")
file.write("#include <%s>\n"%(base_name))
file.write(self.STRUCT_PROP_DEF)
file.write("\nconst TCommTable CommTable[] = { \n")
for items in sorted_comm_items:
comm_str = items[0]
menu_item_index = items[8]
default_str = items[9]
caption_str = items[1]
is_measure = items[10]
if default_str == DEFAULT_EMPTY_STR :
default_str_offset = 0
else :
default_str_offset = utils.dict_or_object_get_attr(dictManager.MenuStringDict, default_str, 0)
comm_addr, bit, sign = get_comm_str_info(items[0])
para_name = get_variable_name(items[1])
if is_measure :
file.write(COMM_MEASURE_STRUCT_ITEM_INIT%(caption_str, comm_addr, para_name, default_str_offset, menu_item_index, para_name))
else :
file.write(COMM_PARA_STRUCT_ITEM_INIT%(caption_str, comm_addr, para_name, default_str_offset, menu_item_index, para_name))
file.write("\n};")
file.close()
if __name__ == "__main__":
modify_value = 1.0
#把浮点数转换成4字节数, 然后转化成32位整数
bs = struct.pack("f", modify_value)
print("%02x%02x%02x%02x"%(bs[0], bs[1], bs[2], bs[3]))
dictManager = DictsManager()
#[01]打印<别名字典列表alias_table>全部内容 --> DebugPrint(alias_table)
#[02]将所有别名字符串存储到<全局字符串字典MenuStringDict>,根据<别名字典列表alias_table>创建2张别名表 --> Create_MenuAliasTables()->StuffDict_MenuStringDict_ByAliasDict()
#[03]根据菜单内容,填充<全局字符串字典MenuStringDict>和各个字段字典<MenuUnitDict>,<MenuScaleFormatDict>,<MenuActionDict> --> StuffDict_MenuDict()
#[04]根据菜单结构创建2张菜单表 --> Create_MenuItemTable()
#[05]打包<MenuStringDict> 得到Packed_MenuStringTable --> Pack_MeunStringDict()
#[06]打包<MenuUnitDict> 得到Packed_MenuUnitTable --> Pack_MenuUnitDict()
#[07]打包<MenuScaleFormatDict> 得到Packed_MenuScaleFormatTable --> Pack_MenuScaleFormatDict()
#[08]打包<MenuActionDict> 得到Packed_MenuActionTable --> Pack_MenuActionDict()
#[09]打包2张别名表<MenuAliasTable>和<MenuAliasTable2> 得到Packed_AliasBuf和Packed_AliasBuf2 --> Pack_MenuAliasTables()
#[10]打包2张菜单表<MenuMenuTable>和<MenuMenuTable2> 得到Packed_MenuBuf和Packed_MenuBuf2 --> Pack_MenuMenuTable()
#[11]打包全部
DebugPrint("↓---------------------------------------------------S(打印<别名字典列表alias_table>全部内容)---------------------------------------------↓")
DebugPrint("Step_01")
DebugPrint(dictManager.alias_table)
DebugPrint("Step_01")
DebugPrint("↑--------------------alias_table------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
DebugPrint("↓---------------------------------------S(将所有别名字符串存储到<全局字符串字典MenuStringDict>)--------------------------------------------↓")
DebugPrint("↓--------------------------------------------S(根据<别名字典列表alias_table>创建2张别名表)------------------------------------------------↓")
DebugPrint("Step_02")
dictManager.Create_MenuAliasTables()
DebugPrint("__________MenuStringDict___________>"+ str(dictManager.MenuStringDict))
DebugPrint("Step_02")
DebugPrint("↑--------------------------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
dictManager.Create_MenuNameDict()
dictManager.Create_MenuCommTables()
DebugPrint("↓-----------S(根据菜单内容,填充<全局字符串字典MenuStringDict>和各个字段字典<MenuUnitDict>,<MenuScaleFormatDict>,<MenuActionDict>)--------------↓")
DebugPrint("Step_03")
dictManager.Create_MenuInfo()
DebugPrint("↓--------------------------------------------S(根据菜单结构,创建2张菜单表)-----------------------------------------------------------------------↓")
DebugPrint("Step_04")
dictManager.Create_AllMenuItemTable()
DebugPrint("Step_04")
DebugPrint("↑----------------------------------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
dictManager.Create_MenuDescriptionTable()
DebugPrint("<Dict>MenuDescriptionTable->")
DebugPrint(dictManager.MenuDescriptionTable)
DebugPrint(" ")
DebugPrint("<Dict>MenuUnitDict->")
DebugPrint(dictManager.MenuUnitDict)
DebugPrint(" ")
DebugPrint("<Dict>MenuScaleFormatDict->")
DebugPrint(dictManager.MenuScaleFormatDict)
DebugPrint(" ")
DebugPrint("<Dict>MenuActionDict->")
DebugPrint(dictManager.MenuActionDict)
DebugPrint(" ")
DebugPrint("<Dict>MenuStringDict->")
DebugPrint(dictManager.MenuStringDict)
DebugPrint("Step_03")
DebugPrint("↑----------------------------------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
DebugPrint("↓--------------------------------------------S(打包<MenuStringDict> 得到Packed_MenuStringTable )------------------------------------------------↓")
DebugPrint("↓--------------------------------------------S(打包<MenuUnitDict> 得到Packed_MenuUnitTable )------------------------------------------------↓")
DebugPrint("↓--------------------------------------------S(打包<MenuScaleFormatDict> 得到Packed_MenuScaleFormatTable )--------------------------------------↓")
DebugPrint("↓--------------------------------------------S(打包<MenuActionDict> 得到Packed_MenuActionTable )------------------------------------------------↓")
DebugPrint("Step_05")
dictManager.Pack_MeunStringDict()
dictManager.Pack_MenuUnitDict()
dictManager.Pack_MenuScaleFormatDict()
dictManager.Pack_MenuActionDict()
dictManager.Pack_MenuCaptionInfoDict()
dictManager.Pack_MenuLimitDict()
dictManager.Pack_MenuCommDict()
DebugPrint("Step_05")
DebugPrint("↑----------------------------------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
DebugPrint("↓--------------------------------S(打包<MenuAliasTable>和<MenuAliasTable2> 得到Packed_AliasBuf和Packed_AliasBuf2)-------------------------------↓")
DebugPrint("TEST_06")
dictManager.Pack_MenuAliasTables()
DebugPrint("TEST_06")
DebugPrint("↑---------------------------------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
DebugPrint("↓--------------------------------S(打包<MenuMenuTable>和<MenuMenuTable2> 得到Packed_MenuBuf和Packed_MenuBuf2)-------------------------------↓")
DebugPrint("TEST_07")
dictManager.Pack_MenuMenuTable()
DebugPrint("TEST_07")
DebugPrint("↑---------------------------------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
DebugPrint("↓-------------------------------------------------------------------S(打包全部)-----------------------------------------------------------------↓")
DebugPrint("TEST_08")
pack_file_buf = dictManager.Pack_All()
DebugPrint("TEST_08")
DebugPrint("↑---------------------------------------------------------------------------------------------------------------------------------------------↑")
DebugPrint("|")
file_name = sys.path[0] + "/menu.dat"
print(file_name)
dictManager.PackSave(file_name, pack_file_buf)
file_name = sys.path[0] + "/menu_dat.c"
print(file_name)
dictManager.PackSaveC(file_name, pack_file_buf)
print("%s"%(1.23))
name1 = get_variable_name("系统电压")
name2 = get_variable_name("Ia 校正")
name3 = get_variable_name("Ib 校正")
name4 = get_variable_name("馈电设备")
table_create = CommTableCreate()
file_name = sys.path[0] + "/CommTable.c"
table_create.CommFileCreate(file_name, dictManager)