#! /usr/bin/env python3 # -*- coding: utf-8 -*- #from __future__ import absolute_import, division, print_function #from builtins import str, open, range, dict #from builtins import * """ 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, version 2 of the License. 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 . (c) 2012 micha@uxsrv.de """ import sys if sys.version_info.major <= 2: print("exit Python3 is needet") sys.exit() fn ="xx" sys.stdout.write("\x1b]2;"+str(fn)+"\x07") # terminal title if "__file__" in dir(): fn = __file__ if "/" in fn: fn = fn.split("/")[-1] sys.stdout.write("\x1b]2;"+str(fn)+" Beta 22.01"+"\x07") # terminal title else: sys.stdout.write("\x1b]2;"+str("__file__")+"\x07") # terminal title import string import time import os import json from optparse import OptionParser parser = OptionParser() parser.add_option("-r", "--recive", dest="recive", help="set recive ip like --recive 10.") parser.add_option("-s", "--sendto", dest="sendto", help="set sender ip like --sendto 2.255.255.255") parser.add_option("-t", "--test", dest="testuniv", help="set test univers like --test [0-16]") parser.add_option("", "--inmap", dest="inmap", help="set test univers like --test [0-16]") #parser.add_option("-q", "--quiet", # action="store_false", dest="verbose", default=True, # help="don't print status messages to stdout") (options, args) = parser.parse_args() print("option",options) print(options.sendto) cython = 0 if cython: if " arm" in os.popen("uname -a").read(): import cy.ArtNetProcessor_cy_pi as cy else: import cy.ArtNetProcessor_cy as cy from collections import OrderedDict from datetime import datetime #print(dir()) #input() # ============================================================ # memcach ========================================= # ============================================================ mc = None try: import memcache mc = memcache.Client(['127.0.0.1:11211'], debug=0) mc.set("dmx-1", [1]*512) except Exception as e: print("Exception",e) def memcachd_index_clear(): _index = {} try: mc.set("index",_index) except Exception as e: print("memcach exception",e) memcachd_index_clear() def update_memcachd_index(key,val="",active=-1): try: _index = mc.get("index") #print("A",_index) if type(_index) is type(None): _index = {} #print("A",_index) if key not in _index: _index[key] = [0,-33] _index[key][0] += 1 _index[key][1] = active mc.set("index",_index) except Exception as e: print("memcach exception",e) if mc: INDEX="index-artpoll" mc.set(INDEX ,{}) def update_mc_artpoll_index(key,val=""): try: INDEX="index-artpoll" _index = mc.get(INDEX) #print("A",_index) if type(_index) is type(None): _index = {} #print("A",_index) #now = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') if key not in _index: _index[key] = [0,""] _index[key][0] += 1 _index[key][1] = now #val mc.set(INDEX ,_index) except Exception as e: print("memcach exception",e) def count_active_dmx_ch(dmx): active = 0 for i,v in enumerate(dmx): if type(v) is int and v>=1: if active < 0: active = 0 active += 1 return active # ============================================================ # Text Grafik Curses ========================================= # ============================================================ import curses class CursesDummy(): def __init__(self): self.sel_host=Pager() self.sel_host.wrap=1 self.sel_univ=Pager() self.sel_univ.wrap=1 self.sel_mode=Pager() self.sel_mode.wrap=1 pass def dir(self): pass def test(self): pass def init(self): pass def addstr(self,x,y,txt): pass def draw_lines(self,lines): pass def inp(self): return "" pass def read(self): pass def clear(self): pass def exit(self): pass class Window(): def __init__(self): self.myscreen = curses.initscr() #print( dir(self.myscreen)) #print( self.myscreen.getmaxyx() ) self._inp="" self.cmd = [] self.sel_host=Pager() self.sel_host.wrap=1 self.sel_univ=Pager() self.sel_univ.wrap=1 self.sel_mode=Pager() self.sel_mode.wrap=1 self.mode="dmx" if options.sendto: self.sel_mode.data = ["stop","stop","ltp","dmx","mtx","main"] # mtx = matrix self.sel_mode.maxindex = len( self.sel_mode.data )-1 self.mode="stop" #self.sel_mode.set(1) #stop #self.sel_mode.prev() #stop #self.sel_mode.prev() #stop #self.sel_mode.prev() #stop self.sel_mode.prev() #stop else: self.sel_mode.data = ["dmx","mtx","main"] # mtx = matrix self.sel_mode.maxindex = len( self.sel_mode.data )-1 self.mode = self.sel_mode.get() self.ttime = time.time() self.univ2 = 0 self.host ="" self.ohost = HostBuffer() # as default self.ohost.update(host="Win-"+str(options.sendto),univ=0,dmxframe=[0]*512) # dummy input self.__reinit_time = time.time() def dir(self): return dir(self.myscreen) def test(self): self.init() #self.loop() self.draw_lines(["a","b","c"]) try: time.sleep(10) finally: self.exit() def reinit(self): self.exit() print( "reinit",time.time()) self.myscreen = curses.initscr() #time.sleep(5) #self.__init() self.init() self.__reinit_time = time.time() def init(self): curses.savetty() curses.noecho() curses.cbreak() curses.noqiflush() #? curses.noraw() #? self.clear() curses.beep() frame = 10 i = 0 def addstr(self,x,y,txt): self.myscreen.addstr(x, y, txt ) #zeile,spalte,text def draw_lines(self,lines): self.clear() try: x,y= self.myscreen.getmaxyx() for i,l in enumerate(lines): #print(i,l) if i >= x-2: break self.myscreen.addstr(i+1, 1, l ) #zeile,spalte,text if i >= self.myscreen.getmaxyx()[0]-2: self.myscreen.addstr(i+1, 1, "..." ) #zeile,spalte,text self.myscreen.refresh() self.myscreen.resize(x-1,y-1) # to prevent slowdown.. self.myscreen.resize(x,y) if self.__reinit_time+60 < time.time(): self.reinit() except KeyboardInterrupt as e: self.exit() print("KeyboardInterrupt") raise e #except Exception as e: # self.exit() # raise e def inp(self): x= self._inp self._inp="" return x def read(self): self.myscreen.nodelay(1) try: self._inp=self.myscreen.getkey() if not self._inp: self._inp = self.myscreen.getch() self.myscreen.addstr(0, 1, str(self._inp) ) #zeile,spalte,text self.myscreen.refresh() return self._inp except: pass#self._inp="" def clear(self): self.myscreen.clear() self.myscreen.border(0) curses.nocbreak(); self.myscreen.keypad(0); #self.read() curses.echo() curses.resetty() #self.myscreen.addstr(10, 2, x ) #zeile,spalte,text def exit(self): self.clear() curses.endwin() print("ENDE",self) def keyread(self): #continue # input command buffer self.read() inp2=self.inp() x="" if "q" == inp2: inp2="" self.exit() sys.exit() elif "?" == inp2: self.mode = "?" elif "," == inp2: x=self.sel_mode.next() self.ttime = time.time()-2 inp2="" elif ";" == inp2: x=self.sel_mode.prev() self.ttime = time.time()-2 inp2="" elif "." == inp2: x=self.sel_univ.next() self.ttime = time.time()-2 inp2="" elif ":" == inp2: x=self.sel_univ.prev() self.ttime = time.time()-2 inp2="" elif "-" == inp2: x=self.sel_host.next() self.ttime = time.time()-2 inp2="" elif "_" == inp2: x=self.sel_host.prev() self.ttime = time.time()-2 inp2="" elif "#" == inp2: if "main" in self.sel_mode.data: x = self.sel_mode.data.index( "main") self.sel_mode.index = x self.sel_mode.check() self.ttime = time.time()-2 inp2="" if x: self.myscreen.addstr(0, 6,str(x) ) if inp2 == "\n": cmd2 = "".join( self.cmd).split() self.cmd=[] if len(cmd2) < 2: pass elif "C^" in cmd2: screen.exit() sys.exit() elif "univ" in cmd2 or "u" == cmd2[0]: x="" if cmd2[1] in sel_univ.data: x = sel_univ.data.index( cmd2[1]) sel_univ.index = x sel_univ.check() elif "mode" in cmd2 or "m" == cmd2[0]: if cmd2[1] in self.sel_mode.data: x = self.sel_mode.data.index( cmd2[1]) self.sel_mode.index = x self.sel_mode.check() elif "host" in cmd2 or "h" == cmd2[0]: try: x=int(cmd2[1]) self.sel_host.set(x) except: pass else: self.cmd.append(inp2) def loop(self): self.keyread() #print( "LOOP") host = self.sel_host.get() univ2 = self.sel_univ.get() #if type(univ2) is list: # univ2.sort() self.mode = self.sel_mode.get() if self.mode == "stop": if self.ttime+5 < time.time(): self.ttime = time.time() self.draw_lines( ["STOP",str(time.time())] ) #self.exit() #print( ["STOP",str(time.time())] ) return if time.time()-0.12 > self.ttime: #if 1: lines = [ ] #print("cmd:",cmd) lines.append(" host:"+ hostname +":"+netns+" CMD:" + "".join(self.cmd) ) if self.mode=="help" or self.mode=="?": lines.append("HILFE[h]: " ) lines.append("MODE [m]: inp, in2 in1 " ) lines.append("UNIV [u]: 0-16 " ) lines.append(" " ) lines.append("HILFE " ) elif self.mode=="dmx" or self.mode == "DMX": self.ttime = time.time() dmx=self.ohost.get(host,univ=univ2)#univ=head_uni) info=self.ohost.info() #lines.append("frame "+str(info.keys()) ) if univ2 in info: if host in info[univ2] : lines.append("frame "+str(info[univ2][host]["frame"])) x="" for i,v in enumerate(dmx): if v == 0: v = "+" x += str(v).rjust(4," ") #if (i+1) % 21 == 0:# and i: if (i+1) % 20 == 0:# and i: lines.append(x) x="" if x: lines.append(x) lines.append(" ") lines.append(str(self.ttime)) #screen.draw_lines(lines) elif self.mode=="stop": return 0 elif self.mode=="mtx": self.ttime = time.time() dmx=self.ohost.get_mtx(host,univ=univ2)#univ=head_uni) info=self.ohost.info() #lines.append("frame "+str(info.keys()) ) if univ2 in info: if host in info[univ2] : lines.append("frame "+str(info[univ2][host]["frame"])) x="" for i,v in enumerate(dmx): x += str(v).rjust(4," ") if (i+1) % 20 == 0:# and i: lines.append(x) x="" if x: lines.append(x) lines.append(" ") lines.append(str(self.ttime)) #screen.draw_lines(lines) elif self.mode=="ltp" or self.mode=="LTP": self.ttime = time.time() dmx=self.ohost.get(univ=univ2)#head_uni) #univ2="" host="" info=self.ohost.info() lines.append("frame "+str(info.keys()) ) x="" for i,v in enumerate(dmx): x += str(v).rjust(4," ") if (i+1) % 20 == 0: lines.append(x) x="" if x: lines.append(x) lines.append(" ") lines.append(str(self.ttime)) #screen.draw_lines(lines) else: self.ttime = time.time() x=self.ohost.get(univ=univ2) #lines = [] host="" univ2="" info=self.ohost.info() jinfo = "" for i in info: xl = json.dumps(i) + "=======X " # live lines.append( xl ) for j in info[i]: lines2=[] lines.append( " " + json.dumps([j,""]) ) for k in info[i][j]: if k in ["fpsx","uni","flag"]: lines2.append( " "+str(k).ljust(5," ")+": " + json.dumps( info[i][j][k]) ) else: lines.append( " "+str(k).ljust(5," ")+": " + json.dumps( info[i][j][k]) ) lines2 = "".join(lines2) lines.append(lines2) lines.append( " " + json.dumps([j,""]) ) lines.append(" ") lines.append(str(self.ttime)) #screen.draw_lines(lines) tmp = "" tmp += " mode:"+(str(self.mode).ljust(10," ")) tmp += " univ:"+str(self.sel_univ.index)+":"+(str(self.sel_univ.get()).ljust(8," ")) tmp += " host:"+str(self.sel_host.index)+":"+(str(self.sel_host.get()).ljust(8," ")) tmp += " --recive:"+str(options.recive) tmp += " --sendto:"+str(options.sendto) lines.insert(0,tmp) tmp = "" sel_univ_data = self.sel_univ.data #sel_univ_data.sort() tmp += " univ:"+ (str(self.sel_univ.data))#.ljust(20," ")) tmp += " list:"+ (str(self.sel_host.data))#.ljust(20," ")) lines.insert(0,tmp) self.draw_lines(lines) class UniversBuffer(): def __init__(self,univers_nr=0): """buffer and merge a universe from multiple sender/hosts/ip's """ self.__hosts = [] self.__universes_dmx = {} self.__universes_fps = {} self.__universes_frames = {} self.__universes_flag = {} self.__universes_x_frames = {} self.__universes_x_time = {} self.__universes_count = {} self.__universes_timer = {} self.__universes_matrix = ["."]*512 self.__universes_info = {} self.__univers_nr = univers_nr self.__frame = 0 def _add(self,host): if host not in self.__hosts: self.__hosts.append(host) #re-order hosts list for LTP #print( "ADDING HOST:",host,"UNIV:",self.__univers_nr) self.__universes_dmx[host] = [0]*512 self.__universes_frames[host] = 0 self.__universes_x_frames[host] = 0 self.__universes_fps[host] = [""]*20 self.__universes_flag[host] = [0]*20 self.__universes_x_time[host] = time.time() self.__universes_timer[host] = [0]*512 self.__universes_info[host] = {} def _next_frame(self,host): self.__frame += 1 self.__universes_frames[host] += 1 self.__universes_x_frames[host] += 1 if self.__universes_x_time[host]+10 < time.time(): sec = time.time()-self.__universes_x_time[host] fps = self.__universes_x_frames[host] /sec #fps = round(fps,1) fps = int(fps) self.__universes_fps[host].pop(0) self.__universes_fps[host].append(fps) self.__universes_x_time[host] = time.time() self.__universes_x_frames[host] = 0 def update(self,host,dmxframe): if type(dmxframe) != list: #print( "update ERROR dmxframe is not a list", host ) return self._add(host) update_matrix = [0]*512 dmx=[0]*512 update_flag = 0 dmxframe_old = self.__universes_dmx[host] self._next_frame(host) #if len(dmxframe) <= 512: #len(dmxframe_old): if cython:# "cython": if len(dmxframe) <= 512: #len(dmxframe_old): dmxnew = dmxframe dmxold = dmxframe_old matrix = self.__universes_matrix hostid = self.__hosts.index(host) x= cy.merge(dmxold,dmxnew,matrix,hostid) dmx = list(x[0]) self.__universes_matrix = list(x[1]) update_flag = x[2] else: if len(dmxframe) <= 512: #len(dmxframe_old): for i,v in enumerate(dmxframe): if dmxframe[i] != dmxframe_old[i]: update_flag += 1 self.__universes_matrix[i] = self.__hosts.index(host) dmx[i] = v self.__universes_flag[host].pop(0) self.__universes_flag[host].append( update_flag ) tmp = {} tmp["flag"] =update_flag tmp["flagx"] = self.__universes_flag[host] tmp["fpsx"] = int(self.__universes_x_frames[host] / (time.time()-self.__universes_x_time[host])) tmp["frame"] = self.__frame #tmp["hosts"] = self.__hosts tmp["uni"] = self.__univers_nr tmp["fps"] = self.__universes_fps[host] tmp["active"] = count_active_dmx_ch(dmxframe) self.__universes_info[host] = tmp if update_flag: #print( "UPDATE HOST:",host, update_flag,"UNIV:",self.__univers_nr) self.__universes_dmx[host] = dmx # dmxframe self.__universes_timer[host] = update_matrix def get(self,host=""): if host and host in self.__hosts: return self.__universes_dmx[host] dmx = [":"]*512 for i,v in enumerate(self.__universes_matrix): if type(v) is int: host = self.__hosts[v] v = self.__universes_dmx[host][i] dmx[i] = v return dmx def get_mtx(self,host=""): return self.__universes_matrix def info(self): return self.__universes_info def hosts(self): x = self.__universes_dmx.keys() x=list(x) x.sort() return x class HostBuffer(): def __init__(self): """buffer hosts and route data into universes """ self.__hosts = [] # LTP order self.__universes = OrderedDict() # {} # 192.168.0.1 = [0]*512 #self.update(host="localhost",univ=0,dmxframe=[6]*512) dmxframe = [0]*512 dmxframe[15] = -6 #self.update(host="333.333.333.333",univ=8,dmxframe=dmxframe) def get_mtx(self,host="", univ=""): return self.__universes[str(univ)].get_mtx(host) def get(self,host="", univ=""): if str(univ) in self.__universes: return self.__universes[str(univ)].get(host) else: return [-8]*512 def hosts(self): hosts = [] for univ in self.__universes: x=self.__universes[univ].hosts() for y in x: #x=univ.hosts() if y not in hosts: hosts.append(y) hosts.sort() return hosts def univs(self): x=self.__universes.keys() x=list(x) #x.sort() return x def update(self,host,univ, dmxframe): #print( "update", host ) if str(univ) not in self.__universes: self.__universes[str(univ)] = UniversBuffer(str(univ)) self.__universes[str(univ)].update(host,dmxframe) def info(self,univ=0): out = {} #print self.__universes.keys() for univ in self.__universes.keys(): #print("INFO:",univ) x=self.__universes[univ] out[univ] = x.info() return out # ============================================================ # Network ==================================================== # ============================================================ import socket, struct hostname = socket.gethostname() netns = "none" x = os.popen("ip netns identify $$") xx = x.read() if xx: netns = xx.strip() import fcntl #socket control import errno def toPrintable(nonprintable): out = "" for i in str(nonprintable): printable = string.ascii_letters + string.digits +"/()=?{[]}\;:,.-_ " if str(i) in printable : out += str(i) return out def unpack_art_dmx(data): dmx = [] for i in range(len(data[18:]) ): x=data[18+i] #print("x",x) #print( "data",b'!B', data[18+i]) #x=struct.unpack( b'!B',data[18+i]) #print( "data",b'!B', data[18+i],x) #x=x[0] dmx += [x] return dmx def ArtPollCheck(data,addr): opcode=artnet_get_opcode(data) if "ArtPoll" in opcode or "ArtPollReplay" in opcode: #print("PKG3",addr, opcode,len(data)) try: k = "{}:{}".format(addr[0],opcode[0]) mc.set(k, data) update_mc_artpoll_index(k,val="") except Exception as e: print("ArtPollCheck err:",e) if mc: mc.set("artnet-pkg-count" ,{}) class PKG_COUNT(): def __init__(self,name="PKG_COUNT"): self.time = 0 self.fps = 0 self._count = 0 self.fps_hitory = [0]*10 self.fps_count = 0 self.name = name self.start = time.time() def count(self): self.fps_count += 1 def check(self): if time.time()-self.time > 10: self.reset() return True def reset(self,t=None): if t is None: self.time = time.time() else: self.time = t #print("reset",self.name, self.time) def info(self): self.fps = self.fps_count/10 self.fps_count = 0 #run_time=int((time.time()-self.start)/60) self.fps_hitory = self.fps_hitory[1:] self.fps_hitory.append(self.fps) self._count += 1 return {self.name+"-fps":self.fps,self.name+"-hist":self.fps_hitory,self.name+"-count":self._count} def update_mc(self): data = {} x =mc.get("artnet-pkg-count") if x: data.update(x) data.update(self.info()) mc.set("artnet-pkg-count" ,data) class IN_Socket(): def __init__(self,bind='',port=6454): self.__port =port self.__bind =bind self.__poll = 0 self.__data = [] self.__addr = "NONE" #self.__hosts = {"host":{"9":[0]*512}} self.__hosts = {} self.hosts = self.__hosts self.open() self.start = time.time() self.pkg_in_count = PKG_COUNT(name="in") def open(self): try: print("connecting to ArtNet bind:",self.__bind,"Port",self.__port) self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sock.bind((self.__bind, self.__port)) fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK) #self.sock.setblocking(0) except socket.error as e: print("Socket ",self.__bind,self.__port, "ERR: {0} ".format(e.args)) #raw_input() #sys.exit() def poll(self): if not self.__poll: if mc: if self.pkg_in_count.check(): self.pkg_in_count.reset() self.pkg_in_count.update_mc() try: self.__data, self.__addr = self.sock.recvfrom(self.__port) data, addr = (self.__data,self.__addr) self.pkg_in_count.count() ArtPollCheck(data,addr) opcode=artnet_get_opcode(data) if opcode[0] != "ArtDMX": return self.host = addr[0] head = data[:18] rawdmx = data[18:] #print([head],addr) self.univ = -1 try: self.head = struct.unpack("!8sHBBBBHBB" , head ) except Exception as e: pass#print( "======E09823" , e) univ = self.head[6]/255 # /512 # * 512 self.univ = int(univ) #if "2.0.0.11" not in addr: # print("PKG3",addr,"univ:",self.univ, opcode,len(rawdmx)) if self.host.startswith("127."): #allways recive localhost on port self.__poll = 1 return 1 elif not options.recive: self.__poll = 1 return 1 elif self.host.startswith(options.recive): self.__poll = 1 return 1 else: self.__poll = 0 addr = str(addr) univ = str(univ) if self.__poll: if addr not in self.__hosts: self.__hosts[addr] = {} if univ not in self.__hosts[addr]: self.__hosts[addr][univ] = {} self.__hosts[addr][univ] = {"head":head,"addr":addr,"univ":univ,"dmx":rawdmx} self.hosts = self.__hosts except socket.timeout as e: err = e.args[0] if err == 'timed out': time.sleep(1) print('recv timed out, retry later') else: print(e) except socket.error as e: pass def recive(self): if self.__poll: self.__poll = 0 data, addr = (self.__data,self.__addr) #print("PKG", self.univ,self.head) self.dmx = unpack_art_dmx(data) return { "host":self.host,"dmx":self.dmx,"univ":self.univ,"head":self.head,"data":data,"addr":addr} # ============================================================ # miniartnet4.py ============================================= # ============================================================ import time import socket import struct import random class ArtNetNode(): """simple Object to generate raw ArtNet like Network packages works in Python2 and Python3 2021-12-05 (only basic implementation) "Art-Netâ„¢ Designed by and Copyright Artistic Licence Holdings Ltd" https://art-net.org.uk/ """ def __init__(self, to="10.10.10.255",univ=7,port=6454): print("\n"+self.__doc__+"\n") try: univ = int(univ) except: print("errror univ",univ ,"is not int ... set to 7") univ = 7 self.univ=univ self.sendto = to self.portto = port self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.stamp = time.time() self.test_stamp = time.time() self.dmx=[33]*512 self.v=0 self.d=1 #self.pkg_out_count = PKG_COUNT(name="out-"+str(univ)) self.pkg_counter = {} def head(self): self._header = [] self._header.append(b"Art-Net\x00") # Name, 7byte + 0x00 self._header.append(struct.pack(' 0x5000, Low Byte first self._header.append(struct.pack('>H', 14)) # Protocol Version 14, High Byte first self._header.append(b"\x00") # Order -> nope -> 0x00 self._header.append(struct.pack('B',1)) # Eternity Port # Address #if 0 <= universe <= 15 and 0 <= net <= 127 and 0 <= subnet <= 15 net, subnet, universe = (0,0,self.univ) #address self._header.append(struct.pack('H', len(dmx) ) ) #print([c]) dmx_count = 0 for v in dmx: if type(v) is not int: v=0 elif v > 255: # max dmx value 255 v = 255 elif v < 0: # min dmx value 0 v = 0 dmx_count += 1 c.append(struct.pack("B",v)) c = b"".join(c) if port: self.s.sendto(c, (self.sendto, port)) # default 6454 else: self.s.sendto(c, (self.sendto, self.portto)) # default 6454 # multicounter management ! name = "out-"+str(self.univ) if name not in self.pkg_counter: self.pkg_counter[name] = PKG_COUNT(name=name) counter = self.pkg_counter[name] counter.count() if mc: if counter.check(): counter.reset() counter.update_mc() return c def _test_frame(self): if self.test_stamp+0.1 > time.time(): return 0 self.test_stamp = time.time() dmx = [0]*512 dmx[420] = self.v self.dmx = dmx self.next() #self.send(dmx) #print( [x] ) if self.v >= 255: self.d=0 elif self.v <=0: self.d=1 if self.d: self.v+=1 else: self.v-=1 #time.sleep(1/30.) def next(self): if self.stamp + (1/60) <= time.time(): self.send() def artnet_test(): artnet = ArtNetNode() artnet._tes_frame() def artnet_get_opcode(head): #print([head]) #[9:10]) opcode=0x0000 name ="unkown" try: opcode=hex(struct.unpack('= _max: self.index = 0 elif self.index < 0: self.index = _max-1 else: if self.index >= _max: self.index = _max-1 elif self.index < 0: self.index = 0 class Timer(): def __init__(self,sec=1,start=None): if start is None: self.last = time.time() else: self.last = start self.sec = sec print( self,"init") def reset(self): self.last = time.time() def check(self): if self.last+self.sec < time.time(): #print(self,"chk",time.time()+self.sec-time.time()) self.reset() return 1 # ============================================================ # main ======================================================= # ============================================================ class Main(): def __init__(self): pass def loop(self): ohost = HostBuffer() screen=Window() screen.exit() screen.ohost = ohost #artnet_out = ArtNetNode(to="10.0.25.255") artnet_out = ArtNetNode(to=options.sendto) ohost.update(host="Main-"+str(options.sendto),univ=0,dmxframe=[0]*512) # dummy input #artnet_out._test_frame() if options.testuniv: artnet = ArtNetNode(univ=options.testuniv) artnet._test_frame() #ysocket = Socket(bind='127.0.0.1' ,port=6555) in_socket = IN_Socket() xt = time.time() ohost_buf = {} ohost_timer = Timer(1/30.,start=0) # 0.03333 send_timer = Timer(1/30.) # 0.03333 try: screen.exit() while 1: poll_flag = 0 if options.testuniv: artnet._test_frame() #artnet_out._test_frame() #if in_socket.poll(): while in_socket.poll(): xt = time.time() poll_flag = 1 x = in_socket.recive() if x["host"] == options.recive: try: x["univ"] = int(options.inmap ) except TypeError: pass if x["host"] not in ohost_buf: ohost_buf[x["host"]] = {} if x["univ"] not in ohost_buf[x["host"]]: ohost_buf[x["host"]][x["univ"]] = {} ohost_buf[x["host"]][x["univ"]] = x["dmx"] #write into buffer to prevent package latency encreasing try: k = "{}:{}".format(x["host"],x["univ"]) mc.set(k, x["dmx"]) # "dmx-{}".format(univ), ltp) active = count_active_dmx_ch(x["dmx"]) update_memcachd_index(key=k,active=active) except Exception as e: print("exception:",e) time.sleep(.1) #ohost.update(x["host"],x["univ"],x["dmx"]) if 0:#ysocket.poll(): poll_flag = 1 x = ysocket.recive() if x["host"] == options.recive: try: x["univ"] = int(options.inmap ) except TypeError: pass ohost.update(host=x["host"],univ=x["univ"],dmxframe=x["dmx"]) screen.sel_univ.data = ohost.univs() screen.sel_host.data = ohost.hosts() if ohost_timer.check(): for i in ohost_buf: for j in ohost_buf[i]: dmx=ohost_buf[i][j] ohost.update(host=i,univ=j,dmxframe=dmx) # update univ_data from input buffer ohost_buf = {} # clear package buffer if send_timer.check() and options.sendto: #x=ohost.get(univ=univ2) info=ohost.info() jinfo = "" for i in info: univ = i if str(univ) == "54": break xl = json.dumps(univ) + "======= " #XX ltp=ohost.get(univ=i) try: k="ltp-out:{}".format(univ) mc.set(k,ltp) active = count_active_dmx_ch(ltp) update_memcachd_index(key=k,active=active) except Exception as e: print("Exc memcachd_index1 ",e) artnet_out.univ=int(univ) artnet_out.send(ltp) if not poll_flag: time.sleep(.001) screen.loop() finally: pass #screen.exit() #print(dir(curses)) if __name__ == "__main__": print("main") main = Main() print("loop") main.loop()