import tkinter as tk
from tkinter import ttk, Canvas
import serial.tools.list_ports
from threading import Thread, Timer, Lock
import socket
import time
import viewmode

class MainWidget(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.master.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.btn_val = 0
        self.sndpkg_no = 0
        self.netsndpkg_no = 0
        self.net_lock = Lock()
        self.netrcvrunning = False
        self.create_widgets()

    def on_closing(self):
        self.on_net_close()
        self.on_close()
        self.master.destroy()

    def create_widgets(self):
        self.devlist = serial.tools.list_ports.comports()
        self.s = serial.Serial(baudrate=115200, timeout=1);
        self.receiving = False

        self.frame_line1 = ttk.Frame(self.master)
        self.frame_line1.grid(column=0, row=0)

        self.frame_line11 = ttk.Frame(self.frame_line1)
        self.frame_line11.grid(column=0, row=0)

        self.devcombo = ttk.Combobox(self.frame_line11)
        self.devcombo['values'] = self.devlist
        self.devcombo.grid(column=0, row=0)

        self.open_btn = tk.Button(self.frame_line11, text = "Open",  command = self.on_open)
        self.open_btn.grid(column=1, row=0)
        
        self.info_btn_Front = tk.Button(self.frame_line11, text = "Front", command = self.on_btn_front)
        self.info_btn_Front.grid(column=2, row=0)
        self.info_btn_Rear = tk.Button(self.frame_line11, text = "Rear", command = self.on_btn_rear)
        self.info_btn_Rear.grid(column=3, row=0)
        self.info_btn_IR = tk.Button(self.frame_line11, text = "IR", command = self.on_btn_IR)
        self.info_btn_IR.grid(column=4, row=0)
        self.info_btn_NUC = tk.Button(self.frame_line11, text = "NUC", command = self.on_btn_NUC)
        self.info_btn_NUC.grid(column=5, row=0)

        self.frame_line12 = ttk.Frame(self.frame_line1)
        self.frame_line12.grid(column=0, row=1)

        self.ip_label = tk.Label(self.frame_line12, text='IP:')
        self.ip_label.grid(column=0, row=0)
        self.ip_editor = tk.Entry(self.frame_line12)
        self.ip_editor.grid(column=1, row=0)

        self.port_label = tk.Label(self.frame_line12, text='Port:')
        self.port_label.grid(column=2, row=0)
        self.port_editor = tk.Entry(self.frame_line12)
        self.port_editor.grid(column=3, row=0)

        self.net_btn_conn = tk.Button(self.frame_line12, text = "Connect",  command = self.on_net_conn)
        self.net_btn_conn.grid(column=4, row=0)

        video_list = ["No View"]
        for i in range(len(viewmode.VideoMode)):
            video_list.append(viewmode.VideoMode[i][0])

        self.VO1_label = tk.Label(self.frame_line12, text='Video Out 0:')
        self.VO1_label.grid(column=0, row=1)
        self.VI1_combo = ttk.Combobox(self.frame_line12)
        self.VI1_combo['values'] = video_list
        self.VI1_combo.grid(column=1, row=1)
        self.VI1_combo.bind('<<ComboboxSelected>>', self.VO1_send)


        self.ip_label = tk.Label(self.frame_line12, text='IP:')
        self.ip_label.grid(column=2, row=1)
        self.ip1 = tk.Entry(self.frame_line12)
        self.ip1.grid(column=3, row=1)

        self.port_label = tk.Label(self.frame_line12, text='Port:')
        self.port_label.grid(column=4, row=1)
        self.port1 = tk.Entry(self.frame_line12)
        self.port1.grid(column=5, row=1)

        self.VO2_label = tk.Label(self.frame_line12, text='Video Out 1:')
        self.VO2_label.grid(column=0, row=2)
        self.VI2_combo = ttk.Combobox(self.frame_line12)
        self.VI2_combo['values'] = video_list
        self.VI2_combo.grid(column=1, row=2)
        self.VI2_combo.bind('<<ComboboxSelected>>', self.VO2_send)

        self.ip_label = tk.Label(self.frame_line12, text='IP:')
        self.ip_label.grid(column=2, row=2)
        self.ip2 = tk.Entry(self.frame_line12)
        self.ip2.grid(column=3, row=2)

        self.port_label = tk.Label(self.frame_line12, text='Port:')
        self.port_label.grid(column=4, row=2)
        self.port2 = tk.Entry(self.frame_line12)
        self.port2.grid(column=5, row=2)

        self.VO3_label = tk.Label(self.frame_line12, text='Video Out 2:')
        self.VO3_label.grid(column=0, row=3)
        self.VI3_combo = ttk.Combobox(self.frame_line12)
        self.VI3_combo['values'] = video_list
        self.VI3_combo.grid(column=1, row=3)
        self.VI3_combo.bind('<<ComboboxSelected>>', self.VO3_send)

        self.ip_label = tk.Label(self.frame_line12, text='IP:')
        self.ip_label.grid(column=2, row=3)
        self.ip3 = tk.Entry(self.frame_line12)
        self.ip3.grid(column=3, row=3)

        self.port_label = tk.Label(self.frame_line12, text='Port:')
        self.port_label.grid(column=4, row=3)
        self.port3 = tk.Entry(self.frame_line12)
        self.port3.grid(column=5, row=3)

        self.VO4_label = tk.Label(self.frame_line12, text='Video Out 3:')
        self.VO4_label.grid(column=0, row=4)
        self.VI4_combo = ttk.Combobox(self.frame_line12)
        self.VI4_combo['values'] = video_list
        self.VI4_combo.grid(column=1, row=4)
        self.VI4_combo.bind('<<ComboboxSelected>>', self.VO4_send)

        self.ip_label = tk.Label(self.frame_line12, text='IP:')
        self.ip_label.grid(column=2, row=4)
        self.ip4 = tk.Entry(self.frame_line12)
        self.ip4.grid(column=3, row=4)

        self.port_label = tk.Label(self.frame_line12, text='Port:')
        self.port_label.grid(column=4, row=4)
        self.port4 = tk.Entry(self.frame_line12)
        self.port4.grid(column=5, row=4)

        self.frame_line13 = ttk.Frame(self.frame_line1)
        self.frame_line13.grid(column=0, row=2)

        self.sys_btn_vout0 = tk.Button(self.frame_line13, text = "VOUT1", bg = "green")
        self.sys_btn_vout0.grid(column=0, row=0)
        self.sys_btn_vout1 = tk.Button(self.frame_line13, text = "VOUT2", bg = "green")
        self.sys_btn_vout1.grid(column=1, row=0)
        self.sys_btn_vout2 = tk.Button(self.frame_line13, text = "VOUT3", bg = "green")
        self.sys_btn_vout2.grid(column=2, row=0)
        self.sys_btn_vout3 = tk.Button(self.frame_line13, text = "VOUT4", bg = "green")
        self.sys_btn_vout3.grid(column=3, row=0)

        self.frame_line14 = ttk.Frame(self.frame_line1)
        self.frame_line14.grid(column=0, row=3)

        self.sys_btn_sdi0 = tk.Button(self.frame_line14, text = "SDI1", bg = "green")
        self.sys_btn_sdi0.grid(column=0, row=0)
        self.sys_btn_sdi1 = tk.Button(self.frame_line14, text = "SDI2", bg = "green")
        self.sys_btn_sdi1.grid(column=1, row=0)
        self.sys_btn_sdi2 = tk.Button(self.frame_line14, text = "SDI3", bg = "green")
        self.sys_btn_sdi2.grid(column=2, row=0)
        self.sys_btn_sdi3 = tk.Button(self.frame_line14, text = "SDI4", bg = "green")
        self.sys_btn_sdi3.grid(column=3, row=0)
        self.sys_btn_sdi4 = tk.Button(self.frame_line14, text = "SDI5", bg = "green")
        self.sys_btn_sdi4.grid(column=4, row=0)
        self.sys_btn_sdi5 = tk.Button(self.frame_line14, text = "SDI6", bg = "green")
        self.sys_btn_sdi5.grid(column=5, row=0)
        self.sys_btn_sdi6 = tk.Button(self.frame_line14, text = "SDI7", bg = "green")
        self.sys_btn_sdi6.grid(column=6, row=0)
        self.sys_btn_sdi7 = tk.Button(self.frame_line14, text = "SDI8", bg = "green")
        self.sys_btn_sdi7.grid(column=7, row=0)
        self.sys_btn_sdi8 = tk.Button(self.frame_line14, text = "SDI9", bg = "green")
        self.sys_btn_sdi8.grid(column=8, row=0)
        self.sys_btn_sdi9 = tk.Button(self.frame_line14, text = "SDI10", bg = "green")
        self.sys_btn_sdi9.grid(column=9, row=0)

        self.frame_line15 = ttk.Frame(self.frame_line1)
        self.frame_line15.grid(column=0, row=4)
        
        self.sys_btn_sdi10 = tk.Button(self.frame_line15, text = "SDI11", bg = "green")
        self.sys_btn_sdi10.grid(column=0, row=0)
        self.sys_btn_sdi11 = tk.Button(self.frame_line15, text = "SDI12", bg = "green")
        self.sys_btn_sdi11.grid(column=1, row=0)
        self.sys_btn_sdi12 = tk.Button(self.frame_line15, text = "SDI13", bg = "green")
        self.sys_btn_sdi12.grid(column=2, row=0)
        self.sys_btn_sdi13 = tk.Button(self.frame_line15, text = "SDI14", bg = "green")
        self.sys_btn_sdi13.grid(column=3, row=0)
        self.sys_btn_sdi14 = tk.Button(self.frame_line15, text = "SDI15", bg = "green")
        self.sys_btn_sdi14.grid(column=4, row=0)
        self.sys_btn_sdi15 = tk.Button(self.frame_line15, text = "SDI16", bg = "green")
        self.sys_btn_sdi15.grid(column=5, row=0)
        self.sys_btn_sdi16 = tk.Button(self.frame_line15, text = "SDI17", bg = "green")
        self.sys_btn_sdi16.grid(column=6, row=0)
        self.sys_btn_sdi17 = tk.Button(self.frame_line15, text = "SDI18", bg = "green")
        self.sys_btn_sdi17.grid(column=7, row=0)
        self.sys_btn_sdi18 = tk.Button(self.frame_line15, text = "SDI19", bg = "green")
        self.sys_btn_sdi18.grid(column=8, row=0)
        self.sys_btn_sdi19 = tk.Button(self.frame_line15, text = "SDI20", bg = "green")
        self.sys_btn_sdi19.grid(column=9, row=0)

        self.frame_line16 = ttk.Frame(self.frame_line1)
        self.frame_line16.grid(column=0, row=5)

        self.label = tk.Label(self.frame_line16, text="cpu0:")
        self.label.grid(column=0, row=0)
        self.cpu0 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.cpu0)
        self.label.grid(column=1, row=0)
        self.cpu0.set("-")

        self.label = tk.Label(self.frame_line16, text="cpu1:")
        self.label.grid(column=2, row=0)
        self.cpu1 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.cpu1)
        self.label.grid(column=3, row=0)
        self.cpu1.set("-")

        self.label = tk.Label(self.frame_line16, text="cpu2:")
        self.label.grid(column=4, row=0)
        self.cpu2 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.cpu2)
        self.label.grid(column=5, row=0)
        self.cpu2.set("-")

        self.label = tk.Label(self.frame_line16, text="cpu3:")
        self.label.grid(column=6, row=0)
        self.cpu3 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.cpu3)
        self.label.grid(column=7, row=0)
        self.cpu3.set("-")

        self.label = tk.Label(self.frame_line16, text="mem0:")
        self.label.grid(column=8, row=0)
        self.mem0 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.mem0)
        self.label.grid(column=9, row=0)
        self.mem0.set("-")

        self.label = tk.Label(self.frame_line16, text="mem1:")
        self.label.grid(column=10, row=0)
        self.mem1 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.mem1)
        self.label.grid(column=11, row=0)
        self.mem1.set("-")

        self.label = tk.Label(self.frame_line16, text="mem2:")
        self.label.grid(column=12, row=0)
        self.mem2 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.mem2)
        self.label.grid(column=13, row=0)
        self.mem2.set("-")

        self.label = tk.Label(self.frame_line16, text="mem3:")
        self.label.grid(column=14, row=0)
        self.mem3 = tk.StringVar()
        self.label = tk.Label(self.frame_line16, textvariable=self.mem3)
        self.label.grid(column=15, row=0)
        self.mem3.set("-")

        self.frame_line17 = ttk.Frame(self.frame_line1)
        self.frame_line17.grid(column=0, row=6)
        
        self.label = tk.Label(self.frame_line17, text="temp0:")
        self.label.grid(column=0, row=0)
        self.temp0 = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.temp0)
        self.label.grid(column=1, row=0)
        self.temp0.set("-")

        self.label = tk.Label(self.frame_line17, text="temp1:")
        self.label.grid(column=2, row=0)
        self.temp1 = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.temp1)
        self.label.grid(column=3, row=0)
        self.temp1.set("-")

        self.label = tk.Label(self.frame_line17, text="temp2:")
        self.label.grid(column=4, row=0)
        self.temp2 = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.temp2)
        self.label.grid(column=5, row=0)
        self.temp2.set("-")

        self.label = tk.Label(self.frame_line17, text="temp3:")
        self.label.grid(column=6, row=0)
        self.temp3 = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.temp3)
        self.label.grid(column=7, row=0)
        self.temp3.set("-")

        self.label = tk.Label(self.frame_line17, text="Version:")
        self.label.grid(column=8, row=0)
        self.version = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.version)
        self.label.grid(column=9, row=0)
        self.version.set("-")

        self.label = tk.Label(self.frame_line17, text="Variant:")
        self.label.grid(column=10, row=0)
        self.variant = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.variant)
        self.label.grid(column=11, row=0)
        self.variant.set("-")
        
        self.label = tk.Label(self.frame_line17, text="iDDP View:")
        self.label.grid(column=12, row=0)
        self.iddp = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.iddp)
        self.label.grid(column=13, row=0)
        self.iddp.set("-")

        self.label = tk.Label(self.frame_line17, text="NumRTPStreams:")
        self.label.grid(column=14, row=0)
        self.numrtpstreams = tk.StringVar()
        self.label = tk.Label(self.frame_line17, textvariable=self.numrtpstreams)
        self.label.grid(column=15, row=0)
        self.numrtpstreams.set("-")

    def on_open(self):
        curSel = self.devcombo.current()
        port = self.devlist[curSel].device
        if self.s.is_open:
            self.s.close()
        self.s.port = port
        self.s.open()

        if self.s.is_open:
            self.open_btn['text'] = "Close"
            self.open_btn['command'] = self.on_close
            self.rcvtd = Thread(target=self.rcv_cb)
            self.rcvtd.start()
            self.sndtd = Timer(0.1, self.sending_cb)
            self.sndtd.start()
            
    def on_close(self):
        if self.receiving:
           self.receiving = False
           self.rcvtd.join()
        if self.s.is_open:
            self.s.close()
            self.sndtd.cancel()
        self.open_btn['text'] = "Open"
        self.open_btn['command'] = self.on_open

    def on_btn_front(self):
        self.btn_val = self.btn_val & 0xc
        self.btn_val = self.btn_val | 1
        
    def on_btn_rear(self):
        self.btn_val = self.btn_val & 0xc
        self.btn_val = self.btn_val | 2
        
    def on_btn_IR(self):
        self.btn_val = self.btn_val | 4
        
    def on_btn_NUC(self):
        self.btn_val = self.btn_val | 8

    def sending_cb(self):
        if self.s.is_open:
            sndstr = "$KEY,{0},{1:02X},0,0*".format(self.sndpkg_no, self.btn_val)
            snd_byte = bytearray(sndstr, 'utf-8')
            snd_byte.append(0x00)
            self.s.write(snd_byte)
            self.sndpkg_no = self.sndpkg_no + 1
            if self.sndpkg_no > 255:
                self.sndpkg_no = 0
            self.sndtd = Timer(0.1, self.sending_cb)
            self.sndtd.start()
            
    def rcv_cb(self):
        self.receiving = True
        rcv_data = bytearray()
        rcv_step = 0
        while self.receiving:
            rec = self.s.read(1)
            if len(rec) < 1:
                continue
            if rcv_step == 0 and rec[0] == 0x24:
                rcv_step = 1
            elif rcv_step == 1:
                if rec[0] == 0x2a:
                    rcv_step = 2
                else:
                    rcv_data.append(rec[0])
            elif rcv_step == 2:
                if rec[0] == 0 or rec[0] == 0x0d or rec[0] == 0x0a:
                    rcv_step = 3
            elif rcv_step == 3:
                rcv_step = 0
                print(rcv_data);
                rcvlist = rcv_data.decode().split(',')
                rcv_data = bytearray()
                if len(rcvlist) >= 3:
                    if rcvlist[0] == "KEYA":
                        keyval = int(rcvlist[2], 16)
                        if keyval & 0x1:
                            self.btn_val = self.btn_val & 0xe
                        if keyval & 0x2:
                            self.btn_val = self.btn_val & 0xd
                        if keyval & 0x4:
                            self.btn_val = self.btn_val & 0xb
                        if keyval & 0x8:
                            self.btn_val = self.btn_val & 0x7         
            else:
                rcv_step = 0

    def show_sysbit_status(self, sys_status):
        if sys_status & 0x1:
            self.sys_btn_sdi0.configure(bg = "red")
        else:
            self.sys_btn_sdi0.configure(bg = "green")
        if sys_status & 0x2:
            self.sys_btn_sdi1.configure(bg = "red")
        else:
            self.sys_btn_sdi1.configure(bg = "green")
        if sys_status & 0x4:
            self.sys_btn_sdi2.configure(bg = "red")
        else:
            self.sys_btn_sdi2.configure(bg = "green")
        if sys_status & 0x8:
            self.sys_btn_sdi3.configure(bg = "red")
        else:
            self.sys_btn_sdi3.configure(bg = "green")
        if sys_status & 0x10:
            self.sys_btn_sdi4.configure(bg = "red")
        else:
            self.sys_btn_sdi4.configure(bg = "green")
        if sys_status & 0x20:
            self.sys_btn_sdi5.configure(bg = "red")
        else:
            self.sys_btn_sdi5.configure(bg = "green")
        if sys_status & 0x40:
            self.sys_btn_sdi6.configure(bg = "red")
        else:
            self.sys_btn_sdi6.configure(bg = "green")
        if sys_status & 0x80:
            self.sys_btn_sdi7.configure(bg = "red")
        else:
            self.sys_btn_sdi7.configure(bg = "green")
        if sys_status & 0x100:
            self.sys_btn_sdi8.configure(bg = "red")
        else:
            self.sys_btn_sdi8.configure(bg = "green")
        if sys_status & 0x200:
            self.sys_btn_sdi9.configure(bg = "red")
        else:
            self.sys_btn_sdi9.configure(bg = "green")
        if sys_status & 0x400:
            self.sys_btn_sdi10.configure(bg = "red")
        else:
            self.sys_btn_sdi10.configure(bg = "green")
        if sys_status & 0x800:
            self.sys_btn_sdi11.configure(bg = "red")
        else:
            self.sys_btn_sdi11.configure(bg = "green")
        if sys_status & 0x1000:
            self.sys_btn_sdi12.configure(bg = "red")
        else:
            self.sys_btn_sdi12.configure(bg = "green")
        if sys_status & 0x2000:
            self.sys_btn_sdi13.configure(bg = "red")
        else:
            self.sys_btn_sdi13.configure(bg = "green")
        if sys_status & 0x4000:
            self.sys_btn_sdi14.configure(bg = "red")
        else:
            self.sys_btn_sdi14.configure(bg = "green")
        if sys_status & 0x8000:
            self.sys_btn_sdi15.configure(bg = "red")
        else:
            self.sys_btn_sdi15.configure(bg = "green")
        if sys_status & 0x10000:
            self.sys_btn_sdi16.configure(bg = "red")
        else:
            self.sys_btn_sdi16.configure(bg = "green")
        if sys_status & 0x20000:
            self.sys_btn_sdi17.configure(bg = "red")
        else:
            self.sys_btn_sdi17.configure(bg = "green")
        if sys_status & 0x40000:
            self.sys_btn_sdi18.configure(bg = "red")
        else:
            self.sys_btn_sdi18.configure(bg = "green")
        if sys_status & 0x80000:
            self.sys_btn_sdi19.configure(bg = "red")
        else:
            self.sys_btn_sdi19.configure(bg = "green")
        if sys_status & 0x100000:
            self.sys_btn_vout0.configure(bg = "red")
        else:
            self.sys_btn_vout0.configure(bg = "green")
        if sys_status & 0x200000:
            self.sys_btn_vout1.configure(bg = "red")
        else:
            self.sys_btn_vout1.configure(bg = "green")
        if sys_status & 0x400000:
            self.sys_btn_vout2.configure(bg = "red")
        else:
            self.sys_btn_vout2.configure(bg = "green")
        if sys_status & 0x800000:
            self.sys_btn_vout3.configure(bg = "red")
        else:
            self.sys_btn_vout3.configure(bg = "green")
                                       
    def net_rcv_cb(self):
        self.netrcvrunning = True
        while self.netrcvrunning == True:
            rcv_bytes = self.client.recv(1500)
            if rcv_bytes.__len__() > 20:
                msgHeader = int.from_bytes(rcv_bytes[0:2], "little")
                type = int.from_bytes(rcv_bytes[2:3], "little")
                version = int.from_bytes(rcv_bytes[3:4], "little")
                sequencenumber = int.from_bytes(rcv_bytes[4:8], "little")
                timestamp = int.from_bytes(rcv_bytes[8:16], "little")

                if msgHeader != 0x5354:
                    continue
                if type == 1:
                    snd_bytes = bytearray(b'\x54\x53\x02\x00')
                    snd_bytes = snd_bytes + rcv_bytes[4:16]
                    self.client.send(snd_bytes)

                    sysload0 = int.from_bytes(rcv_bytes[20:21], "little")
                    sysload1 = int.from_bytes(rcv_bytes[21:22], "little")
                    sysload2 = int.from_bytes(rcv_bytes[22:23], "little")
                    sysload3 = int.from_bytes(rcv_bytes[23:24], "little")
                    sysmem0 = int.from_bytes(rcv_bytes[24:25], "little")
                    sysmem1 = int.from_bytes(rcv_bytes[25:26], "little")
                    sysmem2 = int.from_bytes(rcv_bytes[26:27], "little")
                    sysmem3 = int.from_bytes(rcv_bytes[27:28], "little")
                    systemp0 = int.from_bytes(rcv_bytes[28:29], "little")
                    systemp1 = int.from_bytes(rcv_bytes[29:30], "little")
                    systemp2 = int.from_bytes(rcv_bytes[30:31], "little")
                    systemp3 = int.from_bytes(rcv_bytes[31:32], "little")
                    version = "{0}.{1}.{2}".format(int.from_bytes(rcv_bytes[32:33], "little"), int.from_bytes(rcv_bytes[33:34], "little"), int.from_bytes(rcv_bytes[34:35], "little"))
                    variant = int.from_bytes(rcv_bytes[35:36], "little")
                    iddpview = int.from_bytes(rcv_bytes[36:37], "little")
                    numrtpstreams = int.from_bytes(rcv_bytes[37:38], "little")
                    bitReportMask = int.from_bytes(rcv_bytes[40:44], "little")
                    
                    self.show_sysbit_status(bitReportMask)

                    self.cpu0.set("{0}".format(sysload0))
                    self.cpu1.set("{0}".format(sysload1))
                    self.cpu2.set("{0}".format(sysload2))
                    self.cpu3.set("{0}".format(sysload3))
                    self.mem0.set("{0}".format(sysmem0))
                    self.mem1.set("{0}".format(sysmem1))
                    self.mem2.set("{0}".format(sysmem2))
                    self.mem3.set("{0}".format(sysmem3))
                    self.temp0.set("{0}".format(systemp0))
                    self.temp1.set("{0}".format(systemp1))
                    self.temp2.set("{0}".format(systemp2))
                    self.temp3.set("{0}".format(systemp3))
                    self.version.set(version)
                    self.variant.set("{0}".format(variant))
                    self.iddp.set("{0}".format(iddpview))
                    self.numrtpstreams.set("{0}".format(numrtpstreams))
                if type == 2:
                    SequenceNumver = int.from_bytes(rcv_bytes[4:8], "little")
                    Timestampe = int.from_bytes(rcv_bytes[8:16], "little")
                    AckSequenceNumber = int.from_bytes(rcv_bytes[16:20], "little")
                    AckStatus = int.from_bytes(rcv_bytes[20:21], "little")
                    FaultCode = int.from_bytes(rcv_bytes[22:24], "little")
                    print("AckNo:{0} AckStatus:{1} Fault:{2:X}".format(AckSequenceNumber, AckStatus, FaultCode))
                                       
            else:
                self.net_btn_conn['text'] = "Connect"
                self.net_btn_conn['command'] = self.on_net_conn

                self.cpu0.set("-")
                self.cpu1.set("-")
                self.cpu2.set("-")
                self.cpu3.set("-")
                self.mem0.set("-")
                self.mem1.set("-")
                self.mem2.set("-")
                self.mem3.set("-")
                self.temp0.set("-")
                self.temp1.set("-")
                self.temp2.set("-")
                self.temp3.set("-")
                self.version.set("-")
                self.variant.set("-")
                self.iddp.set("-")
                self.numrtpstreams.set("-")

                self.netrcvrunning = False

                self.client.close()
                
    def on_net_conn(self):        
        ipaddr = self.ip_editor.get()
        ipport = self.port_editor.get()
        port = int(ipport)
        print('ipaddr={0} port={1}'.format(ipaddr, port))
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.client.settimeout(2)
        try:
            self.client.connect((ipaddr, port))
        except socket.error as msg:
            print("connect error:{0}".format(msg))
            return

        self.net_btn_conn['text'] = "Disconnect"
        self.net_btn_conn['command'] = self.on_net_close

        self.netrcvtd = Thread(target=self.net_rcv_cb)
        self.netrcvtd.start()
	

    def on_net_close(self):
        if self.netrcvrunning:
            self.netrcvrunning = False
            time.sleep(1)
            self.client.close()

        self.net_btn_conn['text'] = "Connect"
        self.net_btn_conn['command'] = self.on_net_conn

        self.cpu0.set("-")
        self.cpu1.set("-")
        self.cpu2.set("-")
        self.cpu3.set("-")
        self.mem0.set("-")
        self.mem1.set("-")
        self.mem2.set("-")
        self.mem3.set("-")
        self.temp0.set("-")
        self.temp1.set("-")
        self.temp2.set("-")
        self.temp3.set("-")
        self.version.set("-")
        self.variant.set("-")
        self.iddp.set("-")
        self.numrtpstreams.set("-")


    def VO1_send(self, event):
        insel = self.VI1_combo.current()
        ipaddr = self.ip1.get()
        ipport = self.port1.get()
        self.VO_send(0, insel, ipaddr, ipport)

    def VO2_send(self, event):
        insel = self.VI2_combo.current()
        ipaddr = self.ip2.get()
        ipport = self.port2.get()
        self.VO_send(1, insel, ipaddr, ipport)

    def VO3_send(self, event):
        insel = self.VI3_combo.current()
        ipaddr = self.ip3.get()
        ipport = self.port3.get()
        self.VO_send(2, insel, ipaddr, ipport)

    def VO4_send(self, event):
        insel = self.VI4_combo.current()
        ipaddr = self.ip4.get()
        ipport = self.port4.get()
        self.VO_send(3, insel, ipaddr, ipport)

    def VO_send(self, outsel, insel, ipaddr, ipport):
        if insel == 0:
            cmdlist = []
            viewlist = []
            list_no = 0
        else:
            insel = insel - 1
            cmdlist = viewmode.VideoMode[insel]
            viewlist = cmdlist[3]
            list_no = len(viewlist)

        if list_no == 0:
            snd_byte = bytearray(b'\x54\x53\x11\x00\x01\x02\x03\x04\x01\x02\x03\x04\x05\x06\x07\x08')
            iplist = ipaddr.split('.')
            snd_byte.append(int(iplist[0]))
            snd_byte.append(int(iplist[1]))
            snd_byte.append(int(iplist[2]))
            snd_byte.append(int(iplist[3]))
            intport = int(ipport)
            snd_byte.append(intport&0xff)
            snd_byte.append((intport >> 8)&0xff)
            snd_byte.append(0)
            snd_byte.append(0)
        else:
            snd_byte = bytearray(b'\x54\x53\x10\x00\x01\x02\x03\x04\x01\x02\x03\x04\x05\x06\x07\x08')
            iplist = ipaddr.split('.')
            snd_byte.append(int(iplist[0]))
            snd_byte.append(int(iplist[1]))
            snd_byte.append(int(iplist[2]))
            snd_byte.append(int(iplist[3]))
            intport = int(ipport)
            snd_byte.append(intport&0xff)
            snd_byte.append((intport >> 8)&0xff)
            snd_byte.append(0)
            snd_byte.append(0)
            snd_byte.append(cmdlist[1] & 0xff)
            snd_byte.append((cmdlist[1] >> 8) & 0xff)
            snd_byte.append(cmdlist[2] & 0xff)
            snd_byte.append((cmdlist[2] >> 8) & 0xff)
            snd_byte.append(0)
            snd_byte.append(0)
            snd_byte.append(0)
            snd_byte.append(list_no)
            for i in range(list_no):
                snd_byte.append(viewlist[i][0])
                snd_byte.append(viewlist[i][1])
                snd_byte.append(0)
                snd_byte.append(0)
                snd_byte.append(viewlist[i][2] & 0xff)
                snd_byte.append((viewlist[i][2] >> 8) & 0xff)
                snd_byte.append(viewlist[i][3] & 0xff)
                snd_byte.append((viewlist[i][3] >> 8) & 0xff)
                snd_byte.append(viewlist[i][4] & 0xff)
                snd_byte.append((viewlist[i][4] >> 8) & 0xff)
                snd_byte.append(viewlist[i][5] & 0xff)
                snd_byte.append((viewlist[i][5] >> 8) & 0xff)

        self.net_lock.acquire(timeout=5)
        try:
            self.client.send(snd_byte)
        except socket.error as msg:
            print("send error:{0}".format(msg))
            self.on_net_close()
            self.net_lock.release()
            return
		
        self.net_lock.release()
        
    def devinfo_read(self):
        sndstr = '$DEV,0*'
        snd_byte = bytearray(sndstr, 'utf-8')
        snd_byte.append(0x00)
        self.net_lock.acquire(timeout=5)
        try:
            self.client.send(snd_byte)
        except socket.error as msg:
            print("send error:{0}".format(msg))
            self.on_net_close()
            self.net_lock.release()
            return
		
        try:
            rcv_byte = self.client.recv(1500)
        except socket.error as msg:
            print("recv error:{0}".format(msg))
            self.on_net_close()
            self.net_lock.release()
            return
        self.net_lock.release()
        
        self.net_rcv_cb(rcv_byte)
         
if __name__ == "__main__":
    root = tk.Tk()
    mainwin = MainWidget(master = root)
    mainwin.mainloop()
