Пример #1
0
        screen_height = self.parent.winfo_screenheight()
        splash_canvas = tk.Canvas(self.parent,
                                  width=screen_width,
                                  height=screen_height)
        splash_canvas.pack()
        self.tkimage = ImageTk.PhotoImage(self.image1)
        splash_canvas.create_image(0, 0, image=self.tkimage, anchor="nw")
        splash_canvas.create_text(200,
                                  34,
                                  text="[LOADING]...PLEASE WAIT",
                                  font=("small fonts", 20),
                                  fill="white")
        progressbar = ttk.Progressbar(orient=tk.HORIZONTAL,
                                      length=900,
                                      mode='determinate',
                                      style="Horizontal.TProgressbar")
        progressbar.place(x=450, y=25)
        progressbar.start()
        if self.nxt_func != None:
            self.parent.after(5050, self.proceed)


if __name__ == '__main__':
    root = ThemedTk("black")
    root["bg"] = "gray21"
    style = ttk.Style()
    style.configure("Horizontal.TProgressbar", foreground='gray21')
    app = SplashScreen(root, None)
    app.display()
    root.after(5050, root.destroy)
    root.mainloop()
Пример #2
0
class Toplevel1(object):
	def __init__(self):
		'''This class configures and populates the toplevel window.
		   top is the toplevel containing window.'''
		self.root = ThemedTk(theme="arc")
		self.style = ttk.Style()
		# self.root = tk.Tk()
		self.root.geometry("1200x661+284+114")
		# self.root.minsize(120, 1)
		# self.root.maxsize(1924, 1061)
		self.root.resizable(1, 1)
		self.root.title("New Toplevel")
		
		self.img = Image.open(r"G:\MoveOn\Gispot\GUIs\Icons\folder1.png")
		self.image_1 = ImageTk.PhotoImage(self.img)
		
		# top.configure(background="#d9d9d9")
		#
		# self.menubar = tk.Menu(top,font="TkMenuFont",bg=_bgcolor,fg=_fgcolor)
		# top.configure(menu = self.menubar)
		
		# self.style.configure('TNotebook.Tab', background=_bgcolor)
		# self.style.configure('TNotebook.Tab', foreground=_fgcolor)
		# self.style.map('TNotebook.Tab', background=
		#     [('selected', _compcolor), ('active',_ana2color)])
		self.TNotebook1 = ttk.Notebook(self.root)
		self.TNotebook1.place(relx=0.0, rely=0.0, relheight=1.0,
							  relwidth=1.0)
		self.TNotebook1.configure(takefocus="")
		self.TNotebook1_t1 = tk.Frame(self.TNotebook1)
		
		
		self.TNotebook1.add(self.TNotebook1_t1, padding=3)
		self.TNotebook1.tab(0, text="Page 1", compound="left",
							image = self.image_1)
		self.TNotebook1_t2 = tk.Frame(self.TNotebook1)
		self.TNotebook1.add(self.TNotebook1_t2, padding=3)
		self.TNotebook1.tab(1, text="Page 2", compound="left",
							underline="-1", )
		self.f = tk.Frame(self.TNotebook1_t1, width=20, height=100
						 )
		self.f.place(x=0, y=0)
		self.set_button()
		
		# self.f2 = tk.Frame(self.TNotebook1_t1, width=20, height=100, bg="blue")
		# self.f2.place(x=0, y=600,anchor="nw")
		# self.set_label()
	
	def set_button(self):
		button = ttk.Button(self.TNotebook1_t1,text = "bt",command = self.set_button_command)
		# lambda 形式也可以
		# button = ttk.Button(self.TNotebook1_t1,text = "bt",command = lambda:(self.root.after(2000, self.add_label)))
		button.pack()
	
	def add_label(self):
		lb = ttk.Button(self.f, text=1)
		lb.pack()
		# 加入该行可以循环添加
		self.set_button_command()
			
	def set_button_command(self):
			self.root.after(100, self.add_label)
Пример #3
0
)
autostart_box.grid(column=0, row=1)

chars = get_characters()
if selected_char.get() == "":
    selected_char.set(chars[0])
    set_conf()

character_dropdown = OptionMenu(frame,
                                selected_char,
                                selected_char.get(),
                                *chars,
                                command=set_conf)
character_dropdown.grid(column=1, row=0)

status_message = Message(frame, width=300)
status_message.grid(column=0, columnspan=2, row=2)

credit_button = Button(
    frame,
    text="Github Page",
    command=lambda: webbrowser.open(
        "https://github.com/ToasterUwU/EVE-Discord-Presence"),
)
credit_button.grid(column=0, columnspan=2, row=3)

frame.place(relx=0.5, rely=0.5, anchor="c")

