华荣三照明、合信、荣欣八组合馈电
This commit is contained in:
726
menu_group.py
Normal file
726
menu_group.py
Normal file
@ -0,0 +1,726 @@
|
||||
import modbus_tk.defines as cst
|
||||
from modbus_tk import modbus_tcp, hooks, modbus
|
||||
import menu_utils as utils
|
||||
import menu_key_def as KEYDEF
|
||||
import ZZ_9TE as device_9TE
|
||||
import struct
|
||||
from threading import Thread
|
||||
from typing import Tuple
|
||||
from device_conf import class_comm_device_config
|
||||
from comm_device import class_comm_device
|
||||
from menu_base import class_menu_layer_info, class_device_menu
|
||||
import menu_page
|
||||
import modbus_server
|
||||
from modbus_server import class_modbus_tcp_server
|
||||
import comm_global
|
||||
from comm_thread import class_comm_master_thread
|
||||
|
||||
DEFAULT_EMPTY_STR = " "
|
||||
MAX_NUMS_OF_STRING = 20 #每个字符串占用寄存器数
|
||||
MAX_NUMS_OF_MENU_LINE = MAX_NUMS_OF_STRING * 2
|
||||
MAX_NUMS_OF_MODIFY_STRING = 20
|
||||
|
||||
|
||||
MENU_PAGE_DYNAMIC_MENU =1
|
||||
MENU_PAGE_ALARM =2
|
||||
|
||||
class class_menu_group(Thread, class_device_menu) :
|
||||
def __init__(self,
|
||||
device_remap = 0,
|
||||
max_menu_lines = 8,
|
||||
comm_config : class_comm_device_config = None,
|
||||
modbus_tcp_server : class_modbus_tcp_server = None):
|
||||
|
||||
Thread.__init__(self)
|
||||
class_device_menu.__init__(self, device_remap, comm_config)
|
||||
|
||||
self.modbus_tcp_server = modbus_tcp_server
|
||||
self.max_menu_lines = max_menu_lines
|
||||
self.server = None
|
||||
|
||||
self.menu_reg_count = 10000
|
||||
self.menu_active = None if self.config == None else self.config.get_menu_top()
|
||||
return
|
||||
|
||||
def menu_get_regsiter_addr(self, row, col) :
|
||||
if col == 1:
|
||||
addr = modbus_server.REGISTER_MENU_STRING_ROW0_COL1 + row * MAX_NUMS_OF_STRING
|
||||
else :
|
||||
addr = modbus_server.REGISTER_MENU_STRING_ROW0_COL0 + row * MAX_NUMS_OF_STRING
|
||||
return addr
|
||||
|
||||
def register_menu_string_fill(self, addr, menu_str, max_count) :
|
||||
index = 0
|
||||
for chr in menu_str :
|
||||
self.update_server_register(addr + index, ord(chr))
|
||||
if index >= max_count - 1:
|
||||
break
|
||||
index += 1
|
||||
self.update_server_register(addr + index, 0)
|
||||
|
||||
def menu_display_string(self, row, col, menu_str) :
|
||||
addr = self.menu_get_regsiter_addr(row, col)
|
||||
self.register_menu_string_fill(addr, menu_str, MAX_NUMS_OF_STRING)
|
||||
|
||||
def menu_display_modify_caption_string(self, menu_str) :
|
||||
addr = modbus_server.REGISTER_MENU_MODIFY_CAPTION_STRING
|
||||
self.register_menu_string_fill(addr, menu_str, MAX_NUMS_OF_MODIFY_STRING)
|
||||
|
||||
def menu_display_modify_string(self, menu_str) :
|
||||
addr = modbus_server.REGISTER_MENU_MODIFY_STRING
|
||||
self.register_menu_string_fill(addr, menu_str, MAX_NUMS_OF_MODIFY_STRING)
|
||||
|
||||
def menu_display_modify_select_string(self, menu_str) :
|
||||
addr = modbus_server.REGISTER_MENU_MODIFY_SELECT_STRING
|
||||
self.register_menu_string_fill(addr, menu_str, MAX_NUMS_OF_MODIFY_STRING)
|
||||
|
||||
def menu_get_value_regs(self, menu_item) :
|
||||
comm_str = utils.dict_or_object_get_attr(menu_item, "addr", None)
|
||||
value = None
|
||||
comm_thread : class_comm_master_thread= None
|
||||
comm_device : class_comm_device = None
|
||||
comm_device, comm_thread, device_menu = comm_global.search_device_remap_infos(self.device_remap)
|
||||
|
||||
if comm_str != None:
|
||||
reg_addr, bit, reg_count = utils.comm_str_unpack(comm_str)
|
||||
if comm_thread == None or reg_count == 0:
|
||||
value = None
|
||||
elif bit >= 0:
|
||||
start_index = int(bit / 16)
|
||||
end_index = int((bit + reg_count + 15) / 16)
|
||||
reg_items = end_index - start_index
|
||||
value = comm_device.read_register_count(reg_addr + start_index, reg_items)
|
||||
#value = comm_thread.comm_hold_register_read(comm_addr, reg_addr + start_index, reg_items)
|
||||
comm_device.device_comm_flush_request(reg_addr + start_index, reg_items, cycle = 3000)
|
||||
else :
|
||||
value = comm_device.read_register_count(reg_addr, reg_count)
|
||||
#value = comm_thread.comm_hold_register_read(comm_addr, reg_addr, reg_count)
|
||||
|
||||
#刷新请求
|
||||
comm_device.device_comm_flush_request(reg_addr, reg_count, cycle = 3000)
|
||||
return value
|
||||
|
||||
def menu_get_value_scale_float(self, menu_item) :
|
||||
comm_str = utils.dict_or_object_get_attr(menu_item, "addr", None)
|
||||
reg_addr, bit, reg_count = utils.comm_str_unpack(comm_str)
|
||||
value = self.menu_get_value_regs(menu_item)
|
||||
is_big_endian = self.menu_data_is_big_endian(menu_item)
|
||||
is_float = self.menu_data_is_float(menu_item)
|
||||
|
||||
new_value = None
|
||||
if value != None :
|
||||
if len(value) == 2:
|
||||
if is_big_endian:
|
||||
new_value = value[1] + (value[0] << 16)
|
||||
else :
|
||||
new_value = value[0] + (value[1] << 16)
|
||||
|
||||
if is_float :
|
||||
bytes = struct.pack('BBBB', new_value & 0xFF, (new_value >> 8) & 0xFF, (new_value >> 16) & 0xFF, (new_value >> 24) & 0xFF)
|
||||
new_value = struct.unpack("<f", bytes)
|
||||
elif len(value) == 1:
|
||||
new_value = value[0]
|
||||
|
||||
if bit >= 0 and new_value != None and is_float == False:
|
||||
bit = bit % 16
|
||||
new_value = (new_value >> bit) & (0xFFFFFFFF >> (32 - reg_count))
|
||||
|
||||
if new_value != None :
|
||||
scale = utils.dict_or_object_get_attr(menu_item, "scale", 1.0)
|
||||
new_value = new_value * scale
|
||||
return new_value
|
||||
|
||||
def menu_get_value(self, menu_item) :
|
||||
return self.menu_get_value_scale_float(menu_item)
|
||||
|
||||
def menu_write_value(self, menu_item, new_value) :
|
||||
comm_str = utils.dict_or_object_get_attr(menu_item, "addr", None)
|
||||
if comm_str != None and new_value != None:
|
||||
reg_addr, bit, reg_count = utils.comm_str_unpack(comm_str)
|
||||
|
||||
comm_thread : class_comm_master_thread = None
|
||||
comm_device : class_comm_device = None
|
||||
comm_device, comm_thread, device_menu = comm_global.search_device_remap_infos(self.device_remap)
|
||||
|
||||
if comm_thread != None and comm_device != None and reg_count == len(new_value) :
|
||||
return comm_thread.comm_hold_register_write(comm_device.comm_addr, reg_addr, reg_count, new_value)
|
||||
return False
|
||||
|
||||
def menu_get_value_string(self, menu_item) :
|
||||
value_str = None
|
||||
value = None
|
||||
format_str = utils.dict_or_object_get_attr(menu_item, "format", "%f")
|
||||
is_big_endian = self.menu_data_is_big_endian(menu_item)
|
||||
action_str = utils.dict_or_object_get_attr(menu_item, "action", None)
|
||||
|
||||
if action_str == "time" :
|
||||
value = self.menu_get_value_regs(menu_item)
|
||||
value_str = self.menu_get_time_string(value)
|
||||
elif action_str == "date" :
|
||||
value = self.menu_get_value_regs(menu_item)
|
||||
value_str = self.menu_get_date_string(value)
|
||||
elif action_str == "ip" :
|
||||
value = self.menu_get_value_regs(menu_item)
|
||||
value_str = self.menu_get_ip_string(value, is_big_endian)
|
||||
elif action_str != None:
|
||||
return None
|
||||
else :
|
||||
new_value = self.menu_get_value_scale_float(menu_item)
|
||||
if new_value != None :
|
||||
value_str = format_str%(new_value)
|
||||
|
||||
return value_str
|
||||
|
||||
def menu_display_page(self, page) :
|
||||
self.update_server_register(modbus_server.REGISTER_MENU_DISPLAY_PAGE, page)
|
||||
|
||||
def menu_popup_modify_status_change(self, active = False) :
|
||||
self.update_server_register(modbus_server.REGISTER_MENU_POPUP_MODIFY_ACTIVE, int(active))
|
||||
|
||||
def menu_remap_addr_flush(self, menu_table) :
|
||||
if menu_table == None:
|
||||
return
|
||||
for menu_item in menu_table:
|
||||
sub_menu_name = utils.dict_or_object_get_attr(menu_item, "sub_menu", None)
|
||||
sub_menu = self.config.get_menu(sub_menu_name)
|
||||
|
||||
if sub_menu :
|
||||
#子菜单递归调用
|
||||
self.menu_remap_addr_flush(sub_menu)
|
||||
continue
|
||||
remap_addr = utils.dict_or_object_get_attr(menu_item, "remap_addr", None)
|
||||
if remap_addr != None :
|
||||
#需要加上设备重映射基础地址
|
||||
remap_addr += self.device_remap
|
||||
new_value = self.menu_get_value_scale_float(menu_item)
|
||||
if type(new_value) == float:
|
||||
reg_values = []
|
||||
bs = struct.pack('f', new_value)
|
||||
reg_values.append(bs[0] | bs[1] << 8)
|
||||
reg_values.append(bs[2] | bs[3] << 8)
|
||||
self.update_server_register(remap_addr, reg_values)
|
||||
|
||||
def menu_top_remap_addr_flush(self) :
|
||||
self.menu_remap_addr_flush(self.menu_table)
|
||||
|
||||
def menu_display(self):
|
||||
menu_count = 0
|
||||
row = 0
|
||||
col = 0
|
||||
active_layer : class_menu_layer_info = self.menu_get_layer_info()
|
||||
menu_active = active_layer.menu_active
|
||||
|
||||
menu_index = 0
|
||||
for menu_item in menu_active :
|
||||
if menu_index < active_layer.menu_display_start:
|
||||
menu_index += 1
|
||||
continue
|
||||
|
||||
caption = DEFAULT_EMPTY_STR
|
||||
if "name" in menu_item.keys() :
|
||||
caption = menu_item["name"]
|
||||
col = 0
|
||||
self.menu_display_string(row, col, caption)
|
||||
|
||||
sub_menu_name = utils.dict_or_object_get_attr(menu_item, "sub_menu", None)
|
||||
sub_menu = self.config.get_menu(sub_menu_name)
|
||||
|
||||
if sub_menu != None:
|
||||
self.menu_display_string(row, col + 1, " ")
|
||||
else :
|
||||
alias_str = self.menu_get_alias_value_string(menu_item)
|
||||
if alias_str :
|
||||
self.menu_display_string(row, col + 1, alias_str)
|
||||
else :
|
||||
value_str = self.menu_get_value_string(menu_item)
|
||||
if value_str != None :
|
||||
unit_str = utils.dict_or_object_get_attr(menu_item, "unit", DEFAULT_EMPTY_STR)
|
||||
value_str = value_str + " " + unit_str
|
||||
self.menu_display_string(row, col + 1, value_str)
|
||||
else :
|
||||
self.menu_display_string(row, col + 1, DEFAULT_EMPTY_STR)
|
||||
|
||||
row = row + 1
|
||||
menu_count += 1
|
||||
if menu_count >= self.max_menu_lines :
|
||||
break
|
||||
|
||||
while row < self.max_menu_lines :
|
||||
self.menu_display_string(row, 0, DEFAULT_EMPTY_STR)
|
||||
self.menu_display_string(row, 1, DEFAULT_EMPTY_STR)
|
||||
row += 1
|
||||
|
||||
def menu_get_alias_dict(self, alias_name) :
|
||||
alias_value_dict = None
|
||||
if alias_name != None and self.alias_table != None:
|
||||
for alias_dict in self.alias_table :
|
||||
if alias_name in alias_dict.keys() :
|
||||
alias_value_dict = alias_dict[alias_name]
|
||||
return alias_value_dict
|
||||
|
||||
def menu_get_alias_value_string(self, menu_item) :
|
||||
alias = utils.dict_or_object_get_attr(menu_item, "alias", None)
|
||||
if alias == None :
|
||||
return None
|
||||
|
||||
alias_dict = self.menu_get_alias_dict(alias)
|
||||
if alias_dict == None :
|
||||
return None
|
||||
|
||||
value = self.menu_get_value_scale_float(menu_item)
|
||||
alias_value_str = None
|
||||
if alias_dict != None and value != None:
|
||||
alias_value = int(value)
|
||||
if alias_value in alias_dict.keys() :
|
||||
alias_value_str = alias_dict[alias_value]
|
||||
return alias_value_str
|
||||
|
||||
def menu_modify_value_string(self, value_string, unit_string = DEFAULT_EMPTY_STR, caption_string = DEFAULT_EMPTY_STR) :
|
||||
sel_bit = 0
|
||||
if value_string == None:
|
||||
return None
|
||||
|
||||
modify_value_string = value_string
|
||||
key = KEYDEF.MENU_PACK_KEY_NULL
|
||||
while True :
|
||||
key = comm_global.g_key_thread.menu_wait_key(0.1)
|
||||
value_string_display = modify_value_string
|
||||
if key == KEYDEF.MENU_PACK_KEY_RESET_OR_UP or key == KEYDEF.MENU_PACK_KEY_ESCAPE :
|
||||
break
|
||||
if key == KEYDEF.MENU_PACK_KEY_DOWN :
|
||||
if str.isdigit(modify_value_string[sel_bit]) :
|
||||
modify_value_list = list(modify_value_string)
|
||||
modify_value_list[sel_bit] = chr(ord(modify_value_list[sel_bit]) - 1)
|
||||
if modify_value_list[sel_bit] < '0':
|
||||
modify_value_list[sel_bit] = '9'
|
||||
modify_value_string = ''.join(modify_value_list)
|
||||
|
||||
elif key == KEYDEF.MENU_PACK_KEY_UP :
|
||||
if str.isdigit(modify_value_string[sel_bit]) :
|
||||
modify_value_list = list(modify_value_string)
|
||||
modify_value_list[sel_bit] = chr(ord(modify_value_list[sel_bit]) + 1)
|
||||
if modify_value_list[sel_bit] > '9':
|
||||
modify_value_list[sel_bit] = '0'
|
||||
modify_value_string = ''.join(modify_value_list)
|
||||
|
||||
elif key == KEYDEF.MENU_PACK_KEY_ENTER_OR_RIGHT or key == KEYDEF.MENU_PACK_KEY_RIGHT:
|
||||
while sel_bit < len(modify_value_string):
|
||||
sel_bit += 1
|
||||
if sel_bit >= len(modify_value_string) :
|
||||
key = KEYDEF.MENU_PACK_KEY_ENTER
|
||||
break
|
||||
if str.isdigit(modify_value_string[sel_bit]) :
|
||||
break
|
||||
if sel_bit >= len(modify_value_string):
|
||||
break
|
||||
|
||||
value_string_list = list(value_string_display)
|
||||
value_string_list[sel_bit] = ' '
|
||||
value_string_display = ''.join(value_string_list)
|
||||
|
||||
value_string_display_select = modify_value_string[0 : sel_bit + 1]
|
||||
|
||||
self.menu_display_modify_caption_string(caption_string)
|
||||
self.menu_display_modify_string(value_string_display + unit_string)
|
||||
self.menu_display_modify_select_string(value_string_display_select)
|
||||
|
||||
if key == KEYDEF.MENU_PACK_KEY_ENTER or key == KEYDEF.MENU_PACK_KEY_ENTER_OR_RIGHT:
|
||||
return modify_value_string
|
||||
return value_string
|
||||
|
||||
def menu_modify_date_menu_item(self, menu_item) :
|
||||
origin_value = self.menu_get_value_regs(menu_item)
|
||||
value_string = self.menu_get_value_string(menu_item)
|
||||
unit_string = utils.dict_or_object_get_attr(menu_item, "unit", DEFAULT_EMPTY_STR)
|
||||
new_value_string:str = self.menu_modify_value_string(value_string, unit_string)
|
||||
if new_value_string != value_string :
|
||||
date_str = new_value_string.split('-')
|
||||
new_value = origin_value
|
||||
|
||||
if len(date_str) == 3:
|
||||
new_value = []
|
||||
year = int(date_str[0])
|
||||
month = int(date_str[1])
|
||||
day = int(date_str[2])
|
||||
new_value.append(year)
|
||||
new_value.append(month)
|
||||
new_value.append(day)
|
||||
return new_value, True
|
||||
else :
|
||||
return origin_value, False
|
||||
|
||||
def menu_modify_time_menu_item(self, menu_item) :
|
||||
origin_value = self.menu_get_value_regs(menu_item)
|
||||
value_string = self.menu_get_value_string(menu_item)
|
||||
unit_string = utils.dict_or_object_get_attr(menu_item, "unit", DEFAULT_EMPTY_STR)
|
||||
new_value_string:str = self.menu_modify_value_string(value_string, unit_string)
|
||||
if new_value_string != value_string :
|
||||
date_str = new_value_string.split(':')
|
||||
new_value = origin_value
|
||||
|
||||
if len(date_str) == 3:
|
||||
new_value = []
|
||||
hour = int(date_str[0])
|
||||
minute = int(date_str[1])
|
||||
second = int(date_str[2])
|
||||
new_value.append(hour)
|
||||
new_value.append(minute)
|
||||
new_value.append(second)
|
||||
return new_value, True
|
||||
else :
|
||||
return origin_value, False
|
||||
|
||||
def menu_get_date_string(self, date_value) :
|
||||
value_string = None
|
||||
if date_value != None:
|
||||
if len(date_value) == 3 :
|
||||
year = date_value[0]
|
||||
month = date_value[1]
|
||||
day = date_value[2]
|
||||
value_string = "%04d-%02d-%02d"%(year, month, day)
|
||||
return value_string
|
||||
|
||||
def menu_get_time_string(self, time_value) :
|
||||
value_string = None
|
||||
if time_value != None :
|
||||
if len(time_value) == 3 :
|
||||
hour = time_value[0]
|
||||
minute = time_value[1]
|
||||
second = time_value[2]
|
||||
value_string = "%02d:%02d:%02d"%(hour, minute, second)
|
||||
return value_string
|
||||
|
||||
def menu_get_ip_string(self, ip_value, is_big_endian = False) :
|
||||
value_string:str = None
|
||||
if ip_value != None:
|
||||
if len(ip_value) == 2:
|
||||
if is_big_endian:
|
||||
str_ip1 = "%03d"%(((ip_value[1] >> 0) & 0xFF),)
|
||||
str_ip2 = "%03d"%(((ip_value[1] >> 8) & 0xFF),)
|
||||
str_ip3 = "%03d"%(((ip_value[0] >> 16) & 0xFF),)
|
||||
str_ip4 = "%03d"%(((ip_value[0] >> 24) & 0xFF),)
|
||||
else :
|
||||
str_ip1 = "%03d"%(((ip_value[0] >> 0) & 0xFF),)
|
||||
str_ip2 = "%03d"%(((ip_value[0] >> 8) & 0xFF),)
|
||||
str_ip3 = "%03d"%(((ip_value[1] >> 16) & 0xFF),)
|
||||
str_ip4 = "%03d"%(((ip_value[1] >> 24) & 0xFF),)
|
||||
value_string = "%s.%s.%s.%s"%(str_ip1, str_ip2, str_ip3, str_ip4)
|
||||
return value_string
|
||||
|
||||
def menu_get_ip_value(self, ip_str:str) :
|
||||
ip = ip_str.split(sep = '.')
|
||||
ip_value = []
|
||||
|
||||
if len(ip) == 4 :
|
||||
ip0 = int(ip[0])
|
||||
ip1 = int(ip[1])
|
||||
ip2 = int(ip[2])
|
||||
ip3 = int(ip[3])
|
||||
ip_value.append((ip0 << 0) | (ip1 << 8))
|
||||
ip_value.append((ip2 << 16) | (ip3 << 24))
|
||||
return ip_value
|
||||
|
||||
def menu_data_is_big_endian(self, menu_item) :
|
||||
comm_str = utils.dict_or_object_get_attr(menu_item, "addr", DEFAULT_EMPTY_STR)
|
||||
is_big_endian = False
|
||||
if comm_str :
|
||||
if "#>" in comm_str :
|
||||
is_big_endian = True
|
||||
return is_big_endian
|
||||
|
||||
def menu_data_is_float(self, menu_item) :
|
||||
comm_str = utils.dict_or_object_get_attr(menu_item, "addr", DEFAULT_EMPTY_STR)
|
||||
is_float = False
|
||||
if comm_str :
|
||||
if "#f" in comm_str :
|
||||
is_float = True
|
||||
return is_float
|
||||
|
||||
def menu_modify_ip_menu_item(self, menu_item) :
|
||||
origin_value = self.menu_get_value_regs(menu_item)
|
||||
is_big_endian = self.menu_data_is_big_endian(menu_item)
|
||||
|
||||
value_string:str = self.menu_get_ip_string(origin_value, is_big_endian)
|
||||
unit_string = DEFAULT_EMPTY_STR
|
||||
new_value_string = self.menu_modify_value_string(value_string, unit_string)
|
||||
if new_value_string != value_string :
|
||||
new_value = self.menu_get_ip_value(new_value_string)
|
||||
return new_value, True
|
||||
else :
|
||||
return origin_value, False
|
||||
|
||||
def menu_update_modify_regs(self, menu_item, old_value_regs, modify_value) :
|
||||
comm_str = utils.dict_or_object_get_attr(menu_item, "addr", DEFAULT_EMPTY_STR)
|
||||
reg_addr, bit, reg_count = utils.comm_str_unpack(comm_str)
|
||||
scale = utils.dict_or_object_get_attr(menu_item, "scale", 1.0)
|
||||
is_float = self.menu_data_is_float(menu_item)
|
||||
is_big_endian = self.menu_data_is_big_endian(menu_item)
|
||||
|
||||
if modify_value == None :
|
||||
return old_value_regs
|
||||
|
||||
modify_regs = None
|
||||
if len(old_value_regs) == 2:
|
||||
modify_regs = []
|
||||
modify_value = modify_value / scale
|
||||
|
||||
if is_float :
|
||||
#把浮点数转换成4字节数, 然后转化成32位整数
|
||||
bs = struct.pack("f", modify_value)
|
||||
modify_value = bs[0] | (bs[1] << 8) | (bs[2] << 16) | (bs[3] << 24)
|
||||
else :
|
||||
modify_value = int(modify_value)
|
||||
|
||||
if bit >= 0:
|
||||
if is_big_endian :
|
||||
old_value = (old_value_regs[0] << 16) | old_value_regs[1]
|
||||
else :
|
||||
old_value = (old_value_regs[1] << 16) | old_value_regs[0]
|
||||
|
||||
clear_mask = (0xFFFFFFFF >> (32 - reg_count)) << bit
|
||||
set_mask = (modify_value << bit) & clear_mask
|
||||
modify_value = (old_value & ~clear_mask) | set_mask
|
||||
|
||||
if is_big_endian :
|
||||
modify_regs.append((modify_value >> 16) & 0xFFFF)
|
||||
modify_regs.append(modify_value & 0xFFFF)
|
||||
else :
|
||||
modify_regs.append(modify_value & 0xFFFF)
|
||||
modify_regs.append((modify_value >> 16) & 0xFFFF)
|
||||
elif len(old_value_regs) == 1:
|
||||
modify_regs = []
|
||||
modify_value = int(modify_value / scale)
|
||||
if bit >= 0:
|
||||
old_value = old_value_regs[0]
|
||||
clear_mask = (0xFFFFFFFF >> (32 - reg_count)) << bit
|
||||
set_mask = (modify_value << bit) & clear_mask
|
||||
modify_value = (old_value & ~clear_mask) | set_mask
|
||||
modify_regs.append(int(modify_value) & 0xFFFF)
|
||||
|
||||
return modify_regs
|
||||
|
||||
def menu_modify_normal_menu_item(self, menu_item) ->Tuple[list, bool]:
|
||||
old_value_regs = self.menu_get_value_regs(menu_item)
|
||||
value_string = self.menu_get_value_string(menu_item)
|
||||
|
||||
new_value_string = value_string
|
||||
if value_string != None:
|
||||
unit_string = utils.dict_or_object_get_attr(menu_item, "unit", DEFAULT_EMPTY_STR)
|
||||
new_value_string = self.menu_modify_value_string(value_string, unit_string)
|
||||
|
||||
if new_value_string != value_string and value_string != None:
|
||||
modify_value = float(new_value_string)
|
||||
new_value_regs = self.menu_update_modify_regs(menu_item, old_value_regs, modify_value)
|
||||
return new_value_regs, True
|
||||
else :
|
||||
return old_value_regs, False
|
||||
|
||||
def menu_modify_alias_menu_item(self, menu_item):
|
||||
alias = utils.dict_or_object_get_attr(menu_item, "alias", None)
|
||||
alias_dict = self.menu_get_alias_dict(alias)
|
||||
old_value_regs = self.menu_get_value_regs(menu_item)
|
||||
|
||||
if old_value_regs == None:
|
||||
return old_value_regs, False
|
||||
|
||||
fvalue = self.menu_get_value_scale_float(menu_item)
|
||||
alias_value = int(fvalue)
|
||||
|
||||
alias_value_index = -1
|
||||
search_index = 0
|
||||
for item in alias_dict.keys():
|
||||
if item == alias_value :
|
||||
alias_value_index = search_index
|
||||
break
|
||||
search_index += 1
|
||||
|
||||
if alias_value_index < 0 :
|
||||
return old_value_regs, False
|
||||
|
||||
while True :
|
||||
key = comm_global.g_key_thread.menu_wait_key(0.1)
|
||||
|
||||
if key == KEYDEF.MENU_PACK_KEY_DOWN :
|
||||
alias_value_index += 1
|
||||
if alias_value_index >= len(alias_dict) :
|
||||
alias_value_index = 0
|
||||
|
||||
elif key == KEYDEF.MENU_PACK_KEY_UP :
|
||||
alias_value_index -= 1
|
||||
if alias_value_index < 0 :
|
||||
alias_value_index = len(alias_dict) - 1
|
||||
|
||||
new_alias_value = None
|
||||
new_alias_str = DEFAULT_EMPTY_STR
|
||||
|
||||
search_index = 0
|
||||
for new_alias_value, new_alias_str in alias_dict.items() :
|
||||
if search_index == alias_value_index :
|
||||
break
|
||||
search_index += 1
|
||||
|
||||
self.menu_display_modify_string(new_alias_str)
|
||||
self.menu_display_modify_select_string(new_alias_str)
|
||||
|
||||
if key == KEYDEF.MENU_PACK_KEY_ENTER or key == KEYDEF.MENU_PACK_KEY_ENTER_OR_RIGHT :
|
||||
new_value_regs = self.menu_update_modify_regs(menu_item, old_value_regs, new_alias_value)
|
||||
is_modified = True if (new_value_regs != old_value_regs) else False
|
||||
return new_value_regs, is_modified
|
||||
if key == KEYDEF.MENU_PACK_KEY_RESET_OR_UP:
|
||||
return old_value_regs, False
|
||||
|
||||
def _menu_adjust_select_item(self, increase) :
|
||||
active_layer : class_menu_layer_info = self.menu_get_layer_info()
|
||||
|
||||
active_layer.menu_select += increase
|
||||
if increase > 0 and active_layer.menu_select >= active_layer.menu_item_count :
|
||||
active_layer.menu_select = 0
|
||||
|
||||
if active_layer.menu_select < 0 :
|
||||
active_layer.menu_select = active_layer.menu_item_count - 1
|
||||
|
||||
if active_layer.menu_display_start + self.max_menu_lines <= active_layer.menu_select :
|
||||
active_layer.menu_display_start = active_layer.menu_select - self.max_menu_lines + 1
|
||||
|
||||
if active_layer.menu_select < active_layer.menu_display_start :
|
||||
active_layer.menu_display_start = active_layer.menu_select
|
||||
|
||||
def menu_process(self, key = KEYDEF.MENU_PACK_KEY_NULL) -> Tuple[bool] :
|
||||
active_layer : class_menu_layer_info = self.menu_get_layer_info()
|
||||
if active_layer == None :
|
||||
return False
|
||||
|
||||
result = False
|
||||
|
||||
select_row = active_layer.menu_select - active_layer.menu_display_start
|
||||
if select_row >= 0:
|
||||
self.update_server_register(modbus_server.REGISTER_MENU_ITEM_SELECT_MASK, 0x01 << select_row)
|
||||
if key == KEYDEF.MENU_PACK_KEY_UP :
|
||||
self._menu_adjust_select_item(-1)
|
||||
self.update_server_register(modbus_server.REGISTER_MENU_ITEM_SELECT_MASK, 0x01 << select_row)
|
||||
elif key == KEYDEF.MENU_PACK_KEY_DOWN :
|
||||
self._menu_adjust_select_item(1)
|
||||
self.update_server_register(modbus_server.REGISTER_MENU_ITEM_SELECT_MASK, 0x01 << select_row)
|
||||
elif key == KEYDEF.MENU_PACK_KEY_RESET_OR_UP or key == KEYDEF.MENU_PACK_KEY_ESCAPE:
|
||||
self.menu_return_to_upper_layer()
|
||||
elif key == KEYDEF.MENU_PACK_KEY_ENTER_OR_RIGHT or key == KEYDEF.MENU_PACK_KEY_ENTER :
|
||||
menu_item = self.menu_get_active_item()
|
||||
|
||||
#地址映射有效, 修改映射地址
|
||||
device_remap = utils.dict_or_object_get_attr(menu_item, "device_remap", None)
|
||||
if device_remap != None:
|
||||
self.menu_update_device_remap_addr(device_remap)
|
||||
|
||||
function = utils.dict_or_object_get_attr(menu_item, "function", None)
|
||||
if function != None :
|
||||
device_menu = self
|
||||
result = function(device_menu, menu_item)
|
||||
if result :
|
||||
return True
|
||||
|
||||
sub_menu_name = utils.dict_or_object_get_attr(menu_item, "sub_menu", None)
|
||||
sub_menu = self.config.get_menu(sub_menu_name)
|
||||
|
||||
if sub_menu :
|
||||
self.menu_enter_sub_menu(sub_menu)
|
||||
return True
|
||||
|
||||
format_str = utils.dict_or_object_get_attr(menu_item, "format", None)
|
||||
|
||||
action_str = utils.dict_or_object_get_attr(menu_item, "action", None)
|
||||
if action_str == "exit" :
|
||||
self.menu_return_to_upper_layer()
|
||||
return True
|
||||
elif action_str == "exit2" :
|
||||
self.menu_return_to_most_upper_layer()
|
||||
return True
|
||||
|
||||
self.menu_popup_modify_status_change(active = True)
|
||||
changed = False
|
||||
new_value = None
|
||||
|
||||
if action_str == "time":
|
||||
new_value, changed = self.menu_modify_time_menu_item(menu_item)
|
||||
elif action_str == "date" :
|
||||
new_value, changed = self.menu_modify_date_menu_item(menu_item)
|
||||
elif action_str == "ip" :
|
||||
new_value, changed = self.menu_modify_ip_menu_item(menu_item)
|
||||
elif action_str != None :
|
||||
return False
|
||||
else :
|
||||
alias = utils.dict_or_object_get_attr(menu_item, "alias", None)
|
||||
if alias != None :
|
||||
new_value, changed = self.menu_modify_alias_menu_item(menu_item)
|
||||
else:
|
||||
new_value, changed = self.menu_modify_normal_menu_item(menu_item)
|
||||
|
||||
comm_str = utils.dict_or_object_get_attr(menu_item, "addr", DEFAULT_EMPTY_STR)
|
||||
reg_addr, bit, reg_count = utils.comm_str_unpack(comm_str)
|
||||
|
||||
if changed and new_value != None:
|
||||
comm_device :class_comm_device = None
|
||||
|
||||
comm_device, comm_thread, device_menu = comm_global.search_device_remap_infos(self.device_remap)
|
||||
if comm_thread != None and comm_device != None and reg_count > 0:
|
||||
result = comm_device.write_register(reg_addr, reg_count, new_value)
|
||||
#result = comm_thread.comm_hold_register_write(comm_addr, reg_addr, reg_count, new_value)
|
||||
|
||||
self.menu_popup_modify_status_change(active = False)
|
||||
return result
|
||||
|
||||
def update_server_register(self, addr, value) :
|
||||
if self.modbus_tcp_server :
|
||||
self.modbus_tcp_server.update_server_register(addr, value)
|
||||
|
||||
def run(self) :
|
||||
while True:
|
||||
key = comm_global.g_key_thread.menu_wait_key(0.1)
|
||||
|
||||
page = None
|
||||
active_menu = self.menu_get_active_menu()
|
||||
if self.config != None :
|
||||
page = self.config.menu_get_display_page(active_menu)
|
||||
if page == None :
|
||||
page = menu_page.KUNLUN_GRAOUP_PAGE_MENU
|
||||
|
||||
self.menu_display_page(page)
|
||||
self.menu_process(key)
|
||||
self.menu_display()
|
||||
|
||||
'''
|
||||
可使用的函数:
|
||||
创建从站: server.add_slave(slave_id)
|
||||
slave_id(int):从站id
|
||||
为从站添加存储区: slave.add_block(block_name, block_type, starting_address, size)
|
||||
|
||||
block_name(str):block名
|
||||
block_type(int):block类型,COILS = 1,DISCRETE_INPUTS = 2,HOLDING_REGISTERS = 3,ANALOG_INPUTS = 4
|
||||
starting_address(int):起始地址
|
||||
size(int):block大小
|
||||
设置block值:slave.set_values(block_name, address, values)
|
||||
block_name(str):block名
|
||||
address(int):开始修改的地址
|
||||
values(a list or a tuple or a number):要修改的一个(a number)或多个(a list or a tuple)值
|
||||
获取block值:slave.get_values(block_name, address, size)
|
||||
block_name(str):block名
|
||||
address(int):开始获取的地址
|
||||
size(int):要获取的值的数量
|
||||
'''
|
||||
|
||||
if __name__ == '__main__':
|
||||
comm_device_config: class_comm_device_config = device_9TE.comm_device_config
|
||||
_slave_addr = 2
|
||||
|
||||
_device_remap = 2000
|
||||
|
||||
_modbus_tcp_server = class_modbus_tcp_server(slave_addr = _slave_addr,
|
||||
slave_ip= "192.168.1.54",
|
||||
slave_port = 502)
|
||||
|
||||
object_menu_group = class_menu_group(device_remap =_device_remap,
|
||||
comm_config = comm_device_config,
|
||||
modbus_tcp_server = _modbus_tcp_server,
|
||||
max_menu_lines = 8)
|
||||
|
||||
object_menu_group.start()
|
||||
|
||||
Reference in New Issue
Block a user