#! /usr/bin/python # -*- coding: utf-8 -*- """ Valid-License-Identifier: GPL-2.0-only SPDX-URL: https://spdx.org/licenses/GPL-2.0-only.html (c) 2012 micha@librelight.de """ import os import time import struct import sys import tkinter as Tkinter import _thread as thread import nodescan #import nodescan2 #as nodescaner title = "TK-ArtNet-Nodscaner" sys.stdout.write("\x1b]2;"+title+"\x07") #lock.acquire() #lock.release() class LOCK_BUF(): def __init__(self): self.data = [] self.lock = thread.allocate_lock() def append(self,data): try: self.lock.acquire() self.data.append(data) finally: self.lock.release() def set(self,data): try: self.lock.acquire() self.data = data[:] finally: self.lock.release() def get(self): out = [] try: self.lock.acquire() out = self.data[:] finally: self.lock.release() return out node_list = LOCK_BUF() #[] def fill_form(event=None): print(sys._getframe().f_code.co_name) global node_list clear_form() node_list2 = node_list.get() sel=0 try: csel = li_nodes.curselection()[0] except Exception as e: print("ERR no node selected in node-list:",e) return 0 print("+++",[csel,len(node_list2)]) try: sel = int(li_nodes.get(csel).split()[0])-1 except: print("ERR no leeding number in Listbox.line" ) return 0 if not node_list2: return 0 print("INFO: sel,node_list2",sel,len(node_list2)) e_ip.configure(state='normal') e_ip.insert("end",node_list2[sel]["IP"].replace("[","").replace("]","")) #e_ip.configure(state='readonly') e_ip_new.insert("end",node_list2[sel]["IP"].replace("[","").replace("]","")) e_mac.delete("0","end") e_mac.insert("end",node_list2[sel]["MAC"].replace("[","").replace("]","")) e_mac2.delete("0","end") e_mac2.insert("end",node_list2[sel]["MAC"].split(":")[-1]) print("load",node_list2[sel]) e_lname.delete("0","end") e_lname.insert("end",node_list2[sel]["lname"]) e_sname.delete("0","end") e_sname.insert("end",node_list2[sel]["sname"]) e_artnet_uni1.delete("0","end") univ = "0" try: if node_list2[sel]["PortTypes"][0] == "@": univ = ord(node_list2[sel]["SwIn"][0]) else: univ = ord(node_list2[sel]["SwOut"][0]) except Exception as e: print("load Exception",e) MSG["text"] = e MSG["bg"] = "red" e_artnet_uni1.insert("end",univ) def clear_form(): print(sys._getframe().f_code.co_name) e_ip.configure(state='normal') e_ip.delete("0","end") e_ip.configure(state='readonly') e_ip_new.delete("0","end") e_mac.delete("0","end") e_mac2.delete("0","end") e_lname.delete("0","end") e_sname.delete("0","end") e_artnet_uni1.delete("0","end") def clear_node_list(): print(sys._getframe().f_code.co_name) li_nodes.delete("0","end") def poll(delay=1,ip=""): print(sys._getframe().f_code.co_name) if not ip: ip = p_variable.get() b_scan.insert("end", "ArtNetPoll -> "+str(ip)+"\n") nodescan.ArtNet_poll(ip) time.sleep(1) fill_form() def clear(event= None): print(sys._getframe().f_code.co_name) clear_node_list() clear_form() def poll_loop(): print(sys._getframe().f_code.co_name) time.sleep(1) while 1: poll() time.sleep(1) old_tick = 0 rx = nodescan.ArtNetNodes() #rx = nodescan2 def scan(): print(sys._getframe().f_code.co_name) global rx,node_list,old_tick,Scrollbar print("get node from cache " ) li_nodes.insert("end",str("----")) rx.loop() while 1: try: _scan() except Exception as e: print("_scan Exception as",e,e.argv[0]) MSG["text"] = e MSG["bg"] = "red" time.sleep(0.3) def _scan(): #print(sys._getframe().f_code.co_name) global rx,node_list,old_tick,Scrollbar tick = rx.tick() if tick == old_tick: return 0 old_tick=tick nodes = rx.get() rx.clear() ok=0 for n in nodes: if n not in node_list.get(): node_list.append(n) ok=1 if ok: refresh_node_list() def refresh_node_list(): print(sys._getframe().f_code.co_name) #aprint(len(nodes)) li_node_scroll = li_nodes.yview() li_nodes.delete("0","end") node_nr = 1 nodesB = {} for node in node_list.get(): #nodes: k = node["MAC"] nodesB[k] = node print("k",nodesB.keys()) k_sort = list(nodesB.keys()) k_sort.sort() node_list.set([]) # =[] for k in k_sort: node_list.append(nodesB[k]) print("k sort",k_sort) for k in k_sort: node = nodesB[k] li_nodes.insert("end",str(node_nr).rjust(3," ") +" "+ node["lname"]) bg = "lightgrey" color = li_nodes.itemconfig("end", bg=bg) ip = str(node_nr).rjust(3," ") +" "+ node["IP"] bg = "" if "PortTypes" in node: if not node["PortTypes"]: pass if node["PortTypes"][0] == "@": ip += " DMX-in" bg ="yellow" else: ip += " DMX-out" bg ="lightgreen" if bg: color = li_nodes.itemconfig("end", bg=bg) li_nodes.insert("end",str(node_nr).rjust(3," ") +" short Name:"+ node["sname"]) li_nodes.insert("end",ip) if bg: color = li_nodes.itemconfig("end", bg=bg) inout = " UNIVERS OUT="+ str(ord(node["SwOut"][0]))+" IN="+ str(ord(node["SwIn"][0])) li_nodes.insert("end",str(node_nr).rjust(3," ") + inout) li_nodes.insert("end",str(node_nr).rjust(3," ") +" MAC:"+ node["MAC"]) last_change=time.time()-float(node["UPDATESTAMP"]) timeline = "" timeline += " LASTCHANGE:%0.1f"% (last_change) REFRESHSTAMP = time.time()-float(node["REFRESHSTAMP"]) timeline +=" LASTPING:%0.1f"% REFRESHSTAMP li_nodes.insert("end",str(node_nr).rjust(3," ") +timeline ) if last_change > 10: color = li_nodes.itemconfig("end", bg="ORANGE") if node["BOOT"]: BOOT = time.time()-float(node["BOOT"]) else: BOOT = 0 timeline =" BOOT:%0.1f"% BOOT li_nodes.insert("end",str(node_nr).rjust(3," ") +timeline +" sec" ) bg = "" if bg: li_nodes.itemconfig("end", bg=bg) li_nodes.insert("end","*"*60) node_nr += 1 #node_list += [node] print("scroll:",li_node_scroll) def get_new_ip(event=None): print(sys._getframe().f_code.co_name) b = e_ip_new.get().replace("[","").replace("]","") return b def get_new_ip_str(event=None): print(sys._getframe().f_code.co_name) x = get_new_ip() #x = x[1:-1] x = x.strip() #x = x.replace(",",".") x = x.replace(" ","") x = x.split(",") print( "get_new_ip_str",x) return x def send_artaddr(event=None): print(sys._getframe().f_code.co_name) ln = e_lname.get() sn = e_sname.get() ip = e_ip_new.get() ip = ip.replace(" ","") ip = ip.replace(",",".") univ = e_artnet_uni1.get() print("SEND ArtAddress:",[ln,sn,ip,univ]) if ln and sn and ip and univ: nodescan.ArtAddress(ip=ip ,ShortName=sn, LongName=ln,Port="",Universes=univ) time.sleep(1) poll() def send_none(event=None): print(sys._getframe().f_code.co_name) pass def send_mac(event=None): print(sys._getframe().f_code.co_name) #new_mac = "CMD MAC6 " + hex(e_mac2.get()) #) #new_mac = "CMD MAC6 " + struct.pack("",width=10,command=poll,font=font2) b_scan.configure(bg="#0f0") b_scan.pack(side="left",expand=0,fill="y") #POLL ['192.168.0.255', 6454] OK ; #POLL ['192.168.0.99', 6454] OK ; #POLL ['2.255.255.255', 6454] OK ; #POLL ['2.0.0.255', 6454] OK ; #POLL ['2.255.255.255', 6454] OK ; def get_ips(): local_ips = [] #local_ips.append("2.0.0.255") cmd='ip a | grep " inet " | cut -d " " -f 6 | sort -h' r=os.popen(cmd) print("cmd",cmd) txt=r.readlines() for ip in txt: ip = ip.strip() print([ip]) if ip.startswith("127."): continue if ip.count(".") != 3: continue if ip.endswith("/24"): ip = ip.split(".") ip = ".".join(ip[:3])+".255" elif ip.endswith("/8"): ip = ip.split(".") ip = ".".join(ip[0])+".255.255.255" else: continue print("-",ip) #if ip == "2.255.255.255": # print("- workaround -") # local_ips.append("2.0.0.255") local_ips.append(ip) return local_ips local_ips =get_ips() option_list=local_ips p_variable = Tkinter.StringVar(root) p_variable.set(option_list[0]) # default value e_poll_new = Tkinter.OptionMenu(fframe, p_variable,*option_list,) e_poll_new.configure(font=("Helvetica", 13)) e_poll_new.configure(width=13) e_poll_new["bg"] = "#fff" #print(dir(e_poll_new)) e_poll_new.option_add("end","") #', 'option_clear', 'option_get e_poll_new.option_add("end","215.0.0.0") e_poll_new.pack(side="left") #exit() b_scan = Tkinter.Button(fframe,text="Librelight:",font=font2,relief="flat",bg="orange") b_scan.pack(side="left",expand=0) b_scan = Tkinter.Button(fframe,text="KILL !",command=kill_librelight,width=6,font=font2,bg="red") b_scan.pack(side="left",expand=0) b_scan = Tkinter.Button(fframe,text="START ",command=start_librelight,width=6,font=font2,bg="green") b_scan.pack(side="left",expand=0) scrollbar = Tkinter.Scrollbar(cframe) scrollbar.pack(side=Tkinter.RIGHT, fill="y") #pool = Tkinter.Listbox(root,selectmode="extended",exportselection=0) li_nodes = Tkinter.Listbox(cframe,exportselection=0,width=35,font=font1) li_nodes.pack(side="left",expand=0,fill="y") li_nodes.bind("",fill_form ) li_nodes.config(yscrollcommand=scrollbar.set) scrollbar.config(command=li_nodes.yview) eframe = Tkinter.Frame(cframe) eframe.pack(side="left",expand=0,fill="y") eframe1 = Tkinter.Frame(cframe) eframe1.pack(side="left",expand=0,fill="y") # ---------------------------------------------- line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") x=Tkinter.Label(line_frame,text=" ",font=font2,width=6) c= Tkinter.Label(line_frame,text=" ",font=font1,width=30,anchor="w") c.pack(side="left",expand=0,fill="y") # ---------------------------------------------- # ---------------------------------------------- line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") x=Tkinter.Label(line_frame,text="MSG:",font=font3,width=6) x.pack(side="left",expand=0,fill="y") x.configure(bg="darkgrey") MSG = Tkinter.Label(line_frame,text="xxx",font=font1,width=30,anchor="w") MSG.pack(side="left",expand=0,fill="y") MSG.configure(bg="darkgrey") #msg["bg"] = "lightgrey" #msg.pack(side="left") # ---------------------------------------------- line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") c= Tkinter.Label(line_frame,text=" ",font=font120,width=30,anchor="w") c.pack(side="left",expand=0,fill="y") # ---------------------------------------------- line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="OLD IP:",font=font3,width=6).pack(side="left",expand=0,fill="y") e_ip = Tkinter.Entry(line_frame,font=font20,width=26,state="disabled") e_ip["bg"] = "lightgrey" e_ip.pack(side="left") b_scan = Tkinter.Button(line_frame,text="clean",font=font2,relief="flat",command=clear_form) b_scan.pack(side="left",expand=0) #b_scan = Tkinter.Button(line_frame,width=14,font=font3) #b_scan.pack(side="left",expand=1) # ---------------------------------------------- line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") e_ip_label = Tkinter.Label(line_frame,text=" IP:",font=font3,width=6) e_ip_label.pack(side="left",expand=0,fill="y") e_ip_new = Tkinter.Entry(line_frame,font=font20,width=26) e_ip_new.bind("", set_ip ) e_ip_new.bind("", set_ip) #e_ip_new.bind("", update_name) e_ip_new.bind("", set_ip) e_ip_new.pack(side="left") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") variable = Tkinter.StringVar(root) variable.set("255.0.0.0") # default value Tkinter.Label(line_frame,text="MASK:",font=font3,width=6).pack(side="left",expand=0,fill="y") e_mask_new = Tkinter.OptionMenu(line_frame, variable,"255.255.255.0","255.0.0.0") #,width=10) e_mask_new.configure(font=("Helvetica", 12)) e_mask_new.configure(width=12) e_mask_new["bg"] = "#fff" #heigh=1,font=("Helvetica", 20) e_mask_new.pack(side="left") e=Tkinter.Label(line_frame,text="") e.configure(width=11) e.pack(side="left") #e_mask_new.insert("end","255.0.0.0") #e_mask_new.insert("end","255.255.255.0") b_scan = Tkinter.Button(line_frame,text="SEND TO NODE",command=set_ip,width=14,font=font1) b_scan.pack(side="left",expand=0) #-------------------------------------------- line line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="MAC:",font=font3,width=6).pack(side="left",expand=0,fill="y") e_mac = Tkinter.Entry(line_frame,width=23,font=font20) e_mac.pack(side="left") e_mac["bg"] = "lightgrey" e_mac2 = Tkinter.Entry(line_frame,width=3,font=font20) e_mac2.pack(side="left") e_mac2.bind("", send_mac ) e_mac2.bind("", send_mac) Tkinter.Button(line_frame,text="SEND TO NODE",command=send_mac,width=14,font=font1).pack(side="left",expand=0) # ---------------------------------------------- line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") c= Tkinter.Label(line_frame,text=" ",font=font120,width=30,anchor="w") c.pack(side="left",expand=0,fill="y") # ---------------------------------------------- #-------------------------------------------- line #b_scan = Tkinter.Button(eframe1,width=14,font=font3) #b_scan.pack(side="top",expand=0) line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="DMX:",font=font3,width=6).pack(side="left",expand=0,fill="y") b_set_node_pin = Tkinter.Button(line_frame,text="HW-PIN",command=set_node_pin,width=6,font=font3) b_set_node_pin.pack(side="left",expand=0) b_set_node_in = Tkinter.Button(line_frame,text="IN",command=set_node_in,width=6,font=font3) b_set_node_in.pack(side="left",expand=0) b_set_node_out = Tkinter.Button(line_frame,text="OUT",command=set_node_out,width=6,font=font3) b_set_node_out.pack(side="left",expand=0) #-------------------------------------------- line line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="CMD",font=font3,width=6).pack(side="left",expand=0,fill="y") e_cmd = Tkinter.Entry(line_frame,font=font3,width=26) e_cmd.bind("", send_cmd ) e_cmd.pack(side="left") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="LName",font=font3,width=6).pack(side="left",expand=0,fill="y") e_lname = Tkinter.Entry(line_frame,font=font3,width=26) e_lname.pack(side="left") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="SName",font=font3,width=6).pack(side="left",expand=0,fill="y") e_sname = Tkinter.Entry(line_frame,font=font3,width=26) e_sname.pack(side="left") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="ArtNet",font=font3,width=6).pack(side="left",expand=0,fill="y") Tkinter.Label(line_frame,text="SUB:",font=font3,width=4).pack(side="left",expand=0,fill="y") e_artnet_uni1 = Tkinter.Entry(line_frame,font=font3,width=4,state="disabled") e_artnet_uni1.pack(side="left") Tkinter.Label(line_frame,text="NET:",font=font3,width=4).pack(side="left",expand=0,fill="y") e_artnet_uni1 = Tkinter.Entry(line_frame,font=font3,width=4,state="disabled") e_artnet_uni1.pack(side="left") Tkinter.Label(line_frame,text="UNI:",font=font3,width=4).pack(side="left",expand=0,fill="y") e_artnet_uni1 = Tkinter.Entry(line_frame,font=font3,width=4) e_artnet_uni1.pack(side="left") Tkinter.Button(line_frame,text="send ArtAddr",command=send_artaddr,width=14,font=font1).pack(side="left",expand=0) #-------------------------------------------- line b_scan = Tkinter.Text(eframe,width=20,font=font2) b_scan.pack(side="top",expand=1,fill="x") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe1) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="CMD",font=font3,width=6).pack(side="left",expand=0,fill="y") e_cmd2 = Tkinter.Entry(line_frame,font=font3,width=16) e_cmd2.insert("end","DMX ERASE ") e_cmd2.bind("", send_cmd2 ) e_cmd2.pack(side="left") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe1) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="CMD",font=font3,width=6).pack(side="left",expand=0,fill="y") e_cmd3 = Tkinter.Entry(line_frame,font=font3,width=16) e_cmd3.insert("end","DMX OUT STORE ") e_cmd3.bind("", send_cmd3 ) e_cmd3.pack(side="left") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe1) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="CMD",font=font3,width=6).pack(side="left",expand=0,fill="y") e_cmd4 = Tkinter.Entry(line_frame,font=font3,width=16) e_cmd4.insert("end","DMX OUT SET 2") e_cmd4.bind("", send_cmd4 ) e_cmd4.pack(side="left") #-------------------------------------------- line line_frame = Tkinter.Frame(eframe1) line_frame.pack(side="top",expand=0,fill="x") Tkinter.Label(line_frame,text="CMD",font=font3,width=6).pack(side="left",expand=0,fill="y") e_cmd5 = Tkinter.Entry(line_frame,font=font3,width=16) e_cmd5.insert("end","REBOOT ") e_cmd5.bind("", send_cmd5 ) e_cmd5.pack(side="left") nodescan.bind_cmd_node() def network_listenet(): print(sys._getframe().f_code.co_name) b_scan.insert("end", "log:\n" ) while 1: if nodescan.node_cmd_buf_list: msg = str(nodescan.node_cmd_buf_list) print("read_cmd_buf msg",msg) nodescan.node_cmd_buf_list = [] stamp = str(time.time())+"\n" stamp = time.strftime("%Y-%m-%d %X\n") b_scan.insert("end",stamp) b_scan.insert("end", msg +"\n") b_scan.see("end") time.sleep(0.1) def update_idletask(): print(sys._getframe().f_code.co_name) while 1: time.sleep(1) root.update_idletasks() #print(nodescan.sock) #print(dir(nodescan.sock)) #print(nodescan.sock.getsockopt()) if nodescan.sock.connected == 0: MSG["text"] = "Nodescanner not Connected !" MSG["bg"] = "red" else: MSG["text"] = "" MSG["bg"] = "grey" def main(): print(sys._getframe().f_code.co_name) thread.start_new_thread(scan, () ) thread.start_new_thread(nodescan.node_cmd_recive, () ) thread.start_new_thread(network_listenet, () ) thread.start_new_thread(update_idletask, () ) main() root.mainloop()