浏览代码

add: nodescaner tk-nodescan

micha 2 年之前
父节点
当前提交
365db171cf
共有 2 个文件被更改,包括 1147 次插入0 次删除
  1. 633 0
      tool/nodescan_v6_2.py
  2. 514 0
      tool/tk-nodescan_v7.3.py

+ 633 - 0
tool/nodescan_v6_2.py

@@ -0,0 +1,633 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+This file is part of grandPA.
+
+grandPA is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+grandPA is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with grandPA.  If not, see <http://www.gnu.org/licenses/>.
+
+(c) 2012 micha.rathfelder@gmail.com
+"""
+print("suche ArtNet Nodes ")
+import time
+import socket, struct
+import sys
+import _thread as thread
+import copy
+import random
+
+sys.stdout.write("\x1b]2;Nodescan\x07")
+
+print(socket.AF_INET)
+
+try:
+    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    sock.bind(('', 6454))
+    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+except socket.error as e:
+    print("Socket 6454 ", "ERR: {0} ".format(e.args))
+    sys.exit()
+    
+    
+    
+try:
+    sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    sock2.bind(('', 6455))
+    sock2.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+except socket.error as e:
+    print("Socket2 6454 ", "ERR: {0} ".format(e.args))
+    sys.exit()
+
+
+print(socket.AF_INET)
+sock_cmd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+        
+def bind_cmd_node():
+    global sock_cmd
+    try:
+        sock_cmd.bind(('', 7601)) #7601
+        #sock_cmd.bind(('', 49737))
+        sock_cmd.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+        
+    except socket_cmd.error as e:
+        print("Socket 6454 ", "ERR: {0} ".format(e.args))
+        sys.exit()
+
+if __name__ == "__main__":
+    bind_cmd_node()  
+
+def ArtNet_poll(ip,port=6454):
+    print("POLL",[ip,port],end="")
+    #try:
+    if 1:
+        sock.sendto(b'Art-Net\x00\x00 \x00\x0e\x06\x00',(ip,port)) # ArtPol / ping
+        print(" OK ;",end="")
+        #send_node_cmd(ip=(2,255,255,255),cmd="CMD GT ")
+    #except Exception as e:
+    #    print("Exception ArtNet-POLL",e,)
+
+    print()
+
+    
+    
+def ArtPollReplyDelay():
+    time.sleep(1)
+    ArtPollReply()
+    
+def ArtPollReply():
+    print("ArtPollReply()")
+    
+    port = 6454
+    content = []
+    header = []
+
+    # Name, 7byte + 0x00
+    content.append("Art-Net\x00")
+    # OpCode ArtPollReply -> 0x2100, Low Byte first
+    content.append(struct.pack('<H', 0x2100))
+    # Protocol Version 14, High Byte first
+    content.append(struct.pack('>H', 14))
+    # IP
+    #ip = [int(i) for i in self.own_ip.split('.')]
+    ip = [2, 0, 0, 10]
+    content += [chr(i) for i in ip]
+    # Port
+    content.append(struct.pack('<H', 0x1936))
+    # Firmware Version
+    content.append(struct.pack('>H', 200))
+    # Net and subnet of this node
+    net = 0
+    subnet = 0
+    content.append(chr(net))
+    content.append(chr(subnet))
+    # OEM Code (E:Cue 1x DMX Out)
+    content.append(struct.pack('>H', 0x0360))
+    # UBEA Version -> Nope -> 0
+    content.append(chr(0))
+    # Status1
+    content.append(struct.pack('>H', 0b11010000))
+    # Manufacture ESTA Code
+    content.append('LL')
+    # Short Name
+    content.append('LOOP-OpPollReplay\x00')
+    # Long Name
+    content.append('LOOP-OpPollReplay_ArtNet_Node' + '_' * 34 + '\x00')
+
+    content.append('\x00'*100)
+    # stitch together
+    content = ''.join(content)
+    #print(self.lang['send_ArtPollReply'])
+    #self.s.sendto(content, ("<broadcast>", self.__port))
+    
+    print("send" ,[content])
+    sock.sendto(content, ("<broadcast>", port))
+    sock.sendto(content, ("2.0.0.255", port))
+    sock.sendto(content, ("10.10.10.255", port))
+    sock.sendto(content, ("192.168.2.255", port))
+    #sock.sendto(content, ("2.0.0.255", port))
+    #sock.sendto
+
+def testBounce(ip,port):
+    
+    print(("TESTBOUNCE", (ip, port)))
+    try:
+        sock.sendto("TESTBOUNCE " +ip, (ip, port))
+    except socket.error as e:
+        print("Socket", "ERR: {0} ".format(e.args))
+        print(("TESTBOUNCE", (ip, port)))
+        
+    
+    
+def reciveBounce(timeout=10):
+    start = time.time()
+    while 1:
+        data = sock.recv(500)
+        print("bounce",data)
+        #data, addr = sock.recvfrom(500)
+        if data:
+            #print(addr)
+            
+            print(data)
+            print()
+        if time.time() > start+timeout:
+            print("timeout stopping reciveBounce ")
+            break 
+        
+def poll():
+    port = 6454
+    
+    #ip   = "255.255.255.255"
+    #ArtNet_poll(ip)
+    #ip   = "<broadcast>"
+    #ArtNet_poll(ip)
+    ip   = "192.168.0.255"
+    ArtNet_poll(ip)    
+    ip   = "192.168.0.99"
+    ArtNet_poll(ip)    
+    #ip   = "2.0.0.255"
+    #ArtNet_poll(ip)
+    #ip   = "2.255.255.255"
+    #ArtNet_poll(ip)
+    print("")
+    
+class ArtNetNodes():
+    def __init__(self):
+        print("CONSTRUCKT:",self)
+        self.__nodes = []
+        self.__lock = thread.allocate_lock()
+        self.__tick = 0
+        #self.__lock.acquire()
+        #self.__lock.release()
+    def clear(self):    
+        self.__lock.acquire()
+        self.__nodes = []
+        self.__lock.release()    
+    def add(self,add_node):        
+        #print("ArtNetNodes.add()",add_node)
+        #for i in add_node:
+        #    print(i,[add_node[i]])
+        #print()
+        try:
+            self.__lock.acquire()
+            update_node = 0
+            if "MSG" in add_node and "BOOT" in add_node["MSG"].upper():
+                BOOT = time.time()
+                print("   BOOOOOOOOT")
+            else:
+                BOOT = 0            
+        
+            for node in self.__nodes:
+                info = node["MAC"],node["IP"].ljust(16," "),[node["SwIn"],node["SwOut"],node["PortTypes"]]
+                
+            
+                
+                node_match = 1 
+                keys = ["MAC","SwOut","SwIn","PortTypes"]
+                for i in keys:
+                   if node[i] != add_node[i]:
+                       node_match = 0
+                       break
+                
+                if node_match: # NODE MAC                
+                    update_node = 0
+                    for i in add_node:
+                        UPDATECOUNTER = node["UPDATECOUNTER"]                    
+                            
+                        if node[i] != add_node[i]:
+                            node_match = 0
+                            update_node += 1
+                            node[i] = add_node[i]
+                            UPDATECOUNTER +=1
+                            self.__tick += 1
+                            #break
+                            
+                    if update_node:
+                        node["UPDATECOUNTER"] = UPDATECOUNTER
+                        node["UPDATESTAMP"] = time.time()
+                        node["REFRESHSTAMP"] = time.time()
+                        if BOOT:
+                            node["BOOT"] = BOOT
+                            
+                        print("UPDATE NODE".ljust(16," "),info)
+                        
+                    else:
+                        print("NODE NOT CHANGE".ljust(16," "),info)
+                        node["REFRESHSTAMP"] = time.time()
+                        update_node = 1
+                            
+            if not update_node: # ADD NEW NODE
+                
+                node = add_node
+                node["BOOT"] = BOOT
+                info = node["MAC"],node["IP"].ljust(16," "),[node["SwIn"],node["SwOut"],node["PortTypes"]]
+                
+                node["UPDATECOUNTER"] = 1
+                node["REFRESHSTAMP"] = time.time()
+                node["UPDATESTAMP"] = time.time()
+                print("ADD NEW NODE".ljust(16," "),node["UPDATECOUNTER"],info)
+                self.__tick += 1
+                self.__nodes += [node]
+                  
+            
+        finally:
+            #print("release lock")
+            self.__lock.release()
+    def tick(self):
+        self.__lock.acquire()
+        x = self.__tick
+        self.__lock.release()
+        return x
+        return random.randint(0,1000)
+        
+    def get(self):
+        self.__lock.acquire()
+        out = []
+        if self.__nodes:
+            out = copy.deepcopy(self.__nodes)                
+        self.__lock.release()
+        return out    
+    def recive(self):
+        print("-- NODE SCAN START ---")
+        print()
+        while 1:
+            data, addr = sock.recvfrom(500)
+            new_node = ArtNet_decode_pollreplay( data )            
+            if new_node:
+                #print(new_node)
+                self.add(new_node)
+            time.sleep(0.001)
+        print("-- NODE SCAN STOP ---")
+        print()
+        
+    def loop(self):
+        thread.start_new_thread(self.recive, () )
+        time.sleep(1)
+        poll()
+        
+Reciver = ArtNetNodes
+    
+
+def ArtNet_decode_pollreplay(data):
+    debug = 0
+    node = {}
+    if len(data) >= 10: #min opcode
+    
+        opcode = data[8:9+1]
+        #print([opcode])
+        #if opcode != struct.pack("<H",0x5000): #OpPollReplay
+        if opcode == struct.pack("<H",0x2100): #OpPollReplay
+            if len(data) >= 207: #Mal
+            
+                if debug:print("-----------------------------------------")
+                if debug:print([opcode] ,"OpPollReplay")
+                _ip = []
+                _ip.append( ord(data[10]) )
+                _ip.append( ord(data[11]) )
+                _ip.append( ord(data[12]) )
+                _ip.append( ord(data[13]) )
+                node["IP"] = str(_ip)
+                
+                if debug:print([_ip])
+                _port = struct.unpack("<H",data[14:15+1] )
+                #Versinfo = struct.unpack("<H",data[16:17+1] )
+                Versinfo = data[16:17+1] 
+                node["port"] = _port
+                if debug:print("_port :", [_port ])
+                
+                node["version"] = Versinfo
+                if debug:print("Version:",[Versinfo])
+                
+                NetSwitch = data[18] 
+                node["NetSwitch"] = NetSwitch
+                if debug:print("NetSwitch:",[NetSwitch])
+                SubSwitch = data[19] 
+                node["SubSwitch"] = SubSwitch
+                if debug:print("SubSwitch:",[SubSwitch])
+                
+                #oem = struct.unpack("<H",data[19:20+1] )
+                oem = data[20:21+1]
+                node["oem"] = oem
+                if debug:print("oem",[oem])
+                
+                ubea = data[22]
+                node["ubea"] = ubea
+                if debug:print("ubea ver.",[ubea])
+                stat = data[23]
+                node["status"] = stat
+                if debug:print("Status1 ",[stat])
+                esta = data[24:25+1]
+                node["esta"] = esta
+                if debug:print("esta Manuf",[esta])
+                
+                
+                sname = data[26:26+17]
+                #if debug:print(len(sname) #17+1)
+                sname = sname.strip("\x00")
+                node["sname"] = sname
+                
+                lname = data[44:44+43]
+                #if debug:print(len(lname) #43+1)
+                lname = lname.strip("\x00")
+                node["lname"] = lname
+                
+                NodeReport = data[108:108+20]
+                NodeReport = NodeReport.strip("\x00")
+                #if debug:print("Node",node_nr,addr)
+                if debug:print([sname,lname,NodeReport])
+                
+                NumPort = ord( data[173]) 
+                node["NumPort"] = NumPort
+                if debug:print("NumPort",[NumPort])
+                
+                PortTypes = data[174:174+4]
+                node["PortTypes"] = PortTypes
+                if debug:print("PortTypes",[PortTypes])
+                
+                GoodInput = data[178:178+4]
+                node["GoodInput"] = GoodInput
+                if debug:print("GoodInput",[GoodInput])
+                GoodOutput = data[182:182+4]
+                node["GoodOutput"] = GoodOutput
+                if debug:print("GoodOutput",[GoodOutput])
+                
+                SwIn = data[186:186+4]
+                node["SwIn"] = SwIn
+                if debug:print("SwIn",[SwIn])
+                
+                SwOut = data[190:190+4]
+                node["SwOut"] = SwOut
+                if debug:print("SwOut",[SwOut])
+                
+                msg = data[108:108+40]
+                node["MSG"] = msg.replace("\x00","")
+                if debug:print("MSG",[msg])
+                
+                
+                MAC = data[201:201+6]
+                _MAC = []
+                for x in MAC:
+                    x = hex(ord(x))[2:]
+                    x = x.rjust(2,"0")
+                    _MAC.append(x)
+                #hex(ord("\xf9"))[2:]
+                if debug:print("MAC",[":".join(_MAC)])
+                node["MAC"] = ":".join(_MAC)
+                
+                #node_nr += 1
+                #if debug:print([addr,data])
+                #print()
+            else:
+                print(opcode, len(data))
+    return node
+
+def set_ip4(cur_ip=(2,0,0,91),new_ip=(2,0,0,201),new_netmask=(255,0,0,0)):
+    
+    #send ip
+    port = 7600
+    
+    #print(ip)
+    data = []
+    #New ip
+    #_ip = [192, 168,   2,  91]
+    _ip = [  2,   0,  0, 181] # CLASS C NET
+    _ip = [  2,   0,  0, 101] # CLASS C NET
+    #_ip = [192, 168,  0,  91]
+    _ip = new_ip
+    
+    print("NEW NODE _ip:", _ip)
+    data.append(struct.pack('<B', _ip[0]))
+    data.append(struct.pack('<B', _ip[1]))
+    data.append(struct.pack('<B', _ip[2]))
+    data.append(struct.pack('<B', _ip[3]))
+
+    #_ip = [255, 255, 255, 255] # cange all nodes in Network to the same _ip ! DANGER !
+    #_ip = [002, 000, 000, 255] # cange all nodes in subnet to the same _ip ! DANGER !
+    _ip = [  2,   0,   0, 199]  # CLASS A NET
+    _ip = [192, 168,   0,  91]
+    #_ip = [  2,   0,  0, 191] # CLASS C NET
+    _ip = cur_ip
+    
+    print("OLD NODE _ip:", _ip)
+    #OLD _ip , Target Node to change
+    data.append(struct.pack('<B', _ip[0]))
+    data.append(struct.pack('<B', _ip[1]))
+    data.append(struct.pack('<B', _ip[2]))
+    data.append(struct.pack('<B', _ip[3]))
+    
+    ip = ".".join(str(x) for x in _ip)
+    #print("send to ip:", ip)
+    
+        
+    # NETMASK
+    MASK = []
+    netmask = [255, 255, 255 ,  0] #fast CLASS C funktioniert
+    #netmask = [255, 0, 0 ,  0]  #CLASS C funkioniert nicht
+    netmask = new_netmask
+    print("NEW NODE net:",netmask)
+    MASK.append(struct.pack('<B', netmask[0]))
+    MASK.append(struct.pack('<B', netmask[1]))
+    MASK.append(struct.pack('<B', netmask[2]))
+    MASK.append(struct.pack('<B', netmask[3]))
+    
+    data += MASK
+    data += [struct.pack('<B', 255)]*11 
+    
+    
+    print("------------------------------")
+    data = 'CMD IP '+ "".join(data)
+    
+    print("SENDING TO ",(ip,port))
+    print([data]) #,    cur_ip=(2,0,0,91))
+        
+    #sock.sendto(data ,(ip,port))
+    sock.sendto(data ,(ip,port))
+
+
+def send_cmd(ip=(2,0,0,91),cmd=""):
+    node_nr = 1
+    port = 7600
+    
+    print(ip)
+    data = []
+    
+    _ip = [  2,   0,  0, 91] # CLASS C NET
+    
+    
+    print("NEW NODE _ip:", _ip)
+    data.append(struct.pack('<B', _ip[0]))
+    data.append(struct.pack('<B', _ip[1]))
+    data.append(struct.pack('<B', _ip[2]))
+    data.append(struct.pack('<B', _ip[3]))
+
+    #_ip = [255, 255, 255, 255] # cange all nodes in Network to the same _ip ! DANGER !
+    #_ip = [002, 000, 000, 255] # cange all nodes in subnet to the same _ip ! DANGER !
+    _ip = [  2,   0,   0, 199]  # CLASS A NET
+    _ip = [  2,   0,   0, 91]  # CLASS A NET
+    #_ip = [192, 168,   0,  91]
+    _ip = [  2,   0,  0, 255] # CLASS C NET
+    _ip = [  2,   255,  255, 255] # CLASS C NET
+    
+    print("OLD NODE _ip:", _ip)
+    #OLD _ip , Target Node to change
+    data.append(struct.pack('<B', _ip[0]))
+    data.append(struct.pack('<B', _ip[1]))
+    data.append(struct.pack('<B', _ip[2]))
+    data.append(struct.pack('<B', _ip[3]))
+    
+    ip = ".".join(str(x) for x in ip)
+    print("send to ip:", ip)
+    
+        
+    # NETMASK
+    MASK = []
+    netmask = [255, 255, 255 ,  0] #fast CLASS C funktioniert
+    netmask = [255, 0, 0 ,  0]  #CLASS C funkioniert nicht
+    print("NEW NODE net:",netmask)
+    MASK.append(struct.pack('<B', netmask[0]))
+    MASK.append(struct.pack('<B', netmask[1]))
+    MASK.append(struct.pack('<B', netmask[2]))
+    MASK.append(struct.pack('<B', netmask[3]))
+    
+    data += MASK
+    data += [struct.pack('<B', 255)]*11 
+    print("------------------------------")
+    data = 'CMD '+cmd+' '+ "".join(data)
+    
+    print("SENDING TO ",(ip,port))
+    print([data]    )
+        
+    #sock.sendto(data ,(ip,port))
+    sock.sendto(data ,(ip,port))
+
+
+
+def send_node_cmd(ip="",cmd=""):
+    node_nr = 1
+    port = 7600
+    if not ip:
+        ip = (2,255,255,255)
+    data = []
+    _ip = ip #[2, 0, 0 ,  91]  #CLASS C funkioniert nicht
+    
+    print("OLD NODE _ip:", _ip)
+    #OLD _ip , Target Node to change
+    data.append(struct.pack('<B', int(_ip[0])))
+    data.append(struct.pack('<B', int(_ip[1])))
+    data.append(struct.pack('<B', int(_ip[2])))
+    data.append(struct.pack('<B', int(_ip[3])))
+    
+    ip = ""
+    ip = ".".join(str(x) for x in _ip)
+    print("send to ip:", ip)
+    data2=""
+    if not cmd:
+        data2 = 'CMD GT'
+        #data2 = 'CMD ST'
+        #data2 = 'DMX OUT STORE'
+        data2 = 'CMD  DMX=IN '
+        #data2 = 'CMD DMX=IN '
+        data2 = 'CMD DMX=OUT '
+        data2 = 'CMD DMX=PIN '
+    else:
+        pass#data2 = str(cmd)
+    if type(data2) is str:
+        data2 = bytes(data2,"ascii")
+    print([data2],type(data2)    )
+    data2 = data2.ljust(20,b" ") + b"".join(data)
+    print("SENDING COMMAND TO ",(ip,port))
+    print([data2],type(data2)    )
+        
+    sock.sendto(data2 ,(ip,port))
+    #sock.sendto(bytes(data2,"ascii") ,(ip,port))
+    
+
+node_cmd_buf_list = []
+    
+def node_cmd_recive():
+    global node_cmd_buf_list
+    #sock.sendto('\x00\x00\x00\x00\x00',(ip,port)) # ArtPol / ping
+    while 1:
+        data, addr = sock_cmd.recvfrom(5000)
+        #print(len(data))
+        #print([addr,data])
+        if len(data) == 207:
+            print()
+        else:
+            print("NODE CMD RESPONSE:", [addr,data])
+            node_cmd_buf_list = [addr,data]
+        
+            #print([data])
+            pass
+        time.sleep(0.05)
+
+
+
+
+
+#send_node_cmd(ip="",cmd="CMD DMX=IN")
+#send_node_cmd(ip="",cmd="CMD DMX=OUT")
+#send_node_cmd(ip=(2,0,0,91),cmd="CMD DMX=PIN")
+#send_node_cmd(ip=(2,0,0,91),cmd="DMX OUT STORE")
+#   
+if __name__ == "__main__":        
+
+    thread.start_new_thread(node_cmd_recive, () )
+    #send_node_cmd(ip=(2,0,0,91),cmd="DMX OUT STORE")
+    send_node_cmd(ip=(2,255,255,255),cmd="CMD GT ")
+   
+
+    rx = ArtNetNodes()
+    rx.loop()
+    z = 0
+    while 1:
+        
+        nodes = rx.get()
+        #print(len(nodes))
+        
+        if z % 10 == 0:
+            print()
+            pass
+            
+        
+            print("node count",len(nodes))
+            #for i in nodes:
+            #print(i)
+        z += 1
+        time.sleep(0.2)
+        
+    print()
+    print("time out")
+    raw_input("ENDE")
+
+

+ 514 - 0
tool/tk-nodescan_v7.3.py

@@ -0,0 +1,514 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+This file is part of librelight.
+
+librelight is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+librelight is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with librelight.  If not, see <http://www.gnu.org/licenses/>.
+
+(c) 2012 micha.rathfelder@gmail.com
+"""
+
+import time
+import tkinter as Tkinter
+import sys
+import _thread as thread
+import nodescan_v6_2 as nodscaner 
+import struct
+
+title = "TK-ArtNet-Nodscaner"
+sys.stdout.write("\x1b]2;"+title+"\x07")
+
+node_list = []
+def load(event):
+    sel = int( li_nodes.curselection()[0] )
+    print("li_nodes.get")
+    try:
+        sel = int(li_nodes.get(sel).split()[0])
+        print(sel)
+    except:
+        return 0
+    sel -= 1
+    node_list[sel]
+    clear_entry_ip()
+    
+    e_ip.configure(state='normal')
+    e_ip.insert("end",node_list[sel]["IP"].replace("[","").replace("]",""))
+    #e_ip.configure(state='readonly')
+    
+    e_ip_new.insert("end",node_list[sel]["IP"].replace("[","").replace("]",""))
+    e_mac.delete("0","end")
+    e_mac.insert("end",node_list[sel]["MAC"].replace("[","").replace("]",""))
+    e_mac2.delete("0","end")
+    e_mac2.insert("end",node_list[sel]["MAC"].split(":")[-1])
+    
+    
+    #print(dir(event))
+    #print(node_list)
+    #for i in node_list:
+    #    print(i)
+    
+def clear_entry_ip():
+    e_ip.configure(state='normal')
+    e_ip.delete("0","end")
+    e_ip.configure(state='readonly')
+    e_ip_new.delete("0","end")
+
+    
+def clear_node():
+    global node_list
+    li_nodes.delete("0","end")
+    node_list = []
+    li_nodes.delete("0","end")
+
+    
+def poll(delay=1):
+    global old_tick
+    
+    #clear_entry_ip()
+    clear_node()
+    time.sleep(delay)
+    nodscaner.poll()
+    time.sleep(0.5)
+    old_tick = 0
+    
+def clear(event= None):
+    global rx
+    rx.clear()
+    poll()
+    
+def poll_loop(sleep):
+    if sleep < 1:
+        sleep = 1
+    time.sleep(sleep)
+    while 1:
+        poll()
+        time.sleep(sleep)
+
+old_tick = 0
+rx = nodscaner.ArtNetNodes()
+        
+def _scan():
+    global rx,node_list,old_tick,Scrollbar
+    
+    rx.loop()
+    print("get node from cache "    )
+    li_nodes.insert("end",str("----"))
+    while 1:
+        nodes = rx.get()
+        new_tick = rx.tick()
+        #print("tick",new_tick)
+        if new_tick == old_tick:
+            pass
+            continue
+        old_tick = new_tick
+        print("node",nodes)
+        if nodes:
+            li_node_scroll = li_nodes.yview()
+            
+            clear_node()
+
+            #li_nodes.delete(0,"end")
+            print("yea",len(nodes))
+            node_nr = 1
+            for node in nodes:
+                #print(node)
+                #try:
+                li_nodes.insert("end",str(node_nr).rjust(3," ") +" "+ node["lname"])
+                ip = str(node_nr).rjust(3," ") +" "+ node["IP"]
+                bg = ""
+                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])+1)+" IN="+ str(ord(node["SwIn"][0])+1)
+                li_nodes.insert("end",str(node_nr).rjust(3," ") + inout)
+                
+                li_nodes.insert("end",str(node_nr).rjust(3," ") +" "+ node["MAC"])
+                
+                timeline = ""
+                timeline += " LASTCHANGE:%0.1f"% (time.time()-float(node["UPDATESTAMP"]) )
+                REFRESHSTAMP = time.time()-float(node["REFRESHSTAMP"])
+                timeline +="  LASTPING:%0.1f"% REFRESHSTAMP 
+                li_nodes.insert("end",str(node_nr).rjust(3," ") +timeline )
+                
+                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 REFRESHSTAMP > 5 :
+                    bg="red"
+                else:
+                    bg="lightgreen"
+                if bg:
+                    li_nodes.itemconfig("end", bg=bg)
+                #li_nodes.insert("end",str(node_nr).rjust(3," ") 
+                #li_nodes.insert("end","")
+                li_nodes.insert("end","*"*60)
+                #li_nodes.itemconfig("end", bg="brown")
+                node_nr += 1
+                node_list += [node]
+            
+            #Scrollbar.set('0', '0.1')
+            print(li_node_scroll)
+            #print(dir(li_nodes))
+            #li_node_scroll = int(li_node_scroll[0])
+            #li_nodes.yview_moveto(li_node_scroll)
+            
+        time.sleep(0.2)
+    
+def scan():
+    thread.start_new_thread(_scan, () )
+
+def get_new_ip(event=None):
+    b = e_ip_new.get().replace("[","").replace("]","")
+    return b
+def get_new_ip_str(event=None):
+    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_none(event=None):
+    pass
+    
+def send_mac(event=None):
+    new_mac = "CMD MAC6 " + struct.pack("<B",(int(e_mac2.get(),16)))
+    
+    a = e_ip.get().replace("[","").replace("]","")
+    cur_ip = []    
+    for i in a.split(","):
+        cur_ip +=[int(i)]
+    print("SEND MAC:",cur_ip,new_mac)
+    nodscaner.send_node_cmd(cur_ip,new_mac)
+    poll(1.5)
+
+def send_dmx_store(event=None):
+    cmd = "CMD DMX STORE "
+    
+    a = e_ip.get().replace("[","").replace("]","")
+    cur_ip = []    
+    for i in a.split(","):
+        cur_ip +=[int(i)]
+    print("SEND:",cur_ip,cmd)
+    nodscaner.send_node_cmd(cur_ip,cmd)
+    poll(1.5)
+
+def send_cmd(event=None):
+    cmd = e_cmd.get() #"CMD DMX STORE "
+    _send_cmd(cmd=cmd)
+def send_cmd2(event=None):
+    cmd = e_cmd2.get() #"CMD DMX STORE "
+    _send_cmd(cmd=cmd)
+def send_cmd3(event=None):
+    cmd = e_cmd3.get() #"CMD DMX STORE "
+    _send_cmd(cmd=cmd)
+def send_cmd4(event=None):
+    cmd = e_cmd4.get() #"CMD DMX STORE "
+    _send_cmd(cmd=cmd)
+def send_cmd5(event=None):
+    cmd = e_cmd5.get() #"CMD DMX STORE "
+    _send_cmd(cmd=cmd)
+
+    
+def _send_cmd(event=None,cmd=""):
+    #cmd = e_cmd.get() #"CMD DMX STORE "
+    cmd = cmd.split(" ")
+    value = cmd[-1]
+    try:
+        value = struct.pack("<B",int(value))
+    except:pass
+    cmd = cmd[:-1] #.append(value)
+    cmd.append(value)
+    print("ERRRRR",cmd)
+    cmd=" ".join(cmd )
+    a = e_ip.get().replace("[","").replace("]","")
+    cur_ip = []    
+    for i in a.split(","):
+        cur_ip +=[int(i)]
+    print("SEND:",cur_ip,cmd)
+    nodscaner.send_node_cmd(cur_ip,cmd)
+    poll(1.5)
+
+    
+def set_ip(event=None):
+    print("SET NEW IP")
+
+    cur_ip=(2,0,0,94)
+    new_ip=(2,0,0,201)
+    new_netmask=(255,0,0,0)
+    
+    a = e_ip.get().replace("[","").replace("]","")
+    b = e_ip_new.get().replace("[","").replace("]","")
+    c = variable.get() #e_mask_new.get()
+    new_netmask = [] #c.split(".") #list(c)
+    for i in c.split("."):
+        new_netmask +=[int(i)]
+    cur_ip = []    
+    for i in a.split(","):
+        cur_ip +=[int(i)]
+    new_ip = []
+    for i in b.split(","):
+        new_ip +=[int(i)]
+        
+    if new_ip == cur_ip:
+        print("neu und als IP sind gleich"  )
+        return 0
+    #cur_ip=(2,0,0,94)
+    #new_ip=(2,0,0,201)
+    
+    print("new",[cur_ip, new_ip, new_netmask])
+    print()
+    nodscaner.set_ip4(cur_ip,new_ip, new_netmask)
+    poll(1.5)
+    
+def set_node_pin(evnet=None):
+    cmd = "CMD DMX=PIN"
+    ip = get_new_ip_str()
+    print("ip",[ip])
+    nodscaner.send_node_cmd(ip,cmd=cmd)
+    poll(1.5)
+    
+def set_node_in(evnet=None):
+    cmd="CMD DMX=IN"
+    ip = get_new_ip_str()
+    nodscaner.send_node_cmd(ip,cmd=cmd)
+    poll(1.5)
+    
+def set_node_out(evnet=None):
+    cmd="CMD DMX=OUT"
+    ip = get_new_ip_str()
+    nodscaner.send_node_cmd(ip,cmd=cmd)
+    poll(1.5)
+
+
+    
+root = Tkinter.Tk()
+#root.geometry("900x700+100+100")
+root.geometry("900x400+100+100")
+root.title( title)
+fframe = Tkinter.Frame(root)
+fframe.pack(side="top",expand=0,fill="x")
+cframe = Tkinter.Frame(root)
+cframe.pack(side="top",expand=1,fill="both")
+
+font1 = ("Helvetica", 8)
+font2 = ("Helvetica", 10)
+font3 = ("Helvetica", 16)
+font20 = font=("Helvetica", 20)
+
+b_scan = Tkinter.Button(fframe,text="ArtNetPoll",width=10,command=poll,font=font2)
+b_scan.pack(side="left",expand=0,fill="y")
+b_scan = Tkinter.Button(fframe,text="clear",width=10,command=clear,font=font2)
+b_scan.pack(side="left",expand=0,fill="y")
+
+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("<ButtonRelease-1>",load )
+
+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")
+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)
+e_ip.pack(side="left")
+#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)
+e_ip_new.bind("<Return>", set_ip )
+e_ip_new.bind("<KP_Enter>", set_ip)
+#e_ip_new.bind("<Tab>", update_name)
+e_ip_new.bind("<ISO_Left_Tab>", 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="IPMASK",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")
+e_mask_new.configure(font=("Helvetica", 20))
+e_mask_new.configure(width=17)
+#heigh=1,font=("Helvetica", 20)
+e_mask_new.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=16,font=font20)
+e_mac.pack(side="left")
+e_mac2 = Tkinter.Entry(line_frame,width=3,font=font20)
+e_mac2.pack(side="left")
+e_mac2.bind("<Return>", send_mac )
+e_mac2.bind("<KP_Enter>", send_mac)
+Tkinter.Button(line_frame,text="SEND TO NODE",command=send_mac,width=14,font=font1).pack(side="left",expand=0)
+#-------------------------------------------- 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=16)
+e_cmd.bind("<Return>", 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="L-Name",font=font3,width=6).pack(side="left",expand=0,fill="y")
+e_lname = Tkinter.Entry(line_frame,font=font3,width=10)
+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="S-Name",font=font3,width=6).pack(side="left",expand=0,fill="y")
+e_sname = Tkinter.Entry(line_frame,font=font3,width=10)
+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)
+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)
+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 TO NODE",command=send_none,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("<Return>", 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("<Return>", 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("<Return>", 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("<Return>", send_cmd5 )
+e_cmd5.pack(side="left")
+
+
+#poll_loop(1)
+#thread.start_new_thread(poll_loop,(1,))
+scan()
+nodscaner.bind_cmd_node()
+def read_cmd_buf():
+    b_scan.insert("end", "buf read\n" )
+    while 1:
+        if nodscaner.node_cmd_buf_list:
+            msg = str(nodscaner.node_cmd_buf_list)
+            nodscaner.node_cmd_buf_list = []
+            b_scan.insert("end",str(time.time())+"\n")
+            b_scan.insert("end", msg +"\n")
+            
+            b_scan.see("end")
+        time.sleep(0.1)
+thread.start_new_thread(nodscaner.node_cmd_recive, () )
+thread.start_new_thread(read_cmd_buf, () )
+root.mainloop()