def __init__(self, focus_node, *args, **kwargs): super(ChartPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.sizer) self.system_info_panel = SystemInfoPanel(self) self.system_info_panel.SetMinSize((1564, 188)) self.sizer.Add(self.system_info_panel, flag=wx.ALL, border=20) self.diagram_info_panel = DiagramInfoPanel(self) self.sizer.Add(self.diagram_info_panel, flag=wx.RIGHT | wx.LEFT, border=20) self.SetBackgroundColour((200, 200, 200)) self.system_info = {} self.focus_node = focus_node self.non_decimal = re.compile(r'[^\d.]+') # 订阅消息 pub.subscribe(self.OnSystemInfoEvent, 'system_info_event') # device_params = DevicesInfo() # for uuid in device_params.get_uuid(): # pub.subscribe(self.OnSystemInfoEvent, uuid[-4:] + '_system_info_event') # print(uuid[-4:] + '_system_info_event') # 绑定 self.Bind(EVT_NODE, self.OnNodeShow)
def __init__(self, focus=False, tab='Charts', name='xxxx', *args, **kwargs): super(TabPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.name = name self.focus = focus self.tab = tab self.sizer = wx.GridBagSizer(0, 0) self.SetSizer(self.sizer) # Device # label = "Node-" + name label = name self.module_name = wx.StaticText(parent=self, size=(222, -1), id=wx.ID_ANY, label=label, style=wx.ALIGN_CENTRE_HORIZONTAL) self.module_name.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.module_name, pos=(0, 0), span=(1, 2), flag=wx.EXPAND | wx.BOTTOM, border=1) # Modules Tab self.modules = wx.StaticText(parent=self, size=(110, -1), id=wx.ID_ANY, label="Modules", style=wx.ALIGN_CENTRE_HORIZONTAL) self.modules.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.modules, pos=(1, 0), flag=wx.EXPAND | wx.LEFT, border=0) # Charts Tab self.charts = wx.StaticText(parent=self, size=(110, -1), id=wx.ID_ANY, label="Charts", style=wx.ALIGN_CENTRE_HORIZONTAL) self.charts.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.charts, pos=(1, 1), flag=wx.EXPAND | wx.LEFT, border=1) if self.focus: self.module_name.SetBackgroundColour((0xfe, 0xd3, 0x63)) self.module_name.SetForegroundColour((0, 0, 0)) if self.tab == 'Modules': # self.modules.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.modules.SetBackgroundColour('DodgerBlue') self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) else: self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour((250, 255, 255)) # self.charts.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.charts.SetBackgroundColour('DodgerBlue') self.charts.SetForegroundColour((250, 255, 255)) else: self.module_name.SetBackgroundColour("GREY") self.module_name.SetForegroundColour((250, 255, 255)) self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) self.module_name.Bind(wx.EVT_LEFT_DCLICK, self.OnNodeNameDoubleClicked) self.modules.Bind(wx.EVT_LEFT_DCLICK, self.OnModulesDoubleClicked) self.charts.Bind(wx.EVT_LEFT_DCLICK, self.OnChartsDoubleClicked)
def __init__(self, nodes, focus_node, *args, **kwargs): super(TabInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.tab_panels = {} self.focus_node = focus_node # 创建水平方向网格 wx.BoxSizer self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.SetSizer(self.sizer) # 创建整个TAB信息 for node in nodes: if node == focus_node: focus = True else: focus = False # 创建每一个TAB Panel panel = TabPanel(focus, tab='Charts', name=node, parent=self) self.sizer.Add(panel, flag=wx.EXPAND | wx.ALIGN_LEFT | wx.RIGHT, border=3) self.tab_panels[node] = panel # 创建菜单图标 self.menu_image = buttons.GenBitmapButton( parent=self, id=wx.ID_ANY, bitmap=wx.Bitmap('res//Menu-icon-white.png'), size=(26, 24), style=wx.BORDER_NONE) self.menu_image.SetBackgroundColour('BLACK') # border = 140 border = 1710 - 248 - (len(nodes) * 220) self.sizer.Add(self.menu_image, flag=wx.EXPAND | wx.LEFT, border=border) pos = self.menu_image.GetPosition() # print("pos = ", pos) # self.menu_image.Bind(wx.EVT_MOTION, self.onMotion) self.menu_image.Bind(wx.EVT_ENTER_WINDOW, self.onEnterWindow) self.menu_image.Bind(wx.EVT_LEAVE_WINDOW, self.onExitWindow) self.Bind(EVT_TAB_NODE, self.OnTabNodeShow) pass
def __init__(self, *args, **kwargs): super(NodeInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.sizer = wx.GridBagSizer(0, 0) self.SetSizer(self.sizer) self.uuid = wx.StaticText(parent=self, id=wx.ID_ANY, label="Device UUID : 1234567812345678", style=wx.ALIGN_LEFT) self.uuid.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.uuid, pos=(0, 0), flag=wx.EXPAND | wx.ALL, border=15) self.ip = wx.StaticText(parent=self, id=wx.ID_ANY, label="IP : 192.168.1.127", style=wx.ALIGN_LEFT) self.ip.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.ip, pos=(0, 1), flag=wx.EXPAND | wx.ALL, border=15) self.hw_version = wx.StaticText(parent=self, id=wx.ID_ANY, label="HW Version : V1.0", style=wx.ALIGN_LEFT) self.hw_version.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.hw_version, pos=(0, 2), flag=wx.EXPAND | wx.ALL, border=15) self.sw_version = wx.StaticText(parent=self, id=wx.ID_ANY, label="SW Version : V1.0", style=wx.ALIGN_LEFT) self.sw_version.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.sw_version, pos=(0, 3), flag=wx.EXPAND | wx.ALL, border=15) self.Bind(EVT_NODE_INFO, self.OnNodeInfoEvent) '''
def __init__(self, file="kylin/config.json"): self.__logger = SingleLogger() self._cfg = DEFAULT_SYSTEM_CONFIG path = os.getcwd() + "/" + file # print("path = ", path) try: with open(path, 'r', encoding='utf-8') as f: try: self._cfg = json.load(f) # print(self._cfg) except Exception as e: print(e) self._cfg = DEFAULT_SYSTEM_CONFIG except Exception as e: print(e) self._cfg = DEFAULT_SYSTEM_CONFIG # 获取各个网卡的mac地址 self.__mac_dict = dict() dic = psutil.net_if_addrs() # print("dic = ", dic) for adapter in dic: # print("adapter = ", adapter) sniclist = dic[adapter] for snic in sniclist: # print(type(snic)) # print("snic = ", snic) # print(snic.address) self.__mac_dict[adapter] = snic.address
def __init__(self, name, data, event): super().__init__(name=name) # 调用父类(超类)的__init__()方法 # 初始化日志类 self.__logger = SingleLogger() # 外部通讯参数 self.__queue = data # 用于向外部传输队列数 self.__event = event # 用于触发外部事件 # 控制线程参数初始化 self.__flag = threading.Event() # 用于暂停线程的标识 self.__flag.set() # 设置为True,默认线程运行 self.__running = threading.Event() # 用于停止线程的标识 self.__running.set() # 将running设置为True # 获取系统参数 self.__system_config = system_params() # CAN分析仪的初始化 vid, pid = self.__system_config.get_can_analyzer_info() self.__canfd = CanAnalyze_ZLG(vid, pid) self.__canfd.StartAll() # 协议初始化 self.protocol = ModuleProtocol() # 获取CAN服务器的运行方式 self.__policy = self.__system_config.get_can_protocol() self.__logger.debug("can protocol = %s" % self.__policy) # 服务器不同的协议处理方式 self.__canfd_protocol_treat = { "echo": self.echo, "monitor": self.monitor, "uds": self.uds } # 每个CAN通道的变量 self.msg = dict() # 每个CAN通道的数据bytearray self.start_flag = dict() # 每个CAN通道的数据魔术字状态 # CAN Tree self.__can_node_info = self.__system_config.get_can_all_module_info() # CAN服务器的状态机 ('idle', 'echo', 'monitor', 'uds') self.state = 'idle'
def setup(self): """ 每一个连接建立后的初始化 :return: """ super().setup() g_client_pool.append(self.client_address[0]) # 加入客户端IP地址 g_conn_pool[self.client_address[0]] = self.request # 加入连接池 g_protocol_pool[self.client_address[0]] = ModuleProtocol(self.client_address[0]) # 加入协议对象池 # # wx.CallAfter(pub.sendMessage, 'socket_setup_event', ip=self.client_address[0]) # print('socket(%s) setup!' % self.client_address[0]) single_logger = SingleLogger() single_logger.info('socket(%s) setup!' % self.client_address[0])
def finish(self): """ 每一个连接断开后的清理 :return: """ super().finish() print(self.client_address) # wx.CallAfter(pub.sendMessage, 'socket_finish_event', ip=self.client_address[0]) g_client_pool.remove(self.client_address[0]) # 从客户端IP池移除当前IP地址 del g_conn_pool[self.client_address[0]] # 清除连接池中当前socket句柄 del g_protocol_pool[self.client_address[0]] # 清除协议对象池中当前协议对象 # print('socket(%s) finish!' % self.client_address[0]) single_logger = SingleLogger() single_logger.info('socket(%s) finish!' % self.client_address[0])
def __init__(self, ip='127.0.0.1', serial_id=bytearray([0, 0, 0, 0, 0, 0])): """ 构造方法, 初始化变量 :param ip: 默认的客户端IP """ # self.__ip = ip self.__uuid = "" # 初始化日志类 self.__logger = SingleLogger() # 初始化设备日志 self.__device_logger = None # self.__device_logger = LogFile("12345678") # 初始化需要发布的消息 self.__pub_module_info_msg_name = "module_info_event" # module信息传输触发事件 self.__pub_system_info_msg_name = "system_info_event" # system信息传输触发事件 self.__pub_device_ready_msg_name = "device_node_ready" # 设备准备好触发事件 # print("pub module info : ", self.__pub_module_info_msg_name) # print("pub system info : ", self.__pub_system_info_msg_name) # print("pub device ready : ", self.__pub_device_ready_msg_name) self.__system_info = { "version": {}, "temperature": {}, "memory": {}, "cpu": {}, "storage": {}, "socket": {}, 'uuid': {}, 'uptime': {} } self.vendor_id = const.GWM_VENDOR_ID # 默认厂商号 self.product_id = const.L2_DEVICE_ID self.serial_id = serial_id self._serial_number = 0 # 发送序列号,依次递增 pass
def __init__(self, vendor_id, product_id): # 初始化日志类 self.__logger = SingleLogger() # CAN分析仪参数 self.__vendor_id = vendor_id self.__product_id = product_id self._canfd_devices = [] # CAN 分析仪列表 self._device_number = self.scan_devices(vendor_id, product_id) # CAN分析仪的个数 pass
def __init__(self, name, data, event): super().__init__(name=name) # 调用父类(超类)的__init__()方法 # 初始化日志类 self.__logger = SingleLogger() # 外部通讯参数 self.__queue = data # 用于向外部传输队列数 self.__event = event # 用于触发外部事件 # 控制线程参数初始化 self.__flag = threading.Event() # 用于暂停线程的标识 self.__flag.clear() # 设置为False self.__running = threading.Event() # 用于停止线程的标识 self.__running.set() # 将running设置为True # 获取Module Server的IP和Port system_config = system_params() self.__ip, self.__port = system_config.get_module_server_info() self.__logger.debug("ip = %s" % self.__ip) self.__logger.debug("port = %s" % self.__port)
def license_verify(): logger = SingleLogger() mac_info, date = aes_decrypt() if not mac_verify(mac_info): logger.error("使用MAC地址无法通过校验") return False if not date_verify(date): logger.error("使用期限已过期") return False logger.info("校验已通过,请放心使用") return True
def kylin_main(): single_logger = SingleLogger() single_logger.info('--主线程开始--') app = MechIIApp() queue = Queue() event = threading.Event() # 创建Module Server独立线程 single_logger.info("Module Server Start...") module_server_thread = ModuleServerThread("ModuleServer", queue, event) module_server_thread.start() # 创建CAN Server独立线程 system_config = system_params() vid, pid = system_config.get_can_analyzer_info() if vid != 0 and pid != 0: single_logger.info("CAN Server Start...") can_server_thread = CANServerThread("CANServer", queue, event) can_server_thread.start() app.MainLoop()
def __init__(self, vendor_id, product_id): # 初始化日志类 self.__logger = SingleLogger() super().__init__(vendor_id, product_id) self._canfd_so = "hw/libusbcanfd.so" # CANFD动态库名称 self._canfd = CDLL(self._canfd_so) # 获取CANFD的句柄 self._device_type = 33 # 设备类型 (USBCANFD-200U) self._can_err_msg = ZCAN_ERR_MSG() # self._can_stat = ZCAN_STAT() # CAN分析仪的初始化参数配置 can_clk = 60000000 can_mod = 0 aset = ASET(tseg1=6, tseg2=1, sjw=1, smp=0, brp=5) dset = DSET( tseg1=6, tseg2=1, sjw=1, smp=0, brp=2, ) self._init_info = ZCAN_INIT(clk=can_clk, mode=can_mod, aset=aset, dset=dset) # # self.device_number = self.scan_devices(vendor_id, product_id) # print("device number2 = ", len(self._canfd_devices)) # 获取CAN分析仪的设备信息,保存到私有变量self._canfd_devices_info中 # self._canfd_devices_info = dict() self._canfd_devices_info = self.GetDevicesInfo()
def __init__(self, devices_info={}, focus_device='', focus_node='', UpdateFrame=None, *args, **kwargs): super(MechIIViewer, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() # 更新主窗体方法,通过FrameManager类 self.UpdateFrame = UpdateFrame # 获取设备节点信息 self.devices_info = devices_info self.focus_device = focus_device self.focus_node = focus_node # 创建二维网格 wx.GridBagSizer, 列间隔为0,行间隔为0 self.sizer = wx.GridBagSizer(0, 0) # 设置ICON图标区域 --> 指定大小 (248, 110) self.icon_panel = IconPanel(self) # 控件占满可用空间,四周都增加宽度为0的空白 self.sizer.Add(self.icon_panel, pos=(0, 0), flag=wx.EXPAND | wx.ALL, border=0) self.icon_panel.SetBackgroundColour((0x38, 0x38, 0x38)) # 设置Device信息区域 self.device_info_panel = DeviceInfoPanel( devices=self.devices_info, focus_device=self.focus_device, focus_node=self.focus_node, parent=self) # 控件占满可用空间,四周都增加宽度为0的空白 self.sizer.Add(self.device_info_panel, pos=(1, 0), flag=wx.EXPAND | wx.ALL, border=0) # 创建TAB信息区域 nodes = [] for k, v in self.devices_info.items(): nodes += v self.tab_info_panel = TabInfoPanel(nodes=nodes, focus_node=self.focus_node, parent=self) # 控件占满可用空间,底部对齐,左边增加宽度为2的空白 self.sizer.Add(self.tab_info_panel, pos=(0, 1), flag=wx.EXPAND | wx.ALIGN_BOTTOM | wx.LEFT, border=2) # 创建chart图表区域 --> 默认显示 self.chart_panel = ChartPanel(self.focus_node, self) self.chart_panel.SetMinSize((1600, 960)) self.chart_panel.Hide() self.chart_panel.Show() # 控件占满可用空间,顶部对齐,左边,上边增加宽度为2的空白 self.sizer.Add(self.chart_panel, pos=(1, 1), flag=wx.EXPAND | wx.ALIGN_TOP | wx.TOP | wx.LEFT, border=2) # 创建module模组区域 --> 默认隐藏 self.module_panel = ModulePanel(self) self.module_panel.SetMinSize((1600, 960)) self.module_panel.Hide() # self.module_panel.Show() # self.sizer.Add(self.module_panel, pos=(1, 1), flag=wx.EXPAND | wx.ALIGN_TOP | wx.TOP | wx.LEFT, border=2) # 刷新 self.sizer.Layout() # 设置窗口到当前Sizer self.SetSizer(self.sizer) # 设置整个Panel背景色 (黑色) self.SetBackgroundColour((0, 0, 0)) # 绑定自定义的双击事件 self.Bind(EVT_MODULE, self.OnModuleShow) self.Bind(EVT_CHART, self.OnChartShow)
class NodeInfoPanel(wx.Panel): """ """ def __init__(self, *args, **kwargs): super(NodeInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.sizer = wx.GridBagSizer(0, 0) self.SetSizer(self.sizer) self.uuid = wx.StaticText(parent=self, id=wx.ID_ANY, label="Device UUID : 1234567812345678", style=wx.ALIGN_LEFT) self.uuid.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.uuid, pos=(0, 0), flag=wx.EXPAND | wx.ALL, border=15) self.ip = wx.StaticText(parent=self, id=wx.ID_ANY, label="IP : 192.168.1.127", style=wx.ALIGN_LEFT) self.ip.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.ip, pos=(0, 1), flag=wx.EXPAND | wx.ALL, border=15) self.hw_version = wx.StaticText(parent=self, id=wx.ID_ANY, label="HW Version : V1.0", style=wx.ALIGN_LEFT) self.hw_version.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.hw_version, pos=(0, 2), flag=wx.EXPAND | wx.ALL, border=15) self.sw_version = wx.StaticText(parent=self, id=wx.ID_ANY, label="SW Version : V1.0", style=wx.ALIGN_LEFT) self.sw_version.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.sw_version, pos=(0, 3), flag=wx.EXPAND | wx.ALL, border=15) self.Bind(EVT_NODE_INFO, self.OnNodeInfoEvent) ''' self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.SetSizer(self.sizer) self.uuid = wx.StaticText(parent=self, id=wx.ID_ANY, label="Device UUID : 1234567812345678", style=wx.ALIGN_LEFT) self.uuid.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.uuid, proportion=1, flag=wx.LEFT | wx.TOP, border=10) self.ip = wx.StaticText(parent=self, id=wx.ID_ANY, label="IP : 192.168.1.127", style=wx.ALIGN_LEFT) self.ip.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.ip, proportion=1, flag=wx.TOP, border=10) self.hw_version = wx.StaticText(parent=self, id=wx.ID_ANY, label="HW Version : V1.0", style=wx.ALIGN_LEFT) self.hw_version.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.hw_version, proportion=1, flag=wx.TOP, border=10) self.sw_version = wx.StaticText(parent=self, id=wx.ID_ANY, label="SW Version : V1.0", style=wx.ALIGN_LEFT) self.sw_version.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.sw_version, proportion=1, flag=wx.TOP, border=10) ''' def OnNodeInfoEvent(self, evt): # print("hw = ", evt.hw) # print("sw = ", evt.sw) # print("ip = ", evt.ip) # print("uuid = ", evt.uuid) self.__logger.debug("hw = {}".format(evt.hw)) self.__logger.debug("sw = {}".format(evt.sw)) self.__logger.debug("ip = {}".format(evt.ip)) self.__logger.debug("uuid = {}".format(evt.uuid)) label = "HW Version : V%s" % evt.hw self.hw_version.SetLabelText(label) label = "SW Version : V%s" % evt.sw self.sw_version.SetLabelText(label) label = "IP : %s" % evt.ip self.ip.SetLabelText(label) label = "Device UUID : %s" % evt.uuid self.uuid.SetLabelText(label) pass
class TabInfoPanel(wx.Panel): """ 整个切换信息面板 """ def __init__(self, nodes, focus_node, *args, **kwargs): super(TabInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.tab_panels = {} self.focus_node = focus_node # 创建水平方向网格 wx.BoxSizer self.sizer = wx.BoxSizer(wx.HORIZONTAL) self.SetSizer(self.sizer) # 创建整个TAB信息 for node in nodes: if node == focus_node: focus = True else: focus = False # 创建每一个TAB Panel panel = TabPanel(focus, tab='Charts', name=node, parent=self) self.sizer.Add(panel, flag=wx.EXPAND | wx.ALIGN_LEFT | wx.RIGHT, border=3) self.tab_panels[node] = panel # 创建菜单图标 self.menu_image = buttons.GenBitmapButton( parent=self, id=wx.ID_ANY, bitmap=wx.Bitmap('res//Menu-icon-white.png'), size=(26, 24), style=wx.BORDER_NONE) self.menu_image.SetBackgroundColour('BLACK') # border = 140 border = 1710 - 248 - (len(nodes) * 220) self.sizer.Add(self.menu_image, flag=wx.EXPAND | wx.LEFT, border=border) pos = self.menu_image.GetPosition() # print("pos = ", pos) # self.menu_image.Bind(wx.EVT_MOTION, self.onMotion) self.menu_image.Bind(wx.EVT_ENTER_WINDOW, self.onEnterWindow) self.menu_image.Bind(wx.EVT_LEAVE_WINDOW, self.onExitWindow) self.Bind(EVT_TAB_NODE, self.OnTabNodeShow) pass def OnTabNodeShow(self, evt): """ :param evt: :return: """ self.__logger.info("Switch Node = {} --> {}".format( self.focus_node, evt.name)) if self.focus_node != evt.name: panel = self.tab_panels[self.focus_node] panel.SetFocus(False) panel = self.tab_panels[evt.name] panel.SetFocus(True) self.focus_node = evt.name pass def onMotion(self, evt): # print("onMotion") pass def onEnterWindow(self, evt): print("onEnterWindow") print(evt.GetPosition()) pos = evt.GetPosition() pos = self.ScreenToClient(pos) print("pos = ", pos) self.main_popup_menu = MenuPopup(self) #self.PopupMenu(self.main_popup_menu, pos) self.PopupMenu(self.main_popup_menu, (1350, 60)) self.main_popup_menu.Destroy() # evt.Skip() # ''' try: self.win.GetTopLevelParent() except: self.win = MenuPopup(self.GetTopLevelParent(), wx.SIMPLE_BORDER) btn = evt.GetEventObject() pos = btn.ClientToScreen((0, 0)) sz = btn.GetSize() # 设置弹窗的位置 self.win.Position((300, 300), (500, 500)) self.win.Show(True) ''' pass def onExitWindow(self, evt): print("onExitWindow") # evt.Skip() # self.Destroy() pass
class PerformanceInfoPanel(wx.Panel): def __init__(self, *args, **kwargs): super(PerformanceInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.sizer = wx.GridBagSizer(0, 0) self.SetSizer(self.sizer) self.uptime_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Up Time", size=(300, 30), style=wx.ALIGN_CENTER) self.uptime_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.uptime_title.SetBackgroundColour("Grey") self.uptime_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.uptime_title, pos=(0, 0), flag=wx.EXPAND | wx.LEFT, border=10) self.uptime_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="0:00:00:000", size=(300, 62), style=wx.ALIGN_CENTER) self.uptime_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.uptime_value.SetBackgroundColour("GREY") self.uptime_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.uptime_value, pos=(1, 0), flag=wx.EXPAND | wx.LEFT, border=10) self.temperature_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Device Temperature", size=(300, 30), style=wx.ALIGN_CENTER) self.temperature_title.SetFont( wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.temperature_title.SetBackgroundColour("GREY") self.temperature_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.temperature_title, pos=(0, 1), flag=wx.EXPAND | wx.LEFT, border=10) self.temperature_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="30.0 ℃", size=(300, 62), style=wx.ALIGN_CENTER) self.temperature_value.SetFont( wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.temperature_value.SetBackgroundColour("GREY") self.temperature_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.temperature_value, pos=(1, 1), flag=wx.EXPAND | wx.LEFT, border=10) self.memory_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Memory", size=(300, 40), style=wx.ALIGN_CENTER) self.memory_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.memory_title.SetBackgroundColour("GREY") self.memory_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.memory_title, pos=(0, 2), flag=wx.EXPAND | wx.LEFT, border=10) self.memory_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="28%", size=(300, 62), style=wx.ALIGN_CENTER) self.memory_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.memory_value.SetBackgroundColour("GREY") self.memory_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.memory_value, pos=(1, 2), flag=wx.EXPAND | wx.LEFT, border=10) self.network_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Network Speed", size=(300, 30), style=wx.ALIGN_CENTER) self.network_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.network_title.SetBackgroundColour("GREY") self.network_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.network_title, pos=(0, 3), flag=wx.EXPAND | wx.LEFT, border=10) self.network_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="16Kbps", size=(300, 62), style=wx.ALIGN_CENTER) self.network_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.network_value.SetBackgroundColour("GREY") self.network_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.network_value, pos=(1, 3), flag=wx.EXPAND | wx.LEFT, border=10) self.cpu_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="CPU", size=(300, 30), style=wx.ALIGN_CENTER) self.cpu_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.cpu_title.SetBackgroundColour("GREY") self.cpu_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.cpu_title, pos=(0, 4), flag=wx.EXPAND | wx.LEFT, border=10) self.cpu_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="8", size=(300, 62), style=wx.ALIGN_CENTER) self.cpu_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.cpu_value.SetBackgroundColour("GREY") self.cpu_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.cpu_value, pos=(1, 4), flag=wx.EXPAND | wx.LEFT, border=10) self.Bind(EVT_PERFORMANCE_INFO, self.OnPerformanceInfoEvent) def OnPerformanceInfoEvent(self, evt): # print("uptime = ", evt.uptime) # print("temperature = ", evt.temperature) # print("memory = ", evt.memory) # print(type(evt.memory)) # print("network total = ", evt.network) # print("cpu = ", evt.cpu) self.__logger.debug("uptime = {}".format(evt.uptime)) self.__logger.debug("temperature = {}".format(evt.temperature)) self.__logger.debug("memory = {}".format(evt.memory)) self.__logger.debug("temperature = {}".format(evt.network)) self.__logger.debug("cpu = {}".format(evt.cpu)) self.uptime_value.SetLabelText(evt.uptime) label = "%s ℃" % evt.temperature self.temperature_value.SetLabelText(label) label = "%s%%" % evt.memory self.memory_value.SetLabelText(label) label = "%sBps" % evt.network self.network_value.SetLabelText(label) label = "%s" % evt.cpu self.cpu_value.SetLabelText(label)
def __init__(self, *args, **kwargs): super(PerformanceInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.sizer = wx.GridBagSizer(0, 0) self.SetSizer(self.sizer) self.uptime_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Up Time", size=(300, 30), style=wx.ALIGN_CENTER) self.uptime_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.uptime_title.SetBackgroundColour("Grey") self.uptime_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.uptime_title, pos=(0, 0), flag=wx.EXPAND | wx.LEFT, border=10) self.uptime_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="0:00:00:000", size=(300, 62), style=wx.ALIGN_CENTER) self.uptime_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.uptime_value.SetBackgroundColour("GREY") self.uptime_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.uptime_value, pos=(1, 0), flag=wx.EXPAND | wx.LEFT, border=10) self.temperature_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Device Temperature", size=(300, 30), style=wx.ALIGN_CENTER) self.temperature_title.SetFont( wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.temperature_title.SetBackgroundColour("GREY") self.temperature_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.temperature_title, pos=(0, 1), flag=wx.EXPAND | wx.LEFT, border=10) self.temperature_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="30.0 ℃", size=(300, 62), style=wx.ALIGN_CENTER) self.temperature_value.SetFont( wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.temperature_value.SetBackgroundColour("GREY") self.temperature_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.temperature_value, pos=(1, 1), flag=wx.EXPAND | wx.LEFT, border=10) self.memory_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Memory", size=(300, 40), style=wx.ALIGN_CENTER) self.memory_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.memory_title.SetBackgroundColour("GREY") self.memory_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.memory_title, pos=(0, 2), flag=wx.EXPAND | wx.LEFT, border=10) self.memory_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="28%", size=(300, 62), style=wx.ALIGN_CENTER) self.memory_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.memory_value.SetBackgroundColour("GREY") self.memory_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.memory_value, pos=(1, 2), flag=wx.EXPAND | wx.LEFT, border=10) self.network_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="Network Speed", size=(300, 30), style=wx.ALIGN_CENTER) self.network_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.network_title.SetBackgroundColour("GREY") self.network_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.network_title, pos=(0, 3), flag=wx.EXPAND | wx.LEFT, border=10) self.network_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="16Kbps", size=(300, 62), style=wx.ALIGN_CENTER) self.network_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.network_value.SetBackgroundColour("GREY") self.network_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.network_value, pos=(1, 3), flag=wx.EXPAND | wx.LEFT, border=10) self.cpu_title = wx.StaticText(parent=self, id=wx.ID_ANY, label="CPU", size=(300, 30), style=wx.ALIGN_CENTER) self.cpu_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.cpu_title.SetBackgroundColour("GREY") self.cpu_title.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.cpu_title, pos=(0, 4), flag=wx.EXPAND | wx.LEFT, border=10) self.cpu_value = wx.StaticText(parent=self, id=wx.ID_ANY, label="8", size=(300, 62), style=wx.ALIGN_CENTER) self.cpu_value.SetFont(wx.Font(32, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.cpu_value.SetBackgroundColour("GREY") self.cpu_value.SetForegroundColour((255, 255, 255)) self.sizer.Add(self.cpu_value, pos=(1, 4), flag=wx.EXPAND | wx.LEFT, border=10) self.Bind(EVT_PERFORMANCE_INFO, self.OnPerformanceInfoEvent)
class TabPanel(wx.Panel): """ 单个切换信息面板 """ def __init__(self, focus=False, tab='Charts', name='xxxx', *args, **kwargs): super(TabPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.name = name self.focus = focus self.tab = tab self.sizer = wx.GridBagSizer(0, 0) self.SetSizer(self.sizer) # Device # label = "Node-" + name label = name self.module_name = wx.StaticText(parent=self, size=(222, -1), id=wx.ID_ANY, label=label, style=wx.ALIGN_CENTRE_HORIZONTAL) self.module_name.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.module_name, pos=(0, 0), span=(1, 2), flag=wx.EXPAND | wx.BOTTOM, border=1) # Modules Tab self.modules = wx.StaticText(parent=self, size=(110, -1), id=wx.ID_ANY, label="Modules", style=wx.ALIGN_CENTRE_HORIZONTAL) self.modules.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.modules, pos=(1, 0), flag=wx.EXPAND | wx.LEFT, border=0) # Charts Tab self.charts = wx.StaticText(parent=self, size=(110, -1), id=wx.ID_ANY, label="Charts", style=wx.ALIGN_CENTRE_HORIZONTAL) self.charts.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.sizer.Add(self.charts, pos=(1, 1), flag=wx.EXPAND | wx.LEFT, border=1) if self.focus: self.module_name.SetBackgroundColour((0xfe, 0xd3, 0x63)) self.module_name.SetForegroundColour((0, 0, 0)) if self.tab == 'Modules': # self.modules.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.modules.SetBackgroundColour('DodgerBlue') self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) else: self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour((250, 255, 255)) # self.charts.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.charts.SetBackgroundColour('DodgerBlue') self.charts.SetForegroundColour((250, 255, 255)) else: self.module_name.SetBackgroundColour("GREY") self.module_name.SetForegroundColour((250, 255, 255)) self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) self.module_name.Bind(wx.EVT_LEFT_DCLICK, self.OnNodeNameDoubleClicked) self.modules.Bind(wx.EVT_LEFT_DCLICK, self.OnModulesDoubleClicked) self.charts.Bind(wx.EVT_LEFT_DCLICK, self.OnChartsDoubleClicked) def SetFocus(self, focus): """ 设置当前TAB面板是否聚焦 :param focus: =True, 设置当前面板聚焦 :return: """ # print("name = ", self.name) # print("focus = ", focus) # print("self.focus = ", self.focus) # print("self.tab = ", self.tab) if self.focus != focus: if focus: self.module_name.SetBackgroundColour((0xfe, 0xd3, 0x63)) self.module_name.SetForegroundColour((0, 0, 0)) if self.tab == 'Modules': #self.modules.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.modules.SetBackgroundColour('DodgerBlue') self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) else: self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour((250, 255, 255)) # self.charts.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.charts.SetBackgroundColour('DodgerBlue') self.charts.SetForegroundColour((250, 255, 255)) if self.tab == 'Modules': # self.modules.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.modules.SetBackgroundColour('DodgerBlue') self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) # 发送切换Module图表 evt = ModuleEvent( name=self.tab, ) wx.QueueEvent(wx.GetApp().GetTopWindow(), evt) else: self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour((250, 255, 255)) # self.charts.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.charts.SetBackgroundColour('DodgerBlue') self.charts.SetForegroundColour((250, 255, 255)) # 发送切换Chart图表 evt = ChartEvent( name=self.tab, ) wx.QueueEvent(wx.GetApp().GetTopWindow(), evt) else: self.module_name.SetBackgroundColour("GREY") self.module_name.SetForegroundColour((250, 255, 255)) self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) self.focus = focus pass def OnNodeNameDoubleClicked(self, event): """ 双击TAB区域中Node名字的事件处理 :param event: :return: """ self.__logger.info("double click Node {}".format(self.name)) # 向Device信息区域发送选中Node的信息 evt = NodeEvent( name=self.name, ) wx.QueueEvent(wx.GetApp().GetTopWindow().device_info_panel, evt) # 向Chart图表区域, 发送选中Node的信息 evt = NodeEvent( name=self.name, ) wx.QueueEvent(wx.GetApp().GetTopWindow().chart_panel, evt) # 向ModuleList信息区域,发送选中Node的信息 evt = NodeEvent( name=self.name, ) wx.QueueEvent(wx.GetApp().GetTopWindow().module_panel.list, evt) # 向Tab信息区域发送选中Node的信息 evt = NodeTabEvent( name=self.name, ) wx.QueueEvent(wx.GetApp().GetTopWindow().tab_info_panel, evt) def OnModulesDoubleClicked(self, event): """ 双击Module Tab的事件处理 :param event: :return: """ self.__logger.info("Double click Chart --> Module") if not self.focus: return if self.tab == 'Charts': # self.modules.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.modules.SetBackgroundColour('DodgerBlue') self.modules.SetForegroundColour((250, 255, 255)) self.charts.SetBackgroundColour("GREY") self.charts.SetForegroundColour((250, 255, 255)) evt = ModuleEvent( name=self.tab, ) wx.QueueEvent(wx.GetApp().GetTopWindow(), evt) self.tab = 'Modules' def OnChartsDoubleClicked(self, event): """ 双击Chart Tab的事件处理 :param event: :return: """ self.__logger.info("Double click Module --> Chart") if not self.focus: return if self.tab == 'Modules': self.modules.SetBackgroundColour("GREY") self.modules.SetForegroundColour("WHITE") #self.charts.SetBackgroundColour((0x27, 0xc1, 0xf8)) self.charts.SetBackgroundColour('DodgerBlue') self.charts.SetForegroundColour((250, 255, 255)) evt = ChartEvent( name=self.tab, ) wx.QueueEvent(wx.GetApp().GetTopWindow(), evt) self.tab = 'Charts'
class DeviceInfoPanel(wx.Panel): """ 设备信息面板, 包含多个设备信息 """ def __init__(self, devices={}, focus_device='', focus_node='', *args, **kwargs): super(DeviceInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.devices_info = devices self.focus_device = focus_device self.focus_node = focus_node self.devices_panel = {} self.devices_status = {} # 描述每个Device信息的打开关闭状态 self.nodes_panel = {} # 创建垂直方向网格 wx.BoxSizer, self.sizer = wx.BoxSizer(wx.VERTICAL) for device_name, nodes_name in devices.items(): self.devices_status[device_name] = True # 默认Device信息都是打开状态 # print("device name = ", device_name) if focus_device == device_name: focus = True else: focus = False device_panel = DevicePanel(name=device_name, focus=focus, status=self.devices_status[device_name], parent=self) if focus: device_panel.SetBackgroundColour('DodgerBlue') # device_panel.SetBackgroundColour((0x27, 0xc1, 0xf8)) device_panel.SetForegroundColour((250, 255, 255)) else: device_panel.SetBackgroundColour("GREY") device_panel.SetForegroundColour((250, 255, 255)) self.sizer.Add(device_panel, flag=wx.EXPAND | wx.TOP, border=1) self.devices_panel[device_name] = device_panel for node_name in nodes_name: # print("node name = ", node_name) if focus_node == node_name: focus = True else: focus = False node_panel = NodePanel(name=node_name, focus=focus, parent=self) if focus: node_panel.SetBackgroundColour((0xfe, 0xd3, 0x63)) node_panel.SetForegroundColour("BLACK") else: node_panel.SetBackgroundColour("GREY") node_panel.SetForegroundColour((250, 255, 255)) if self.devices_status[device_name]: node_panel.Show() self.sizer.Add(node_panel, flag=wx.EXPAND | wx.ALL, border=0) else: node_panel.Hide() # self.node_panel.SetBackgroundColour((80, 80, 80)) # self.node_panel.SetForegroundColour((255, 255, 0)) self.nodes_panel[node_name] = node_panel # print(self.nodes_panel) # print(self.devices_panel) self.SetSizer(self.sizer) self.sizer.Layout() # self.GetParent().Show() self.GetParent().sizer.Layout() self.Bind(EVT_NODE, self.OnNodeShow) self.Bind(EVT_DEVICE, self.OnDeviceShow) pass def GetDeviceFromNode(self, node): for device_name, nodes_name in self.devices_info.items(): for node_name in nodes_name: if node == node_name: return device_name pass def OnNodeShow(self, evt): """ 切换设备信息区域的Node :param evt: :return: """ self.__logger.info("Switch Node = {} --> {}".format( self.focus_node, evt.name)) if self.focus_node != evt.name: # 取消原来聚焦的device focus_device = self.GetDeviceFromNode(self.focus_node) device_panel = self.devices_panel[focus_device] device_panel.SetBackgroundColour("GREY") device_panel.SetForegroundColour((250, 255, 255)) # 设置当前聚焦的device focus_device = self.GetDeviceFromNode(evt.name) device_panel = self.devices_panel[focus_device] # device_panel.SetBackgroundColour((0x27, 0xc1, 0xf8)) device_panel.SetBackgroundColour('DodgerBlue') device_panel.SetForegroundColour((250, 255, 255)) # 更新最新聚焦的device名 self.focus_device = focus_device # 取消原来聚焦的node node_panel = self.nodes_panel[self.focus_node] node_panel.SetBackgroundColour("GREY") node_panel.SetForegroundColour((250, 255, 255)) # 设置当前聚焦的node node_panel = self.nodes_panel[evt.name] node_panel.SetBackgroundColour((0xfe, 0xd3, 0x63)) node_panel.SetForegroundColour("BLACK") # 更新最新聚焦的node名 self.focus_node = evt.name pass def OnDeviceShow(self, evt): """ 切换设备信息区域的Device :param evt: :return: """ self.__logger.info("OnDeviceShow in DeviceInfoPanel {}".format( evt.name)) # print(evt.name) children = self.sizer.GetChildren() for child in children: widget = child.GetWindow() self.sizer.Hide(widget) self.sizer.Detach(widget) widget.Destroy() # self.GetParent().sizer.Layout() # self.GetParent().Fit() ''' # 设置 for node_name, node_panel in self.nodes_panel.items(): node_panel.Hide() node_panel.Destroy() for device_name, device_panel in self.devices_panel.items(): device_panel.Hide() device_panel.Destroy() ''' self.devices_panel = {} self.nodes_panel = {} self.devices_status[evt.name] = ( self.devices_status[evt.name] == False) print("devices_status = ", self.devices_status) self.sizer = wx.BoxSizer(wx.VERTICAL) for device_name, nodes_name in self.devices_info.items(): print("device name = ", device_name) if self.focus_device == device_name: focus = True else: focus = False print("status = ", self.devices_status[device_name]) device_panel = DevicePanel(name=device_name, focus=focus, status=self.devices_status[device_name], parent=self) if focus: # device_panel.SetBackgroundColour((0x27, 0xc1, 0xf8)) device_panel.SetBackgroundColour('DodgerBlue') device_panel.SetForegroundColour((250, 255, 255)) else: device_panel.SetBackgroundColour("GREY") device_panel.SetForegroundColour((250, 255, 255)) device_panel.Show() self.sizer.Add(device_panel, flag=wx.EXPAND | wx.ALL, border=1) self.devices_panel[device_name] = device_panel # if not self.devices_status[device_name]: # continue for node_name in nodes_name: # print("node name = ", node_name) if self.focus_node == node_name: focus = True else: focus = False node_panel = NodePanel(name=node_name, focus=focus, parent=self) if focus: node_panel.SetBackgroundColour((0xfe, 0xd3, 0x63)) node_panel.SetForegroundColour("BLACK") else: node_panel.SetBackgroundColour("GREY") node_panel.SetForegroundColour((250, 255, 255)) if self.devices_status[device_name]: node_panel.Show() self.sizer.Add(node_panel, flag=wx.EXPAND | wx.ALL, border=0) else: node_panel.Hide() # self.node_panel.SetBackgroundColour((80, 80, 80)) # self.node_panel.SetForegroundColour((255, 255, 0)) self.nodes_panel[node_name] = node_panel self.SetSizerAndFit(self.sizer) # self.sizer.Layout() self.Hide() self.Show() # self.GetParent().Show() self.GetParent().sizer.Layout() self.GetParent().Fit()
def __init__(self, devices={}, focus_device='', focus_node='', *args, **kwargs): super(DeviceInfoPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.devices_info = devices self.focus_device = focus_device self.focus_node = focus_node self.devices_panel = {} self.devices_status = {} # 描述每个Device信息的打开关闭状态 self.nodes_panel = {} # 创建垂直方向网格 wx.BoxSizer, self.sizer = wx.BoxSizer(wx.VERTICAL) for device_name, nodes_name in devices.items(): self.devices_status[device_name] = True # 默认Device信息都是打开状态 # print("device name = ", device_name) if focus_device == device_name: focus = True else: focus = False device_panel = DevicePanel(name=device_name, focus=focus, status=self.devices_status[device_name], parent=self) if focus: device_panel.SetBackgroundColour('DodgerBlue') # device_panel.SetBackgroundColour((0x27, 0xc1, 0xf8)) device_panel.SetForegroundColour((250, 255, 255)) else: device_panel.SetBackgroundColour("GREY") device_panel.SetForegroundColour((250, 255, 255)) self.sizer.Add(device_panel, flag=wx.EXPAND | wx.TOP, border=1) self.devices_panel[device_name] = device_panel for node_name in nodes_name: # print("node name = ", node_name) if focus_node == node_name: focus = True else: focus = False node_panel = NodePanel(name=node_name, focus=focus, parent=self) if focus: node_panel.SetBackgroundColour((0xfe, 0xd3, 0x63)) node_panel.SetForegroundColour("BLACK") else: node_panel.SetBackgroundColour("GREY") node_panel.SetForegroundColour((250, 255, 255)) if self.devices_status[device_name]: node_panel.Show() self.sizer.Add(node_panel, flag=wx.EXPAND | wx.ALL, border=0) else: node_panel.Hide() # self.node_panel.SetBackgroundColour((80, 80, 80)) # self.node_panel.SetForegroundColour((255, 255, 0)) self.nodes_panel[node_name] = node_panel # print(self.nodes_panel) # print(self.devices_panel) self.SetSizer(self.sizer) self.sizer.Layout() # self.GetParent().Show() self.GetParent().sizer.Layout() self.Bind(EVT_NODE, self.OnNodeShow) self.Bind(EVT_DEVICE, self.OnDeviceShow) pass
class ModuleProtocol: """ Module Server 的协议解析 """ def __init__(self, ip='127.0.0.1', serial_id=bytearray([0, 0, 0, 0, 0, 0])): """ 构造方法, 初始化变量 :param ip: 默认的客户端IP """ # self.__ip = ip self.__uuid = "" # 初始化日志类 self.__logger = SingleLogger() # 初始化设备日志 self.__device_logger = None # self.__device_logger = LogFile("12345678") # 初始化需要发布的消息 self.__pub_module_info_msg_name = "module_info_event" # module信息传输触发事件 self.__pub_system_info_msg_name = "system_info_event" # system信息传输触发事件 self.__pub_device_ready_msg_name = "device_node_ready" # 设备准备好触发事件 # print("pub module info : ", self.__pub_module_info_msg_name) # print("pub system info : ", self.__pub_system_info_msg_name) # print("pub device ready : ", self.__pub_device_ready_msg_name) self.__system_info = { "version": {}, "temperature": {}, "memory": {}, "cpu": {}, "storage": {}, "socket": {}, 'uuid': {}, 'uptime': {} } self.vendor_id = const.GWM_VENDOR_ID # 默认厂商号 self.product_id = const.L2_DEVICE_ID self.serial_id = serial_id self._serial_number = 0 # 发送序列号,依次递增 pass @staticmethod def escape(data): """ 转义处理 :param data: 原始的bytearray :return: """ escape_bin = bytearray() # print(type(data)) for byte in data: # 将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列 if byte == 0x7d: escape_bin.append(0x7d) escape_bin.append(0x01) pass elif byte == 0x7e: escape_bin.append(0x7d) escape_bin.append(0x02) pass else: escape_bin.append(byte) pass return escape_bin @staticmethod def unescape(data): """ 反转义处理 :param data: :return: """ unescape_bin = bytearray() flag = False for byte in data: if flag: if byte == 0x01: unescape_bin.append(0x7d) else: unescape_bin.append(0x7e) flag = False elif byte == 0x7d: flag = True else: unescape_bin.append(byte) return unescape_bin @staticmethod def build_inquiry_body(): """ 构建查询指令 :return: """ cmd = {"system": ["version", "temperature", "cpu", "memory"]} # print(cmd) jsoninfo = json.dumps(cmd) # print(type(jsoninfo)) # print(jsoninfo) body = jsoninfo.encode("utf-8") # print(type(body)) # print_hex(body) return body @staticmethod def build_rtc_sync_body(): """ 构建时钟同步消息体 :return: """ now = datetime.datetime.now() cmd = { 'Setting': { "MOD_RTC": { "year": now.year, "month": now.month, "day": now.day, "hour": now.hour, "min": now.minute, "sec": now.second } } } jsoninfo = json.dumps(cmd) # print(type(jsoninfo)) # print(jsoninfo) body = jsoninfo.encode("utf-8") # print(type(body)) # print_bytes(body) return body @staticmethod def build_adc_setting_body(): now = datetime.datetime.now() cmd = { "Setting": { "MOD_RTC": { "year": now.year, "month": now.month, "day": now.day, "hour": now.hour, "min": now.hour, "sec": now.second } } } jsoninfo = json.dumps(cmd) # print(type(jsoninfo)) # print(jsoninfo) body = jsoninfo.encode("utf-8") # print(type(body)) # print_hex(body) return body @staticmethod def build_emc_control_body(start): cmd = {"Setting": {"MOD_EMC": start}} jsoninfo = json.dumps(cmd) # 将python数据结构转换为json格式字符 # print(type(jsoninfo)) # print(jsoninfo) body = jsoninfo.encode("utf-8") # print(type(body)) # print_hex(body) return body def build_header(self, msg_id, msg_len, vendor_id=const.GWM_VENDOR_ID, product_id=const.L2_DEVICE_ID, serial_id=[0x00, 0x00, 0x00, 0x00, 0x00, 0x00]): """ 构建header的bin数据 :param msg_id: :param msg_len: :param vendor_id: :param product_id: :param serial_id: :return: """ header = struct.pack('<HHBBBBBBBBI', msg_id, msg_len, self.vendor_id, self.product_id, self.serial_id[0], self.serial_id[1], self.serial_id[2], self.serial_id[3], self.serial_id[4], self.serial_id[5], self._serial_number) # print_bytes(header) self._serial_number += 1 return header @staticmethod def build_crc(data): """ 计算crc的值 :param data: 需要计算crc的bytearray :return: byte类型的crc输出 """ # print_bytes(data) check = crc16(data) crc = struct.pack('<H', check) # print_bytes(crc) return crc def build_inquiry_bin(self): """ 构建查询命令的bin格式 :return: """ body = self.build_inquiry_body() header = self.build_header(0x8100, len(body), serial_id=self.serial_id) inquiry_bin = self.build_bin(header + body) return inquiry_bin def build_rtc_sync(self): """ 构建时钟同步消息的bin格式 :return: """ # print("build_rtc_sync++++++++") body = self.build_rtc_sync_body() # print("body = ", body) # header = self.build_header(0x8104, len(body), serial_id=self.serial_id) header = self.build_header(const.RTC_SYNC, len(body), serial_id=self.serial_id) # print("header = ", header) rtc_sync_bin = self.build_bin(header, body) # print("rtc_sync_bin = ", rtc_sync_bin) # print("build_rtc_sync----------") return rtc_sync_bin def build_emc_control(self, cmd): """ 构建emc启动停止命令的bin格式 :param cmd: 'start' or 'stop' :return: """ body = self.build_emc_control_body(cmd) # print("body = ", body) # header = self.build_header(0x8104, len(body), serial_id=self.serial_id) header = self.build_header(const.SETTING_DOWNLOAD, len(body), serial_id=self.serial_id) # print("header = ", header) emc_control_bin = self.build_bin(header, body) # print("emc_control_bin = ", emc_control_bin) return emc_control_bin def build_bin(self, header, body): # print("build_bin++++++++++") crc = self.build_crc(header + body) data = header + body + crc data = self.escape(data) magic_number = const.MAGIC_NUMBER.to_bytes(length=1, byteorder='big', signed=False) data = magic_number + data + magic_number # print("data = ", data) # print_bytes(header) # print_bytes(body) # print_bytes(crc) # print_bytes(data) # print("build_bin----------") return data @staticmethod def parse_header(header): """ 解析头数据 :param header: :return: """ tmp = header[:2] msg_id = int.from_bytes(tmp, byteorder='little', signed=False) tmp = header[2:4] msg_len = int.from_bytes(tmp, byteorder='little', signed=False) vendor_id = header[4] product_id = header[5] serial_id = header[6:12] tmp = header[13:] serial_number = int.from_bytes(tmp, byteorder='little', signed=False) return msg_id, msg_len, vendor_id, product_id, serial_id, serial_number @staticmethod def parse_body(body): # print(body) pass def parse_uuid(self): """ 返回当前设备的uuid :return: """ return self.__uuid def parse_body_heart_beat(self): # print("parse_body_heart_beat::++++++++++++++++++++") devices_info = DevicesInfo() if self.__uuid is "": self.__uuid = '%02X' % self.vendor_id self.__uuid += '%02X' % self.product_id self.__uuid += bytesToHexString(self.serial_id) # print("uuid = ", self.__uuid) devices_info.set_uuid(self.__ip, self.__uuid) # print(devices_info.devices_ready()) if self.__device_logger is None: log_dir = "log/" + self.__uuid # print("log dir = ", log_dir) self.__device_logger = db_file(log_dir) if devices_info.devices_ready(): # print(" send msg device_node_ready!!!") wx.CallAfter(pub.sendMessage, self.__pub_device_ready_msg_name) wx.CallAfter(pub.sendMessage, 'heart_beat_event', mode=True) # print("parse_body_heart_beat::--------------------") def parse_body_event(self, body): """ :param body: :return: """ # print("parse_body_event::++++++++++++++++++++") # print(body) # print_bytes(body) # body_json = json.dumps(body.decode("utf-8")) # print(type(body_json)) # print(body_json) # body_dic = json.loads(body_json) body_dic = json.loads(body.decode("utf-8")) # print(type(body_dic)) # print(body_dic["event"]) if isinstance(body_dic["event"], dict): # self.__logger.info("get a module event") if self.__device_logger is not None: # print(body_dic["event"]) self.__device_logger.save(body_dic["event"]) for k, v in body_dic["event"].items(): # print(k) # print(v) if k == "mod": name = v if k in ["warning", "error", "info"]: status = k log = v if k == "date": timestamp = v # print("name = ", name) # print("log = ", log) # print("status = ", status) # print("timestamp = ", timestamp) self.__logger.debug("name = %s" % name) self.__logger.debug("log = %s" % log) self.__logger.debug("status = %s" % status) self.__logger.debug("timestamp = %s" % timestamp) wx.CallAfter(pub.sendMessage, self.__pub_module_info_msg_name, uuid=self.__uuid, name=name, log=log, status=status, time=timestamp) elif isinstance(body_dic["event"], list): # self.__logger.info("get a module event list") names = [] states = [] logs = [] for event in body_dic["event"]: # print(body_dic["event"]) # print("event = ", event) if self.__device_logger is not None: self.__device_logger.save(event) # print(event["mod"]) for k, v in event.items(): # print("k =", k) # print("v =", v) if k == "mod": names.append(v) if k in ["warning", "error", "info"]: states.append(k) logs.append(v) if k == "date": timestamp = v # print("names = ", names) # print("logs = ", logs) # print("states = ", states) for i in range(len(names)): name = names[i] log = logs[i] state = states[i] # print("type name =", type(name)) # print("name = ", name) # print("log = ", log) # print("state = ", state) # self.__logger.info("name = {}".format(name)) # self.__logger.info("log = {}".format(log)) # self.__logger.info("state = {}".format(state)) wx.CallAfter(pub.sendMessage, self.__pub_module_info_msg_name, uuid=self.__uuid, name=name, log=log, status=state, time=timestamp) else: print("error event!!!") # print("parse_body_event::--------------------") def parse_body_system_info(self, body): body_dic = json.loads(body.decode("utf-8")) system_info = body_dic['system'] system_info['uuid'] = "" for char in bytesTobcd( self.vendor_id.to_bytes(1, byteorder='little', signed=False) + self.product_id.to_bytes(1, byteorder='little', signed=False) + self.serial_id): system_info['uuid'] += char system_info['ip'] = self.__ip self.__system_info.update(system_info) # print("system info = ", self.__system_info) wx.CallAfter(pub.sendMessage, self.__pub_system_info_msg_name, info=self.__system_info) devices_info = DevicesInfo() if devices_info.get_uuid_from_ip(self.__ip) is None: devices_info.set_uuid(self.__ip, system_info['uuid']) def parse_body_rtc_sync(self, body): print("body = ", body) @staticmethod def parse_crc(crc_bin): """ 将两字节的byte类型数据转化为int类型的crc :param crc_bin: byte类型的crc :return: int类型的crc """ crc = int.from_bytes(crc_bin, byteorder='little', signed=False) return crc def parse_uuid(self, data): """ 根据消息,解析出uuid :param data: :return: """ data = self.unescape(data[1:-1]) header_bin = data[:16] msg_id, msg_len, vendor_id, product_id, serial_id, serial_number = self.parse_header( header_bin) uuid = '%02X' % vendor_id uuid += '%02X' % product_id uuid += bytesToHexString(serial_id) return uuid def parse_data(self, data): """ 解析一帧完整bin数据 :param data: :return: """ # self.__logger.info("parse_data++++++++++") # print(data) # print_hex(data) data = self.unescape(data[1:-1]) # print(data) # print_hex(data) header_bin = data[:16] # print_hex(header_bin) msg_id, msg_len, vendor_id, product_id, serial_id, serial_number = self.parse_header( header_bin) # print("msg_id = ", msg_id) # print("msg_len = ", msg_len) # print("vendor_id = ", hex(vendor_id)) # print("product_id = ", hex(product_id)) self.serial_id = serial_id if msg_len: body_bin = data[16:(16 + msg_len)] self.parse_body(body_bin) begin = 16 + msg_len # print("begin = ", begin) # print_hex(data) # print(len(data)) crc_bin = data[begin:] # print_hex(crc_bin) crc = self.parse_crc(crc_bin) # # print_hex(data[:-2]) check = crc16(data[:-2]) if check != crc: # print("body = ", body_bin) # print_hex(data) # print_hex(crc_bin) # print("check = 0x%x" % check) # print("crc = 0x%x" % crc) # print("crc error") return None else: # crc 校验正常 # print("crc ok") # uuid = bytesToHexString(self.serial_id) # log_dir = 'log/' + uuid # print("log dir = ", log_dir) # # self.__device_logger = db_file(log_dir) # device_config.new_device(uuid=uuid, ip=self.ip) if msg_id == const.HEART_BEAT_UPLOAD: # self.__logger.info("this is a head beat package") self.parse_body_heart_beat() return const.HEART_BEAT_UPLOAD elif msg_id == const.MODULE_EVENT_UPLOAD: # self.__logger.info("this is a module event package") self.parse_body_event(data[16:-2]) return const.MODULE_EVENT_UPLOAD elif msg_id == const.SYSTEM_INFO_UPLOAD: # self.__logger.info("this is a system info package") self.parse_body_system_info(data[16:-2]) return const.SYSTEM_INFO_UPLOAD elif msg_id == const.RTC_SYNC: self.parse_body_rtc_sync(data[16:-2]) return const.RTC_SYNC else: self.__logger.error("invalid package") self.__logger.error("msg_id = {}".format(msg_id)) return None """ if self.__device_logger is None: log_dir = bytesToHexString(self.serial_id) log_dir = 'log/' + log_dir print("log dir = ", log_dir) self.__device_logger = LogFile(log_dir) """ """ random_module = ['EMC_MODULE_ADC0', 'EMC_MODULE_ADC1', 'EMC_MODULE_ADC2', 'EMC_MODULE_ADC3', 'EMC_MODULE_ADC4', 'EMC_MODULE_ADC5', 'EMC_MODULE_ADC6', 'EMC_MODULE_ADC7'] random_state = ['info', 'warning', 'error'] name = choice(random_module) log = str(random()) state = choice(random_state) wx.CallAfter(pub.sendMessage, 'recv_module_event', name=name, log=log, status=state) """ # self.__logger.info("parse_data----------") pass
class ModuleList(wx.ListCtrl): def __init__(self, *args, **kwargs): super(ModuleList, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() # 创建数据库管理类 self.__sql = db_sql() # 当前Module Tab显示的列名 self.AddColumns() # 初始化私有变量 self._monitor_modules_list = { } # 对应每个设备(uuid), 记录这个设备的每个module的名字和位置的对应关系 # self._monitor_modules_log = {} # 对应每个设备(uuid), 记录这个设备的每个module的名字和日志的对应关系 # self._monitor_modules_max_state = {} # 对应每个设备(uuid), 记录这个设备的每个module的名字和状态的对应关系 # 默认的焦点设备,节点和设备的uuid devices_info = DevicesInfo() devices = devices_info.get_devices_name() self.__logger.debug("all devices list = {}".format(devices)) # self.__focus_device = list(devices.keys())[0] self.__focus_node = devices[self.__focus_device][0] self.__focus_uuid = devices_info.get_uuid()[0] # 初始化每个设备,必须监控的模块 for uuid in devices_info.get_uuid(): # 当前Module Tab监控的模块 self._monitor_modules_list[uuid] = { } # {name : index} --> 记录每个module的名字和位置的对应关系 # self._monitor_modules_max_state[uuid] = {} # {name : state} --> 记录每个module的名字和最差状态的对应关系 # self._monitor_modules_log[uuid] = {} # {name : log} --> 记录每个module的名字和日志的对应关系 # self.__focus_uuid = uuid # 显示当前节点必须监控的模块 for module in devices_info.get_module_monitor_name_from_uuid(uuid): item = (module, '') index = self.AddItem(item) self._monitor_modules_list[self.__focus_uuid][module] = {} self._monitor_modules_list[ self.__focus_uuid][module]["index"] = index self._monitor_modules_list[ self.__focus_uuid][module]["log"] = '' self._monitor_modules_list[ self.__focus_uuid][module]["state"] = "none" self.__sql.create_table(uuid=uuid, name=module) # 订阅消息 (module信息传输触发事件消息) self.__pub_module_info_msg_name = 'module_info_event' pub.subscribe(self.OnReceiveModuleEvent, self.__pub_module_info_msg_name) # 绑定公共事件处理 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemDoubleClicked) self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnItemRightClicked) # 绑定自定义事件处理 self.Bind(EVT_NODE, self.OnNodeShow) def OnItemSelected(self, event): pass # item = event.GetIndex() # self.Select(item, False) # wx.MessageBox("Single Cilcked", "Single cilck", wx.YES_NO) def OnItemDeselected(self, event): pass # event.Skip() # wx.MessageBox("Double Cilcked", "Double cilck", wx.YES_NO) def OnItemDoubleClicked(self, event): """ 双击Item的事件处理 :param event: :return: """ item_index = event.GetIndex() # 获取当前item第一列的文本内容 item_name = self.GetItem(item_index, 0) module_name = item_name.GetText() # 获取当前item第二列的文本内容 # item_log = self.GetItem(item_index, 1) # module_log = item_log.GetText() path = "log" + os.sep + self.__focus_uuid print("focus uuid = ", self.__focus_uuid) print("module_name = ", module_name) print("path = ", path) frm = LoggerFrame(module=module_name, path=path, mode='all', parent=None, style=wx.DEFAULT_FRAME_STYLE | wx.MAXIMIZE, title='Change wxTextCtrl colors example') frm.Show() pass def OnItemRightClicked(self, event): pass def AddColumns(self): """ 增加列格式,包含列标题 :return: None """ # width = self.GetSize().GetWidth() self.InsertColumn(0, 'Module', wx.LIST_FORMAT_CENTER, width=600) self.InsertColumn(1, 'Log', wx.LIST_FORMAT_CENTER, width=1000) def AddItem(self, item): """ 增加行记录 :param item: 一条行记录 (name, log) :return: None """ name = item[0] log = item[1] index = self.InsertItem(sys.maxsize, name) self.SetItem(index, 1, log) # print("uuid = ", self.__focus_uuid) # self._monitor_modules_list[self.__focus_uuid] = {} # self._monitor_modules_list[self.__focus_uuid][name] = {} # self._monitor_modules_list[self.__focus_uuid][name]["index"] = index # self._monitor_modules_list[self.__focus_uuid][name]["log"] = log # self._monitor_modules_list[self.__focus_uuid][name]["state"] = "none" # self._monitor_modules_log[self.__focus_uuid][name] = log # if name not in self._monitor_modules_max_state[self.__focus_uuid].keys(): # self._monitor_modules_max_state[self.__focus_uuid][name] = 0 # 默认白色 # print("monitor modules list = ", self._monitor_modules_list) # print("monitor module max state = ", self._monitor_modules_max_state) # print("monitor module log = ", self._monitor_modules_log) return index def UpdateItemStatus(self, name, status): """ 更新每一行记录的状态 :param name: :param status: :return: """ if status == 'warning': self.UpdateItemBackground(name, 'yellow') elif status == 'error': self.UpdateItemBackground(name, 'red') elif status == 'info': self.UpdateItemBackground(name, 'green') def UpdateItemBackground(self, item_name, color): """ 更新每一行记录的背景色 :param item_name: :param color: :return: """ index = self._monitor_modules_list[ self.__focus_uuid][item_name]["index"] self.SetItemBackgroundColour(index, color) def OnSize(self, event): """ 包含多列的组件大小变化的事件触发的处理 :param event: 大小变化的事件 :return: None """ # print(type(event)) width = self.GetSize().GetWidth() self.SetColumnWidth(0, width * 0.3) self.SetColumnWidth(1, width * 0.7) event.Skip() pass def OnNodeShow(self, evt): """ 切换Node的事件触发 :param evt: :return: """ self.__logger.info("Switch Node = {} --> {}".format( self.__focus_node, evt.name)) # print("focus_uuid = ", self.__focus_uuid) # if self.__focus_node != evt.name: if self.DeleteAllItems() is not True: self.__logger.error("error in DeleteAllItems") else: self.__logger.debug("ok in DeleteAllItems") devices_info = DevicesInfo() # print(devices_info.get_uuid()) for uuid in devices_info.get_uuid(): if uuid[-4:] == evt.name[-4:]: # print("match evt.name and uuid", uuid[-4:], evt.name[-4:]) # print("modules list = ", self._monitor_modules[uuid]) # print("monitor_modules = ", self._monitor_modules) # print("monitor modules list = ", self._monitor_modules_list) self.__logger.debug("monitor modules list = {}".format( self._monitor_modules_list)) # print("monitor modules log = ", self._monitor_modules_log) # print("monitor modules max state = ", self._monitor_modules_max_state) self.__focus_node = evt.name self.__focus_uuid = uuid # 显示当前节点必须监控的模块 for name in self._monitor_modules_list[self.__focus_uuid]: log = self._monitor_modules_list[ self.__focus_uuid][name]["log"] item = (name, log) index = self.AddItem(item) # self._monitor_modules_list[self.__focus_uuid][name] = {} # self._monitor_modules_list[self.__focus_uuid][name]["index"] = index # self._monitor_modules_list[self.__focus_uuid][name]["log"] = log # self._monitor_modules_list[self.__focus_uuid][name]["state"] = "none" status = self._monitor_modules_list[ self.__focus_uuid][name]["state"] self.UpdateItemStatus(name, status) """ if state == 'warning': self.UpdateItemBackground(name, 'yellow') elif state == 'error': self.UpdateItemBackground(name, 'red') elif state == 'info': self.UpdateItemBackground(name, 'green') """ """ # 判断当前item最恶劣的状态 level = self._monitor_modules_max_state[self.__focus_uuid][name] if level == 2: self.UpdateItemBackground(name, 'yellow') elif level == 3: self.UpdateItemBackground(name, 'red') elif level == 1: self.UpdateItemBackground(name, 'green') """ """ def get_module_state_level(self, state): state_level = { 'info': 1, 'warning': 2, 'error': 3 } return state_level[state] """ def OnReceiveModuleEvent(self, uuid, name, log, status, time): """ 接收监控Module的信息,并刷新界面 :param uuid: :param name: :param log: :param status: :param time: :return: """ self.__logger.debug("uuid = {}".format(uuid)) self.__logger.debug("name = {}".format(name)) self.__logger.debug("log = %s" % log) self.__logger.debug("status = %s" % status) self.__logger.debug("timestamp = %s" % time) # print("self uuid = ", self.__focus_uuid) # print("uuid = ", uuid) # print("name = ", name) # print("log = ", log) # print("status = ", status) # print("time = ", time) if name not in self._monitor_modules_list[uuid].keys(): self.__sql.create_table(uuid=uuid, name=name) self.__sql.insert_record(uuid=uuid, name=name, log=log, state=status, date=time) if self.__focus_uuid != uuid: return if name in self._monitor_modules_list[uuid].keys(): index = self._monitor_modules_list[uuid][name]["index"] # print("++++++++++++++++++++++++++++++++") # print("index = ", index) # print("uuid = ", uuid) # print("name = ", name) # print("log = ", log) # print("status = ", status) # print("monitor modules list = ", self._monitor_modules_list) # print("---------------------------------") self.SetItem(index, 0, name) # 更新Module的名字 self.SetItem(index, 1, log) # 更新Module的日志 self._monitor_modules_list[uuid][name][ "log"] = log # 更新Module的日志信息 else: item = (name, log, status) index = self.AddItem(item) self._monitor_modules_list[self.__focus_uuid][name] = {} self._monitor_modules_list[ self.__focus_uuid][name]["index"] = index # 更新Module的索引信息 self._monitor_modules_list[ self.__focus_uuid][name]["log"] = log # 更新Module的日志信息 self._monitor_modules_list[ self.__focus_uuid][name]["state"] = status # 更新Module的状态信息 self.UpdateItemStatus(name, status) # print("monitor modules list = ", self._monitor_modules_list) """
def __init__(self, *args, **kwargs): super(ModuleList, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() # 创建数据库管理类 self.__sql = db_sql() # 当前Module Tab显示的列名 self.AddColumns() # 初始化私有变量 self._monitor_modules_list = { } # 对应每个设备(uuid), 记录这个设备的每个module的名字和位置的对应关系 # self._monitor_modules_log = {} # 对应每个设备(uuid), 记录这个设备的每个module的名字和日志的对应关系 # self._monitor_modules_max_state = {} # 对应每个设备(uuid), 记录这个设备的每个module的名字和状态的对应关系 # 默认的焦点设备,节点和设备的uuid devices_info = DevicesInfo() devices = devices_info.get_devices_name() self.__logger.debug("all devices list = {}".format(devices)) # self.__focus_device = list(devices.keys())[0] self.__focus_node = devices[self.__focus_device][0] self.__focus_uuid = devices_info.get_uuid()[0] # 初始化每个设备,必须监控的模块 for uuid in devices_info.get_uuid(): # 当前Module Tab监控的模块 self._monitor_modules_list[uuid] = { } # {name : index} --> 记录每个module的名字和位置的对应关系 # self._monitor_modules_max_state[uuid] = {} # {name : state} --> 记录每个module的名字和最差状态的对应关系 # self._monitor_modules_log[uuid] = {} # {name : log} --> 记录每个module的名字和日志的对应关系 # self.__focus_uuid = uuid # 显示当前节点必须监控的模块 for module in devices_info.get_module_monitor_name_from_uuid(uuid): item = (module, '') index = self.AddItem(item) self._monitor_modules_list[self.__focus_uuid][module] = {} self._monitor_modules_list[ self.__focus_uuid][module]["index"] = index self._monitor_modules_list[ self.__focus_uuid][module]["log"] = '' self._monitor_modules_list[ self.__focus_uuid][module]["state"] = "none" self.__sql.create_table(uuid=uuid, name=module) # 订阅消息 (module信息传输触发事件消息) self.__pub_module_info_msg_name = 'module_info_event' pub.subscribe(self.OnReceiveModuleEvent, self.__pub_module_info_msg_name) # 绑定公共事件处理 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemDoubleClicked) self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnItemRightClicked) # 绑定自定义事件处理 self.Bind(EVT_NODE, self.OnNodeShow)
class ChartPanel(wx.Panel): """ 显示图表信息的面板 """ def __init__(self, focus_node, *args, **kwargs): super(ChartPanel, self).__init__(*args, **kwargs) # 初始化日志类 self.__logger = SingleLogger() self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.sizer) self.system_info_panel = SystemInfoPanel(self) self.system_info_panel.SetMinSize((1564, 188)) self.sizer.Add(self.system_info_panel, flag=wx.ALL, border=20) self.diagram_info_panel = DiagramInfoPanel(self) self.sizer.Add(self.diagram_info_panel, flag=wx.RIGHT | wx.LEFT, border=20) self.SetBackgroundColour((200, 200, 200)) self.system_info = {} self.focus_node = focus_node self.non_decimal = re.compile(r'[^\d.]+') # 订阅消息 pub.subscribe(self.OnSystemInfoEvent, 'system_info_event') # device_params = DevicesInfo() # for uuid in device_params.get_uuid(): # pub.subscribe(self.OnSystemInfoEvent, uuid[-4:] + '_system_info_event') # print(uuid[-4:] + '_system_info_event') # 绑定 self.Bind(EVT_NODE, self.OnNodeShow) def OnNodeShow(self, evt): """ :param evt: :return: """ self.__logger.info("Switch Node = {} --> {}".format( self.focus_node, evt.name)) if self.focus_node != evt.name: self.focus_node = evt.name uuid = self.focus_node[-4:] # 计算cpu核数 cpu_core = len(self.system_info[uuid]["cpu"].keys()) self.__logger.debug("cpu core = {}".format(cpu_core)) # 计算内存占有率 total = int(self.system_info[uuid]['memory']['total'][:-1]) used = int(self.system_info[uuid]['memory']['used'][:-1]) memory_usage = (used * 100) // total self.__logger.debug("memory usage = {}".format(memory_usage)) # 计算网络速率 network_tx = float( self.non_decimal.sub('', self.system_info[uuid]["network"]["tx"])) if self.system_info[uuid]["network"]["tx"][-1] == 'M': network_tx * 1024 network_rx = float( self.non_decimal.sub('', self.system_info[uuid]["network"]["rx"])) if self.system_info[uuid]["network"]["rx"][-1] == 'M': network_rx * 1024 if (network_tx + network_rx) > 1024: network_total = "%.2fM" % ((network_tx + network_rx) / 1024) else: network_total = "%.2fK" % (network_tx + network_rx) #network_tx = float(self.system_info[uuid]["network"]["tx"]) #network_rx = float(self.system_info[uuid]["network"]["rx"]) # 刷新设备性能信息 evt = PerformanceInfoEvent( uptime=self.system_info[uuid]["uptime"], temperature=self.system_info[uuid]["temperature"], memory=memory_usage, network=network_total, cpu=cpu_core) wx.QueueEvent(self.system_info_panel.performance_info, evt) # 刷新设备节点信息 evt = NodeInfoEvent(hw=self.system_info[uuid]["version"]['hw'], sw=self.system_info[uuid]["version"]['sw'], ip=self.system_info[uuid]["ip"], uuid=self.system_info[uuid]["uuid"]) wx.QueueEvent(self.system_info_panel.node_info, evt) # 刷新设备CPU图表 if self.system_info[uuid]["cpu"]: # print("labels = ", self.system_info[uuid]["cpu"].keys()) # print("values = ", self.system_info[uuid]["cpu"].values()) evt = CpuInfoEvent(data=self.system_info[uuid]["cpu"].values(), labels=self.system_info[uuid]["cpu"].keys()) wx.QueueEvent(self.diagram_info_panel.cpu_info_panel, evt) # 刷新设备Memory图表 if self.system_info[uuid]["memory"]: sizes = [] memory_sizes = [] memory_labels = ['used', 'unused'] for size in self.system_info[uuid]['memory'].values(): sizes.append(int(size[:-1])) total = int(sizes[0]) used = int(sizes[1]) # print("total = ", total) # print("used = ", used) memory_usage = (used * 100) // total memory_sizes.append(memory_usage) memory_sizes.append(100 - memory_usage) evt = MemoryInfoEvent(sizes=memory_sizes, labels=memory_labels) wx.QueueEvent(self.diagram_info_panel.memory_info_panel, evt) # 刷新设备网络信息图表 if self.system_info[uuid]["network"]: evt = NetworkInfoEvent( tx=self.system_info[uuid]["network"]["tx"], rx=self.system_info[uuid]["network"]["rx"]) wx.QueueEvent(self.diagram_info_panel.network_panel, evt) pass def OnSystemInfoEvent(self, info): """ 接收监控System的信息,并刷新界面 :param info: :return: """ self.__logger.debug("sw version = %s" % info["version"]['sw']) self.__logger.debug("hw version = %s" % info["version"]['hw']) self.__logger.debug("temperature = %s" % info["temperature"]) self.__logger.debug("ip = %s" % info["ip"]) self.__logger.debug("uuid = %s" % info["uuid"]) self.__logger.debug("memory = %s" % info["memory"]) self.__logger.debug("cpu = %s" % info["cpu"]) self.__logger.debug("network = %s" % info["network"]) self.__logger.debug("uptime = %s" % info["uptime"]) """ print("system info : sw version = ", info["version"]['sw']) print("system info : hw version = ", info["version"]['hw']) print("system info : temperature = ", info["temperature"]) print("system info : ip = ", info["ip"]) print("system info : uuid = ", info["uuid"]) print("system info : memory = ", info["memory"]) print("system info : cpu = ", info["cpu"]) print("system info : network = ", info["network"]) print("system info : uptime = ", info["uptime"]) # print("system info : storage = ", info["storage"]) """ uuid = info["uuid"][-4:] self.__logger.debug("uuid = %s" % uuid) self.__logger.debug("focus uuid = %s" % self.focus_node[-4:]) self.system_info[uuid] = info # 每个设备根据UUID保存一份系统信息 if uuid != self.focus_node[-4:]: # 不是当前焦点的uuid,则不显示系统信息 # print("not focus node chart!") return # 计算CPU核数 cpu_core = len(info["cpu"].keys()) self.__logger.debug("cpu core = %d" % cpu_core) # 计算内存占有率 total = int(int(info["memory"]["total"][:-1])) used = int(int(info["memory"]["used"][:-1])) memory_usage = (used * 100) // total self.__logger.debug("memory usage = %d" % memory_usage) network_tx = float( self.non_decimal.sub('', self.system_info[uuid]["network"]["tx"])) if self.system_info[uuid]["network"]["tx"][-1] == 'M': network_tx * 1024 network_rx = float( self.non_decimal.sub('', self.system_info[uuid]["network"]["rx"])) if self.system_info[uuid]["network"]["rx"][-1] == 'M': network_rx * 1024 if (network_tx + network_rx) > 1024: network_total = "%.2fM" % ((network_tx + network_rx) / 1024) else: network_total = "%.2fK" % (network_tx + network_rx) # 刷新某个设备节点的性能信息 evt = PerformanceInfoEvent(uptime=info["uptime"], temperature=info["temperature"], memory=memory_usage, network=network_total, cpu=cpu_core) wx.QueueEvent(self.system_info_panel.performance_info, evt) # 刷新某个设备节点的设备信息 evt = NodeInfoEvent(hw=info["version"]['hw'], sw=info["version"]['sw'], ip=info["ip"], uuid=info["uuid"]) wx.QueueEvent(self.system_info_panel.node_info, evt) # 刷新设备CPU图表 if info["cpu"]: # print("labels = ", info["cpu"].keys()) # print("values = ", info["cpu"].values()) evt = CpuInfoEvent(data=info["cpu"].values(), labels=info["cpu"].keys()) wx.QueueEvent(self.diagram_info_panel.cpu_info_panel, evt) # 刷新设备Memory图表 if info["memory"]: sizes = [] memory_sizes = [] memory_labels = ['used', 'unused'] for size in info['memory'].values(): sizes.append(int(size[:-1])) total = int(sizes[0]) used = int(sizes[1]) memory_usage = (used * 100) // total memory_sizes.append(memory_usage) memory_sizes.append(100 - memory_usage) evt = MemoryInfoEvent(sizes=memory_sizes, labels=memory_labels) wx.QueueEvent(self.diagram_info_panel.memory_info_panel, evt) # 刷新设备网络信息图表 if info["network"]: evt = NetworkInfoEvent(tx=info["network"]["tx"], rx=info["network"]["rx"]) wx.QueueEvent(self.diagram_info_panel.network_panel, evt)
class ModuleServerThread(threading.Thread): """ Module Server 独立线程 """ def __init__(self, name, data, event): super().__init__(name=name) # 调用父类(超类)的__init__()方法 # 初始化日志类 self.__logger = SingleLogger() # 外部通讯参数 self.__queue = data # 用于向外部传输队列数 self.__event = event # 用于触发外部事件 # 控制线程参数初始化 self.__flag = threading.Event() # 用于暂停线程的标识 self.__flag.clear() # 设置为False self.__running = threading.Event() # 用于停止线程的标识 self.__running.set() # 将running设置为True # 获取Module Server的IP和Port system_config = system_params() self.__ip, self.__port = system_config.get_module_server_info() self.__logger.debug("ip = %s" % self.__ip) self.__logger.debug("port = %s" % self.__port) def __del__(self): self.__logger.info("__del__") def pause(self): self.__logger.info("pause module server thread!") self.__flag.clear() # 设置为False, 让线程阻塞 def resume(self): self.__logger.info("resume module server thread!") self.__flag.set() # 设置为True, 让线程停止阻塞, 继续运行 def stop(self): self.__logger.info("stop module server thread!") self.__flag.set() # 将线程从暂停状态恢复, 如何已经暂停的话 self.__running.clear() # 设置为False def run(self): # 启动Module Server server = ModuleTCPServer((self.__ip, self.__port), ModuleServerHandler) server_thread = threading.Thread(target=server.serve_forever, name='ModuleServer', daemon=True) server_thread.start() while self.__running.isSet(): self.__flag.wait() # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回 server.shutdown() server.server_close()
class CANServerThread(threading.Thread): """ CAN 服务器 1. Echo功能 2. 发送休眠唤醒 3. 根据配置,发送数据 """ def __init__(self, name, data, event): super().__init__(name=name) # 调用父类(超类)的__init__()方法 # 初始化日志类 self.__logger = SingleLogger() # 外部通讯参数 self.__queue = data # 用于向外部传输队列数 self.__event = event # 用于触发外部事件 # 控制线程参数初始化 self.__flag = threading.Event() # 用于暂停线程的标识 self.__flag.set() # 设置为True,默认线程运行 self.__running = threading.Event() # 用于停止线程的标识 self.__running.set() # 将running设置为True # 获取系统参数 self.__system_config = system_params() # CAN分析仪的初始化 vid, pid = self.__system_config.get_can_analyzer_info() self.__canfd = CanAnalyze_ZLG(vid, pid) self.__canfd.StartAll() # 协议初始化 self.protocol = ModuleProtocol() # 获取CAN服务器的运行方式 self.__policy = self.__system_config.get_can_protocol() self.__logger.debug("can protocol = %s" % self.__policy) # 服务器不同的协议处理方式 self.__canfd_protocol_treat = { "echo": self.echo, "monitor": self.monitor, "uds": self.uds } # 每个CAN通道的变量 self.msg = dict() # 每个CAN通道的数据bytearray self.start_flag = dict() # 每个CAN通道的数据魔术字状态 # CAN Tree self.__can_node_info = self.__system_config.get_can_all_module_info() # CAN服务器的状态机 ('idle', 'echo', 'monitor', 'uds') self.state = 'idle' def __del__(self): self.__logger("__del__") def pause(self): self.__logger("pause CAN server thread!") self.__flag.clear() # 设置为False, 让线程阻塞 def resume(self): self.__logger("resume CAN server thread!") self.__flag.set() # 设置为True, 让线程停止阻塞 def stop(self): self.__logger("stop CAN server thread!") self.__flag.set() # 将线程从暂停状态恢复, 如何已经暂停的话 self.__running.clear() # 设置为False def run(self): while self.__running.isSet(): self.__flag.wait() # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回 # 根据不同的配置,CAN Server不同的协议处理方式 (默认echo模式) self.__canfd_protocol_treat.get(self.__policy, self.echo)() # id, msg = self.canfd.Receive(index=0, channel=0, mode='CANFD') # can_tx_id = system_config.get_can_tx_id(id) # self.canfd.Send(index=0, channel=0, can_id=can_tx_id, mode='CANFD') # print(type(id)) # print(id) # print(type(msg)) # print(msg) # print_hex(msg) # if self.verify_crc(msg): # log = "OK" # status = "info" # print("crc ok!") # else: # log = "CRC Failed" # status = "error" # print("crc failed!") # name = "MODULE_CAN{}_TX".format(id) # device_config.get_ip_from_uuid("abcdefgh") # wx.CallAfter(pub.sendMessage, self.__pub_message_name, name=name, log=log, status=status) # self.__exit.wait(0.01) # 等待退出事件, 0.01s超时退出 # if self.__exit.isSet(): # self.__exit.clear() # self.__found.clear() # self.__found_label.clear() # self.pause() # 暂停线程 #else: # break def verify(self): print("pause CAN server thread!") def verify_crc(self, data): print(data) res = crc8(data) if res == 0: return True else: return False def parse_uuid(self, msg): """ 根据CAN报文,获取当前消息的uuid :param msg: :param can_tx_id: :param can_rx_id: :return: """ uuid = None if int(msg[0]) == const.MAGIC_NUMBER: token = const.MAGIC_NUMBER.to_bytes(length=1, byteorder='big', signed=False) pos = msg.find(token, 1) print("pos = ", pos) print("data = ", msg[:pos + 1]) uuid = self.protocol.parse_uuid(msg[:pos + 1]) print("uuid = ", uuid) return uuid def echo(self): """ 应答处理 :return: """ for sn in self.__canfd.GetSN(): # 获取所有的CAN分析仪设备SN号 # print("sn = ", sn) index = self.__canfd.GetDevIDFromSN(sn) # 获取所有的CAN分析仪设备的索引号 for channel in self.__canfd.GetChannelFromSN(sn): # 获取所有的CAN分析仪设备 can_rx_id, msg = self.__canfd.Receive(index=index, channel=channel, mode='CANFD', timeout=0) if can_rx_id == 0x00: continue print("index = ", index) print("channel = ", channel) can_tx_id = self.__system_config.get_can_tx_id(id) print("can rx id = ", hex(can_rx_id)) print("can tx id = ", hex(can_tx_id)) print_bytes(msg) self.__canfd.Send(index=index, channel=channel, can_id=can_tx_id, mode='CANFD', data=msg) uuid = self.parse_uuid(msg) if uuid is not None: for name in self.__can_node_info.keys(): if self.__can_node_info[name]['tx_id'] == can_tx_id: if self.__can_node_info[name].get('uuid', True): print("name = ", name) print(self.__can_node_info) self.__can_node_info[name]['uuid'] = uuid self.__can_node_info[name]['index'] = index self.__can_node_info[name]['channel'] = channel print("can node info++++++++++++++++++++") print(self.__can_node_info) print("can node info--------------------") def monitor(self): """ :return: """ pass """ print("monitor::++++++++++") monitor_can_id = system_config.get_can_monitor_id() while True: for sn in self.canfd.GetSN(): # 获取所有的CAN分析仪设备SN号 # print("sn = ", sn) index = self.canfd.GetDevIDFromSN(sn) # 获取所有的CAN分析仪设备的索引号 for channel in self.canfd.GetChannelFromSN(sn): # 获取所有的CAN分析仪设备 # print("index = ", index) # print("channel = ", channel) id, datas = self.canfd.Receive(index=index, channel=channel, mode='CANFD', timeout=1) if id == 0x00: continue if id != monitor_can_id: print("id = ", hex(id)) print_bytes(datas) can_tx_id = system_config.get_can_tx_id(id) print("can rx id = ", hex(id)) print("can tx id = ", hex(can_tx_id)) print_bytes(datas) self.canfd.Send(index=index, channel=channel, can_id=can_tx_id, mode='CANFD', data=datas) continue else: # print("id = ", id) # print("datas = ", datas) if id not in self.msg.keys(): self.msg[id] = b'' wx.CallAfter(pub.sendMessage, 'socket_setup_event', ip=str(id)) if id not in self.start_flag.keys(): self.start_flag[id] = False for data in datas: # print("msg[id] = ", self.msg[id]) print("start_flag[id] = ", self.start_flag[id]) if int(data) == 126: # 将int(0~255)的值 转化为单字节的bytes类型 self.msg[id] += data.to_bytes(length=1, byteorder='big', signed=False) if self.start_flag[id]: print("msg[id] = ", self.msg[id]) print("len msg[id]", len(self.msg[id])) print_bytes(self.msg[id]) self.protocol.parse_data(self.msg[id]) print("\r\n") self.start_flag[id] = False self.msg[id] = b'' break else: self.start_flag[id] = True print("find magic char") # print("type data = ", type(data)) # print("data = ", data) # print("type datas = ", type(datas)) # print("datas = ", datas) # print_hex(datas) # print("id = ", id) elif self.start_flag[id]: #print("len msg[id] ", len(self.msg[id])) #print("len data", len(data)) #print_hex(self.msg[id]) # 将int(0~255)的值 转化为单字节的bytes类型 self.msg[id] += data.to_bytes(length=1, byteorder='big', signed=False) #print("data = ", data) #print("len2 msg[id] ", len(self.msg[id])) #print_hex(self.msg[id]) else: continue print("monitor::----------") pass """ def uds(self): pass def send(self, index, channel, data): """ 跨物理帧的CAN数据传输 :param index: :param channel: :param data: :return: """ head = 0 end = head + 64 while head < len(data): msg = data[head:end] self.canfd.Send(index=index, channel=channel, mode='CANFD', data=msg) head = end end = end + 64