tk.after(0, loop)
tk.mainloop()
class SSN_Server_UI():
    def __init__(self,
                 window_theme="aquativo",
                 window_title="Hello World!",
                 window_geometry="400x400+100+100"):
        self.root_window = ThemedTk()
        self.root_window.set_theme(theme_name=window_theme)
        self.root_window.title(window_title)
        self.root_window.geometry(window_geometry)
        self.window_width = self.root_window.winfo_screenwidth()
        self.window_height = self.root_window.winfo_screenheight()
        # essential communicators
        self.udp_comm = None
        self.mqtt_comm = None
        self.serial_comm = None
        self.use_udp = False
        self.use_mqtt = False
        self.csv_data_recording = None
        ############# if we have more than one node
        self.NodeCountInGUI = 0
        self.message_type_text = list()
        self.node_select_radio_button = SSN_Radio_Button_Common_Option_Widget(
            self.root_window)
        self.nodeid_text = list()
        self.temperature_text = list()
        self.humidity_text = list()
        self.nodeuptime_text = list()
        self.abnormalactivity_text = list()
        ######## Machine Incoming data to be displayed
        self.machine_loadcurrents, self.machine_percentageloads, self.machine_status = [
            [] for _ in range(4)
        ], [[] for _ in range(4)], [[] for _ in range(4)]
        self.machine_timeinstate, self.machine_sincewheninstate = [
            [] for _ in range(4)
        ], [[] for _ in range(4)]
        self.no_connection = 0
        pass

    def start(self):
        self.root_window.mainloop()
        # threading.Thread.__init__(self)
        # self.start()

    def setup_input_interface(self, current_sensor_ratings,
                              mac_addresses_filename, default_configs):
        # enter the SSN new MAC
        full_mac_list = get_MAC_addresses_from_file(mac_addresses_filename)
        self.ssn_mac_dropdown = SSN_DropDown_Widget(
            window=self.root_window,
            label_text="SSN MAC",
            label_pos=(0, vertical_spacing * 0 + 2),
            dropdown_list=full_mac_list,
            dropdown_pos=(horizontal_spacing - 10, vertical_spacing * 0 + 2),
            dropdown_block_width=17)
        ######## Machine Config Inputs
        self.machine_ratings, self.machine_maxloads, self.machine_thresholds = list(
        ), list(), list()
        for i in range(4):
            # generate machine label
            rating_label_text = "M{} Sensor Rating (A)".format(i + 1)
            maxload_label_text = "M{} Max Load (A)".format(i + 1)
            thres_label_text = "M{} Threshold (A)".format(i + 1)
            # enter machine sensor rating
            rating_dropdown = SSN_DropDown_Widget(
                window=self.root_window,
                label_text=rating_label_text,
                label_pos=(horizontal_spacing * 2 * i,
                           vertical_spacing * 1 + 5),
                dropdown_list=current_sensor_ratings,
                dropdown_pos=(horizontal_spacing * (2 * i + 1),
                              vertical_spacing * 1 + 5),
                dropdown_block_width=12,
                default_selected_item=default_configs[0 + 3 * i])
            # enter machine max load
            maxload_text_entry = SSN_Text_Entry_Widget(
                window=self.root_window,
                label_text=maxload_label_text,
                label_pos=(horizontal_spacing * 2 * i,
                           vertical_spacing * 2 + 5),
                text_entry_width=15,
                text_pos=(horizontal_spacing * (2 * i + 1),
                          vertical_spacing * 2 + 5),
                default_value=default_configs[1 + 3 * i])
            # enter machine threshold current
            thresh_text_entry = SSN_Text_Entry_Widget(
                window=self.root_window,
                label_text=thres_label_text,
                label_pos=(horizontal_spacing * 2 * i,
                           vertical_spacing * 3 + 5),
                text_entry_width=15,
                text_pos=(horizontal_spacing * (2 * i + 1),
                          vertical_spacing * 3 + 5),
                default_value=default_configs[2 + 3 * i])
            self.machine_ratings.append(rating_dropdown)
            self.machine_maxloads.append(maxload_text_entry)
            self.machine_thresholds.append(thresh_text_entry)
            pass
        # reporting interval text input
        self.reportinterval_text_entry = SSN_Text_Entry_Widget(
            window=self.root_window,
            label_text="Report Interval (sec)",
            label_pos=(horizontal_spacing * 2, vertical_spacing * 4 + 5),
            text_entry_width=15,
            text_pos=(horizontal_spacing * (2 + 1), vertical_spacing * 4 + 5),
            default_value=default_configs[12])
        pass

    def clear_status_panel(self):
        # clear node status
        for this_node in range(self.NodeCountInGUI):
            self.message_type_text[this_node].clear()
            self.nodeid_text[this_node].clear()
            # clear existing texts for node specific information
            self.temperature_text[this_node].clear()
            self.humidity_text[this_node].clear()
            self.nodeuptime_text[this_node].clear()
            self.abnormalactivity_text[this_node].clear()
            # clear existing texts for machine specific information
            for i in range(4):
                self.machine_loadcurrents[this_node][i].clear()
                self.machine_percentageloads[this_node][i].clear()
                self.machine_status[this_node][i].clear()
                self.machine_timeinstate[this_node][i].clear()
                self.machine_sincewheninstate[this_node][i].clear()
                pass
            pass
        pass

    def send_mac_btn_clicked(self):
        # clear node status panel
        self.clear_status_panel()
        if self.use_udp:
            # construct and send set_mac message
            try:
                self.udp_comm.send_set_mac_message(
                    node_index=self.node_select_radio_button.getSelectedNode()
                    - 1,
                    mac_address=self.ssn_mac_dropdown.get())
                print('\033[34m' + "Sent MAC to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except IndexError:
                print(
                    '\033[31m' +
                    "SSN Network Node Count: {}. Can't Send to SSN Indexed: {}"
                    .format(
                        self.udp_comm.getNodeCountinNetwork(),
                        self.node_select_radio_button.getSelectedNode() - 1))
                pass
        elif self.use_mqtt:
            # construct and send set_mac message
            try:
                self.mqtt_comm.send_set_mac_message(
                    mac_address=self.ssn_mac_dropdown.get())
                print('\033[34m' + "Sent MAC to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except error:
                print('\033[31m' + f"{error}")
                pass
            pass
        pass

    def send_config_btn_clicked(self):
        # clear node status panel
        self.clear_status_panel()
        # get the configs from the GUI
        self.configs = list()
        for i in range(4):
            this_sensor_rating = self.machine_ratings[i].get()
            this_sensor_rating = int(
                this_sensor_rating) if this_sensor_rating != 'NONE' else 0
            self.configs.append(this_sensor_rating)
            self.configs.append(
                int(10 * float(self.machine_thresholds[i].get())))
            self.configs.append(int(self.machine_maxloads[i].get()))
            pass
        self.configs.append(int(self.reportinterval_text_entry.get()))
        if self.use_udp:
            try:
                self.udp_comm.send_set_config_message(
                    node_index=self.node_select_radio_button.getSelectedNode()
                    - 1,
                    config=self.configs)
                print('\033[34m' + "Sent CONFIG to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except IndexError:
                print(
                    '\033[31m' +
                    "SSN Network Node Count: {}. Can't Send to SSN Indexed: {}"
                    .format(
                        self.udp_comm.getNodeCountinNetwork(),
                        self.node_select_radio_button.getSelectedNode() - 1))
            # change button color
            # self.config_button.config(bg='white')
        elif self.use_mqtt:
            # construct and send set_mac message
            try:
                self.mqtt_comm.send_set_config_message(config=self.configs)
                print('\033[34m' + "Sent CONFIG to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except error:
                print('\033[31m' + f"{error}")
                pass
            pass
        pass

    def send_timeofday_btn_clicked(self):
        if self.use_udp:
            try:
                # self.udp_comm.send_set_timeofday_message(node_index=self.node_select_radio_button.getSelectedNode() - 1, current_time=self.server_time_now)
                self.udp_comm.send_set_timeofday_Tick_message(
                    node_index=self.node_select_radio_button.getSelectedNode()
                    - 1,
                    current_tick=utils.get_bytes_from_int(
                        self.servertimeofday_Tick))
                print('\033[34m' + "Sent Time of Day to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except IndexError:
                print(
                    '\033[31m' +
                    "SSN Network Node Count: {}. Can't Send to SSN Indexed: {}"
                    .format(
                        self.udp_comm.getNodeCountinNetwork(),
                        self.node_select_radio_button.getSelectedNode() - 1))
        elif self.use_mqtt:
            # construct and send set_mac message
            try:
                self.mqtt_comm.send_set_timeofday_Tick_message(
                    current_tick=utils.get_bytes_from_int(
                        self.servertimeofday_Tick))
                print('\033[34m' + "Sent Time of Day to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except error:
                print('\033[31m' + f"{error}")
                pass
            pass
        pass

    def debug_reset_eeprom_btn_clicked(self):
        # clear node status panel
        self.clear_status_panel()
        if self.use_udp:
            # send message and clear the status texts
            try:
                self.udp_comm.send_debug_reset_eeprom_message(
                    node_index=self.node_select_radio_button.getSelectedNode()
                    - 1)
                print('\033[34m' + "Sent CLEAR EEPROM to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except IndexError:
                print(
                    '\033[31m' +
                    "SSN Network Node Count: {}. Can't Send to SSN Indexed: {}"
                    .format(
                        self.udp_comm.getNodeCountinNetwork(),
                        self.node_select_radio_button.getSelectedNode() - 1))
        elif self.use_mqtt:
            # construct and send set_mac message
            try:
                self.mqtt_comm.send_debug_reset_eeprom_message()
                print('\033[34m' + "Sent CLEAR EEPROM to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except error:
                print('\033[31m' + f"{error}")
                pass
            pass
        pass

    def debug_reset_ssn_btn_clicked(self):
        # clear node status panel
        self.clear_status_panel()
        if self.use_udp:
            # send message and clear statuss
            try:
                self.udp_comm.send_debug_reset_ssn_message(
                    node_index=self.node_select_radio_button.getSelectedNode()
                    - 1)
                print('\033[34m' + "Sent RESET to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except IndexError:
                print(
                    '\033[31m' +
                    "SSN Network Node Count: {}. Can't Send to SSN Indexed: {}"
                    .format(
                        self.udp_comm.getNodeCountinNetwork(),
                        self.node_select_radio_button.getSelectedNode() - 1))
        elif self.use_mqtt:
            # construct and send set_mac message
            try:
                self.mqtt_comm.send_debug_reset_ssn_message()
                print('\033[34m' + "Sent RESET to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            except error:
                print('\033[31m' + f"{error}")
                pass
            pass
        pass

    def setup_buttons(self):
        # update mac button
        self.mac_button = SSN_Button_Widget(
            window=self.root_window,
            button_text="Send MAC Address",
            button_command=self.send_mac_btn_clicked,
            button_pos=(2 * horizontal_spacing, vertical_spacing * 0 + 0))
        # send sensor configuration button
        self.config_button = SSN_Button_Widget(
            window=self.root_window,
            button_text="Send Configuration",
            button_command=self.send_config_btn_clicked,
            button_pos=(horizontal_spacing * 4, vertical_spacing * 4 + 5))
        # send time of day button; we will also give a display of current time of day with this
        self.servertimeofday_text = SSN_Text_Display_Widget(
            window=self.root_window,
            label_text="Server Time of Day",
            label_pos=(3 * horizontal_spacing + 52, vertical_spacing * 7),
            text_size=(150, vertical_spacing),
            text_pos=(3 * horizontal_spacing + 30, vertical_spacing * 8))
        self.servertimeofday_button = SSN_Button_Widget(
            window=self.root_window,
            button_text="Send Time of Day",
            button_command=self.send_timeofday_btn_clicked,
            button_pos=(3 * horizontal_spacing + 54, vertical_spacing * 9 + 5))
        self.debug_reset_eeprom_button = SSN_Button_Widget(
            window=self.root_window,
            button_text="(DEBUG) CLEAR EEPROM",
            button_command=self.debug_reset_eeprom_btn_clicked,
            button_pos=(5 * horizontal_spacing + 50,
                        vertical_spacing * 8 - 10))
        self.debug_reset_ssn_button = SSN_Button_Widget(
            window=self.root_window,
            button_text="(DEBUG) RESET SSN",
            button_command=self.debug_reset_ssn_btn_clicked,
            button_pos=(5 * horizontal_spacing + 64, vertical_spacing * 9 + 5))
        self.clear_status_panel_button = SSN_Button_Widget(
            window=self.root_window,
            button_text="Clear Status Panel",
            button_command=self.clear_status_panel,
            button_pos=(5 * horizontal_spacing + 69,
                        vertical_spacing * 10 + 22))
        pass

    def GUI_Block(self):
        return (self.NodeCountInGUI - 1) * vertical_spacing * 14 + 40

    def setup_incoming_data_interface(self, NumOfNodes):
        for k in range(NumOfNodes):
            self.NodeCountInGUI += 1
            # received message/status to be displayed
            self.message_type_text.append(
                SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text="Incoming Message Type",
                    label_pos=(0, self.GUI_Block() + vertical_spacing * 6),
                    text_size=(110, vertical_spacing),
                    text_pos=(horizontal_spacing + 20,
                              self.GUI_Block() + vertical_spacing * 6)))
            # add a radio-button to chose this one when we have to send the message
            self.node_select_radio_button.add_radio(
                radio_text="SSN-{}".format(self.NodeCountInGUI),
                radio_value=self.NodeCountInGUI,
                radio_pos=(2 * horizontal_spacing + 20,
                           self.GUI_Block() + vertical_spacing * 6))
            # SSN Node ID to be displayed
            self.nodeid_text.append(
                SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text="Node ID",
                    label_pos=(0, self.GUI_Block() + vertical_spacing * 7),
                    text_size=(110, vertical_spacing),
                    text_pos=(horizontal_spacing + 20,
                              self.GUI_Block() + vertical_spacing * 7)))
            # temperature to be displayed
            self.temperature_text.append(
                SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text="Temperature ({}C)".format(chr(176)),
                    label_pos=(0, self.GUI_Block() + vertical_spacing * 8),
                    text_size=(110, vertical_spacing),
                    text_pos=(horizontal_spacing + 20,
                              self.GUI_Block() + vertical_spacing * 8)))
            # humidity to be displayed
            self.humidity_text.append(
                SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text="Relative Humidity (%)",
                    label_pos=(0, self.GUI_Block() + vertical_spacing * 9),
                    text_size=(110, vertical_spacing),
                    text_pos=(horizontal_spacing + 20,
                              self.GUI_Block() + vertical_spacing * 9)))
            # node uptime to be displayed
            self.nodeuptime_text.append(
                SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text="Node Up Time in (sec)",
                    label_pos=(0, self.GUI_Block() + vertical_spacing * 10),
                    text_size=(110, vertical_spacing),
                    text_pos=(horizontal_spacing + 20,
                              self.GUI_Block() + vertical_spacing * 10)))
            # abnormal activity to be displayed
            self.abnormalactivity_text.append(
                SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text="Abnormal Activity",
                    label_pos=(0, self.GUI_Block() + vertical_spacing * 11),
                    text_size=(110, vertical_spacing),
                    text_pos=(horizontal_spacing + 20,
                              self.GUI_Block() + vertical_spacing * 11),
                    color='green'))

            for i in range(4):
                # generate machine labels
                loadcurrent_label_text = "M{} Load Current (A)".format(i + 1)
                percentload_label_text = "M{} Percentage Load (%)".format(i +
                                                                          1)
                state_label_text = "M{} State (OFF/IDLE/ON)".format(i + 1)
                duration_label_text = "M{} Time In State (sec)".format(i + 1)
                timestamp_label_text = "M{} State Time Stamp".format(i + 1)
                # machine load current
                loadcurrent_text = SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text=loadcurrent_label_text,
                    label_pos=(horizontal_spacing * 2 * i,
                               self.GUI_Block() + vertical_spacing * 12 + 20),
                    text_size=(80, vertical_spacing),
                    text_pos=((2 * i + 1) * horizontal_spacing + 20,
                              self.GUI_Block() + vertical_spacing * 12 + 20))
                percentload_text_entry = SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text=percentload_label_text,
                    label_pos=(horizontal_spacing * 2 * i,
                               self.GUI_Block() + vertical_spacing * 13 + 20),
                    text_size=(80, vertical_spacing),
                    text_pos=(horizontal_spacing * (2 * i + 1) + 20,
                              self.GUI_Block() + vertical_spacing * 13 + 20))
                # machine state
                state_text_entry = SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text=state_label_text,
                    label_pos=(horizontal_spacing * 2 * i,
                               self.GUI_Block() + vertical_spacing * 14 + 20),
                    text_size=(80, vertical_spacing),
                    text_pos=(horizontal_spacing * (2 * i + 1) + 20,
                              self.GUI_Block() + vertical_spacing * 14 + 20))
                # machine state duration
                duration_text_entry = SSN_Text_Display_Widget(
                    window=self.root_window,
                    label_text=duration_label_text,
                    label_pos=(horizontal_spacing * 2 * i,
                               self.GUI_Block() + vertical_spacing * 15 + 20),
                    text_size=(80, vertical_spacing),
                    text_pos=(horizontal_spacing * (2 * i + 1) + 20,
                              self.GUI_Block() + vertical_spacing * 15 + 20))
                # machine state timestamp
                timestamp_dual_text_entry = SSN_Dual_Text_Display_Widget(
                    window=self.root_window,
                    label_text=timestamp_label_text,
                    label_pos=(horizontal_spacing * 2 * i,
                               self.GUI_Block() + vertical_spacing * 16 + 20),
                    text_size=(80, vertical_spacing),
                    text_pos1=(horizontal_spacing * (2 * i + 1) + 20,
                               self.GUI_Block() + vertical_spacing * 16 + 20),
                    text_pos2=(horizontal_spacing * (2 * i + 1) + 20,
                               self.GUI_Block() + vertical_spacing * 17 + 20))
                self.machine_loadcurrents[self.NodeCountInGUI -
                                          1].append(loadcurrent_text)
                self.machine_percentageloads[self.NodeCountInGUI -
                                             1].append(percentload_text_entry)
                self.machine_status[self.NodeCountInGUI -
                                    1].append(state_text_entry)
                self.machine_timeinstate[self.NodeCountInGUI -
                                         1].append(duration_text_entry)
                self.machine_sincewheninstate[self.NodeCountInGUI - 1].append(
                    timestamp_dual_text_entry)
                pass
            pass
        # set default node for sending messages
        self.node_select_radio_button.radio_buttons[0].invoke()
        pass

    def setup_serial_communication(self,
                                   serial_port='COM5',
                                   baudrate=19200,
                                   log_file='../serial_log-110920-130920.txt'):
        self.serial_comm = SERIAL_COMM(serial_port, baudrate, log_file)
        pass

    def setup_udp_communication(self, server_end):
        # essential UDP communicator
        self.udp_comm = UDP_COMM()
        connection_status = self.udp_comm.udp_setup_connection(
            server_address=server_end[0], server_port=server_end[1])
        if connection_status is None:
            print("Cannot Connect to Network!!!")
            return
        self.use_udp = True
        # invoke it just once
        self.read_messages_and_update_UI()
        pass

    def setup_mqtt_communication(self, client_id, host="192.168.0.120"):
        self.mqtt_comm = MQTT(client_id=client_id, host=host)
        self.mqtt_comm.client.loop_start()
        self.use_mqtt = True
        # invoke it just once
        self.read_messages_and_update_UI()
        pass

    def setup_csv_data_recording(self, csv_file):
        this_date = datetime.datetime.fromtimestamp(int(round(time.time())))
        file_name, extension = os.path.splitext(csv_file)
        self.csv_data_file = file_name
        self.csv_data_recording = True
        pass

    def read_messages_and_update_UI(self):
        # check serial comm for messages
        if self.serial_comm:
            self.serial_comm.log()
        self.servertimeofday_Tick = int(round(time.time()))
        self.servertimeofday_text.update(
            new_text_string=self.servertimeofday_Tick)
        # receive the incoming message
        if self.use_udp:
            node_index, message_id, params = self.udp_comm.read_udp_message()
            # check if a valid message was received or not
            if node_index == -1 and message_id == -1:
                self.no_connection += 1
                if self.no_connection > 10:
                    self.no_connection = 0
                    print('\033[30m' + "XXX Nothing Received XXX")
                # recall this method after another second
                self.root_window.after(200, self.read_messages_and_update_UI)
                return
        elif self.use_mqtt:
            if not self.mqtt_comm.message_queue.qsize():
                self.no_connection += 1
                if self.no_connection > 10:
                    self.no_connection = 0
                    print('\033[30m' + "XXX Nothing Received XXX")
                # recall this method after another second
                self.root_window.after(200, self.read_messages_and_update_UI)
                return
            node_index, message_id, params = self.mqtt_comm.message_queue.get()
        # proceed only if a genuine message is found
        self.no_connection = 0
        # message type and node id will always be displayed
        self.message_type_text[node_index].update(
            new_text_string=SSN_MessageID_to_Type[message_id],
            justification='left')
        self.nodeid_text[node_index].update(new_text_string=params[0])
        # basic get messages received?
        if message_id == SSN_MessageType_to_ID['GET_MAC']:
            print('\033[34m' +
                  "Received GET_MAC from SSN-{}".format(node_index + 1))
        elif message_id == SSN_MessageType_to_ID['GET_TIMEOFDAY']:
            print('\033[34m' +
                  "Received GET_TIMEOFDAY from SSN-{}".format(node_index + 1))
            # automate set time of day
            print('\033[34m' +
                  "Sending SET_TIMEOFDAY to SSN-{}".format(node_index + 1))
            if self.use_udp:
                self.udp_comm.send_set_timeofday_Tick_message(
                    node_index=self.node_select_radio_button.getSelectedNode()
                    - 1,
                    current_tick=utils.get_bytes_from_int(
                        self.servertimeofday_Tick))
                print('\033[34m' + "Sent Time of Day to SSN-{}".format(
                    self.node_select_radio_button.getSelectedNode()))
            elif self.use_mqtt:
                self.mqtt_comm.send_set_timeofday_Tick_message(
                    current_tick=utils.get_bytes_from_int(
                        self.servertimeofday_Tick))
        elif message_id == SSN_MessageType_to_ID['GET_CONFIG']:
            print('\033[34m' +
                  "Received GET_CONFIG from SSN-{}".format(node_index + 1))
        # configs have been acknowledged?
        elif message_id == SSN_MessageType_to_ID['ACK_CONFIG']:
            configs_acknowledged = params[1]  # it is a list
            if configs_acknowledged == self.configs:
                print('\033[34m' +
                      "Received CONFIG ACK from SSN-{}".format(node_index + 1))
                # self.config_button.config(bg='light green')
                pass
            pass
        # status update message brings the ssn heartbeat status
        elif message_id == SSN_MessageType_to_ID['STATUS_UPDATE']:
            print('\033[34m' +
                  "Received Status Update from SSN-{}".format(node_index + 1))
            self.temperature_text[node_index].update(new_text_string=params[1])
            self.humidity_text[node_index].update(new_text_string=params[2])
            self.nodeuptime_text[node_index].update(
                new_text_string=self.servertimeofday_Tick - params[3]
            )  # get the difference of static tick and current tick
            activity_level = SSN_ActivityLevelID_to_Type[params[4]]
            # get activity level of the SSN and display properly
            self.abnormalactivity_text[node_index].update(
                new_text_string=activity_level)
            if activity_level == 'NORMAL':
                self.abnormalactivity_text[node_index].change_text_color(
                    new_color='green')
            else:
                self.abnormalactivity_text[node_index].change_text_color(
                    new_color='red')
            fault_count = params[-1]
            if fault_count is not None:
                print('\033[34m' + "Fault Count from SSN-{}: {}".format(
                    node_index + 1, fault_count))
            machine_state_timestamps = []
            for i in range(4):
                self.machine_loadcurrents[node_index][i].update(
                    new_text_string=params[5 + i])
                self.machine_percentageloads[node_index][i].update(
                    new_text_string=params[9 + i])
                self.machine_status[node_index][i].update(
                    new_text_string=Machine_State_ID_to_State[params[13 + i]])
                state_timestamp_tick = params[17 + i]
                if state_timestamp_tick != 0:
                    # elapsed_time_in_state = self.servertimeofday_Tick - state_timestamp_tick
                    good_time = datetime.datetime.fromtimestamp(
                        state_timestamp_tick)
                    exact_time_strings = [
                        "{}:{}:{}".format(good_time.hour, good_time.minute,
                                          good_time.second),
                        "{}/{}/{}".format(good_time.day, good_time.month,
                                          good_time.year)
                    ]
                else:
                    # elapsed_time_in_state = state_timestamp_tick
                    exact_time_strings = ["0:0:0", "0/0/0"]
                machine_state_timestamps.append(exact_time_strings)
                self.machine_timeinstate[node_index][i].update(
                    new_text_string=params[21 + i])
                self.machine_sincewheninstate[node_index][i].update(
                    new_text_strings=machine_state_timestamps[i])
                pass
            # append this data to our CSV file
            if self.csv_data_recording:
                # insertiontimestamp, node_id, node_uptime, activitylevel,
                # temperature, humidity,
                # M1_load, M1_load%, M1_state, M1_statetimestamp, M1_stateduration,
                # M2_*...
                server_time_of_the_day = datetime.datetime.fromtimestamp(
                    self.servertimeofday_Tick)
                data_packet = [
                    server_time_of_the_day, params[0],
                    datetime.datetime.fromtimestamp(params[3]), activity_level,
                    params[1], params[2], params[5], params[9], params[13],
                    datetime.datetime.fromtimestamp(params[17]), params[21],
                    params[6], params[10], params[14],
                    datetime.datetime.fromtimestamp(params[18]), params[22],
                    fault_count
                ]
                with open(self.csv_data_file +
                          "-{}-{}-{}".format(server_time_of_the_day.day,
                                             server_time_of_the_day.month,
                                             server_time_of_the_day.year) +
                          ".csv",
                          'a',
                          newline="") as f:
                    writer = csv.writer(f)
                    writer.writerow(data_packet)
                    pass
                pass
            pass
        # recall this method after another second
        self.root_window.after(200, self.read_messages_and_update_UI)
        pass

    pass
Пример #5
0
class StereoVisionCalculator(object):
    def __init__(self):
        """
        Class constructor of StereoVisionCalculator.
        This method initalizes the tkinter GUI and the object variables to
        store the user input and calculation results.
        """
        # Focal length calculator parameters
        self.sensor_size = None
        self.img_width = None
        self.img_height = None
        self.focal_fov = None

        # Design limits
        self.perf_depth = None
        self.perf_depth_error = None
        self.perf_disp_max = None
        self.perf_disp = None
        self.perf_disp_calibration_error = None

        # Baseline calculator results
        self._min_depth = None
        self._baseline = None
        self._focal_length = None

        # Initialize the complete GUI
        self._initializeGUI()

    Row = namedtuple('Row', ['var_name', 'name', 'io', 'activate', 'units'])

    class RowElement(object):
        def __init__(self):
            self.name = None
            self.io = None
            self.activate = None
            self.units = None

        def setrow(self, row):
            if self.name:
                self.name.grid(row=row)
            if self.io:
                self.io.grid(row=row)
            if self.activate:
                self.activate.grid(row=row)
            if self.units:
                self.units.grid(row=row)

    def _rowPropertiesToGUI(self, master, row_prop):
        """
        Method to convert row_prop of type Row() into a GUI element
        :param: master (The master of tk element)
        :param: row_prop (An instance of Row())
        :return: An instance of RowElement
        """
        row = StereoVisionCalculator.RowElement()

        # Create the name label
        row.name = ttk.Label(master, text=row_prop.name)
        row.name.grid(column=0, sticky="W", pady=5)

        # Create io Entry var
        if row_prop.io:
            row.io = ttk.Entry(master)
        else:
            row.io = ttk.Label(master, text="0.0")
        row.io.grid(column=1, sticky="W")

        if row_prop.activate:
            row.activate = ttk.Checkbutton(master)
            row.activate.grid(column=1, sticky="E")

        # Create units Label/OptionMenu var
        if row_prop.units:
            if isinstance(row_prop.units, list):
                row.units = ttk.OptionMenu(
                    master, tk.StringVar(master, row_prop.units[1]),
                    *row_prop.units)
            else:
                row.units = tk.Label(master, text=row_prop.units)

            row.units.grid(column=2, sticky="W")

        return row

    def _initializeGUI(self):
        """
        Method to setup the StereoVision Calculator GUI using tkinter
        """
        self.root = ThemedTk(theme="arc")
        self.root.tk_setPalette(background='#f5f6f7')
        self.root.title("StereoVision Calculator")
        self.root.resizable(0, 0)  # Don't allow resize

        sensor_size_units = ['', 'mm', 'in']
        fov_type = ['', 'Horizontal', 'Vertical', 'Diagonal']
        depth_units = ['', 'mm', 'cm', 'm', 'in', 'ft']
        row_properties = [
            StereoVisionCalculator.Row('ui_sensor_size', 'Sensor size', True,
                                       False, sensor_size_units),
            StereoVisionCalculator.Row('ui_img_width', 'Image width', True,
                                       False, 'px'),
            StereoVisionCalculator.Row('ui_img_height', 'Image height', True,
                                       False, 'px'),
            StereoVisionCalculator.Row('ui_focal_fov', 'Focal FoV', True,
                                       False, fov_type),
            StereoVisionCalculator.Row('ui_perf_depth', 'Performance depth',
                                       True, False, depth_units),
            StereoVisionCalculator.Row('ui_perf_depth_error',
                                       'Performance depth error', True, False,
                                       depth_units),
            StereoVisionCalculator.Row('ui_perf_disp', 'Performance disparity',
                                       True, True, 'px'),
            StereoVisionCalculator.Row('ui_disp_max', 'Max disparity', True,
                                       False, 'px'),
            StereoVisionCalculator.Row('ui_disp_cal_error',
                                       'Calibration disparity error', True,
                                       False, 'px'),
            StereoVisionCalculator.Row('ui_focal_length', 'Focal length',
                                       False, False, 'mm'),
            StereoVisionCalculator.Row('ui_baseline', 'Baseline', False, False,
                                       'mm'),
            StereoVisionCalculator.Row('ui_depth_min', 'Min depth', False,
                                       False, 'mm'),
            # StereoVisionCalculator.Row('ui_depth_max', 'Max depth', False, False, 'm'),
            StereoVisionCalculator.Row('ui_depth_res', 'Depth resolution',
                                       False, False, 'px'),
            StereoVisionCalculator.Row('ui_depth_fov', 'Depth FoV', False,
                                       False, 'deg')
        ]

        for row_num, rp in enumerate(row_properties, start=1):
            row_element = self._rowPropertiesToGUI(self.root, rp)
            row_element.setrow(row_num)
            self.__setattr__(rp.var_name, row_element)

        self.ui_perf_disp.io["state"] = tk.DISABLED
        self.ui_perf_disp.io["width"] = 14
        self.ui_perf_disp.activate["command"] = self._disp

        self.ui_depth_res.io["text"] = "0 x 0"
        self.ui_depth_fov.io["text"] = "0° x 0°"

        # Buttons
        self.ui_auto_calculate = ttk.Checkbutton(self.root,
                                                 text="Auto calculate",
                                                 command=self._callback)
        self.ui_auto_calculate.grid(row=0, sticky="W", pady=5)

        self.ui_capture = ttk.Button(self.root,
                                     text="Capture",
                                     width=12,
                                     command=self._capture)
        self.ui_capture.grid(row=0, column=2, sticky="W")

        self.ui_calculate = ttk.Button(self.root,
                                       text="Calculate",
                                       width=12,
                                       command=self._callback)
        self.ui_calculate.grid(row=16, sticky="W")

        self.ui_plot = ttk.Button(self.root,
                                  text="Plot",
                                  width=12,
                                  command=self._plot)
        self.ui_plot.grid(row=16, column=2, sticky="W")

        col_count, row_count = self.root.grid_size()

        for col in range(col_count):
            self.root.grid_columnconfigure(col, pad=2)

    def mainloop(self):
        self.root.mainloop()

    def calculateToMeter(self, variable, conversion_from):
        result = 0
        if conversion_from is "mm":
            result = variable / 1000
        elif conversion_from is "cm":
            result = variable / 100
        elif conversion_from is "m":
            result = variable
        elif conversion_from is "in":
            result = variable * 0.0254
        elif conversion_from is "ft":
            result = variable * 0.3048

        return result

    def _focalLengthCalculator(self, size, fov_type):
        """
        Function to calculate the focal length of the imaging sensor given:
        :param: sensor_size: The diagonal sensor size
        :param: size: The measurement system of the sensor (metric/imperial)
        :param: img_width: The amount of pixels in width
        :param: img_height:  The amount of pixels in height
        :param: focal_fov: The field of view of the lens
        :param: fov_type: Horizontal, vertical or diagonal FoV
        """
        if size == 'inch':
            self.sensor_size = self.sensor_size * 25.4
        else:
            self.sensor_size = self.sensor_size

        ratio = self.img_height / self.img_width
        sensor_width_mm = math.sqrt(self.sensor_size**2 / (1.0 + ratio**2))
        sensor_height_mm = math.sqrt(self.sensor_size**2 / (1.0 + 1.0 /
                                                            (ratio**2)))

        roi_width_mm = sensor_width_mm  # * roi_width / img_width
        roi_height_mm = sensor_height_mm  # * roi_height / img_height
        roi_diagonal_mm = math.sqrt(roi_height_mm * roi_height_mm +
                                    roi_width_mm * roi_width_mm)

        fov = self.focal_fov / 180 * math.pi
        atanInner = math.tan(fov * 0.5)

        try:
            if fov_type == 'Horizontal':
                f_mm = roi_width_mm / (2 * atanInner)
            elif fov_type == 'Vertical':
                f_mm = roi_height_mm / (2 * atanInner)
            elif fov_type == 'Diagonal':
                f_mm = roi_diagonal_mm / (2 * atanInner)

            pixel_size_mm = roi_width_mm / self.img_width
            self._focal_length = f_mm / pixel_size_mm
        except ZeroDivisionError:
            f_mm = 0
            self._focal_length = 0

        return f_mm, roi_width_mm, roi_height_mm

    def _baselineCalculator(self):
        """
        Function to calculate the baseline and min depth of the stereo camera given:
            1. Focal length of the lens
            2. Performace depth
            3. Performance depth error
            4. Disparity at performance depth
            5. Calibration disparity error
        """
        disparity = self.perf_disp + self.perf_disp_calibration_error
        depth = self.perf_depth - self.perf_depth_error

        self._baseline = baselineCalculator(self._focal_length, disparity,
                                            depth)
        self._min_depth = disparityToDepth(self._baseline, self._focal_length,
                                           self.perf_disp_max)

    def _depthErrorCalculator(self, depth):
        """
        Method to calculate the max_depth_error for a given depth for
        pre-determined baseline and focal length
        :param: depth
        :return: max_depth_error
        """
        disparity_real = depthToDisparity(self._baseline, self._focal_length,
                                          depth)
        disparity_measured = disparity_real + self.perf_disp_calibration_error

        depth_measured = disparityToDepth(self._baseline, self._focal_length,
                                          disparity_measured)
        return abs(depth_measured - depth)

    def _depthCalculator(self, roi_width, roi_height, roi_width_mm,
                         roi_height_mm, img_width, d_max, f_mm):
        roi_full_pixel = str(roi_width - d_max) + ' x ' + str(roi_height)
        h_full_angle = 2 * math.atan(
            (1 * roi_width_mm * (img_width - d_max) / img_width) / (2 * f_mm))
        v_angle = 2 * math.atan(roi_height_mm / (2 * f_mm))

        FoV_h = round(h_full_angle / math.pi * 180, 1)
        FoV_v = round(v_angle / math.pi * 180, 1)
        FoV = str(FoV_h) + '° x ' + str(FoV_v) + '°'
        return FoV, roi_full_pixel

    def _callback(self):

        if (self.ui_sensor_size.io.get() and self.ui_img_width.io.get()
                and self.ui_img_height.io.get()
                and self.ui_focal_fov.io.get()):

            self.sensor_size = float(self.ui_sensor_size.io.get())
            size = self.ui_sensor_size.units["text"]
            self.img_width = int(self.ui_img_width.io.get())
            self.img_height = int(self.ui_img_height.io.get())
            self.focal_fov = float(self.ui_focal_fov.io.get())
            fov_type = self.ui_focal_fov.units["text"]

            f_mm, roi_width_mm, roi_height_mm = self._focalLengthCalculator(
                size, fov_type)
            self.ui_focal_length.io["text"] = round(f_mm, 2)

            if (self.ui_perf_depth.io.get()
                    and self.ui_perf_depth_error.io.get()
                    and self.ui_disp_max.io.get()
                    and self.ui_disp_cal_error.io.get()):

                self.perf_depth = self.calculateToMeter(
                    float(self.ui_perf_depth.io.get()),
                    self.ui_perf_depth.units["text"])
                self.perf_depth_error = self.calculateToMeter(
                    float(self.ui_perf_depth_error.io.get()),
                    self.ui_perf_depth_error.units["text"])
                self.perf_disp = 1 if not self.ui_perf_disp.io.get() else int(
                    self.ui_perf_disp.io.get())
                self.perf_disp_max = int(self.ui_disp_max.io.get())
                self.perf_disp_calibration_error = float(
                    self.ui_disp_cal_error.io.get())

                self._baselineCalculator()

                d_max = self.perf_disp_max - 1
                depth_fov, depth_res = self._depthCalculator(
                    self.img_width, self.img_height, roi_width_mm,
                    roi_height_mm, self.img_width, d_max, f_mm)
                self.ui_baseline.io["text"] = round(self._baseline * 1000, 2)
                self.ui_depth_min.io["text"] = round(self._min_depth * 1000, 2)
                self.ui_depth_res.io["text"] = depth_res
                self.ui_depth_fov.io["text"] = depth_fov

        if self.ui_auto_calculate.instate(["selected"]):
            self.root.after(100, self._callback)

    def _disp(self):
        if self.ui_perf_disp.activate.instate(["selected"]):
            self.ui_perf_disp.io["state"] = tk.NORMAL
        else:
            self.ui_perf_disp.io["state"] = tk.DISABLED

    def _capture(self):
        x1 = self.root.winfo_rootx()
        x2 = x1 + self.root.winfo_reqwidth()
        y1 = self.root.winfo_rooty()
        y2 = y1 + self.root.winfo_reqheight()

        im = grab(bbox=(x1, y1, x2, y2))
        im.show()

    def _plot(self):
        # Parameters
        if not (self._focal_length and self._baseline and self._min_depth):
            self.error = ThemedTk(theme="arc")
            self.error.tk_setPalette(background='#f5f6f7')
            self.error.title("Error!")
            label = ttk.Label(self.error,
                              text="Missing input variables!").grid(padx=15,
                                                                    pady=25)
            self.error.mainloop()
        else:
            style.use('seaborn-whitegrid')
            fig1, ax = plt.subplots()
            fig1.canvas.set_window_title('Plot')
            plt.title("Depth Error Chart")
            plt.xlabel("Depth (m)")
            plt.ylabel("Depth error (m)")
            x1 = []
            y1 = []

            # Light theme
            fig1.patch.set_facecolor('#f5f6f7')  # 212121 Dark
            ax.patch.set_facecolor('#f5f6f7')
            ax.spines['bottom'].set_color('#5c616c')  # FAFAFA Dark
            ax.spines['top'].set_color('#5c616c')
            ax.spines['right'].set_color('#5c616c')
            ax.spines['left'].set_color('#5c616c')
            ax.tick_params(axis='x', colors='#5c616c', which='both')
            ax.tick_params(axis='y', colors='#5c616c', which='both')
            ax.yaxis.label.set_color('#5c616c')
            ax.xaxis.label.set_color('#5c616c')
            ax.title.set_color('#5c616c')

            # Plot
            # Min range to max range
            max_depth = self._baseline * self._focal_length * 10
            for x in range(int(self._min_depth * 10), int(max_depth)):
                y = self._depthErrorCalculator(float(x / 10))
                x1.append(float(x / 10))
                y1.append(y)

            plt.plot(x1, y1, color="#039BE5")

            # Show
            plt.show()
Пример #6
0
temperatureLabel.grid(row=1, column=0)

pressureLabel = Label(
    main, textvariable=pressureVar)  # On crée un label qui affiche la pression
pressureLabel.grid(row=1, column=1)

humidityLabel = Label(
    main, textvariable=humidityVar)  # On crée un label qui affiche l'humidité
humidityLabel.grid(row=1, column=2)

reloadButton = Button(main, text="Recharger les données", command=reloadData)
# On crée un boutton qui permet de recharger les données
reloadButton.grid(row=2, column=0, columnspan=3)

directionLabel = Label(
    main, textvariable=directionVar
)  # On crée un label qui affiche la direction de la carte
directionLabel.grid(row=3, column=0, columnspan=3)

compass = Canvas(main,
                 width=450,
                 height=450,
                 bd=0,
                 highlightthickness=0,
                 background="#464646")
canvasImg = compass.create_image(0, 0, anchor="nw", image=images[0])
compass.grid(row=4, column=0, columnspan=3)

main.after(1000, sense)
main.mainloop()