oszi_grid.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. # -*- coding: UTF-8 -*-
  2. import os
  3. import fcntl
  4. import time
  5. import socket
  6. import struct
  7. import random
  8. from optparse import OptionParser
  9. parser = OptionParser()
  10. parser.add_option("-r", "--recive", dest="recive",
  11. help="set recive ip like --recive 10.")
  12. parser.add_option("-s", "--sendto", dest="sendto",
  13. help="set sender ip like --sendto 2.255.255.255")
  14. parser.add_option("-t", "--test", dest="testuniv",
  15. help="set test univers like --test [0-16]")
  16. parser.add_option("", "--inmap", dest="inmap",
  17. help="set test univers like --test [0-16]")
  18. #parser.add_option("-q", "--quiet",
  19. # action="store_false", dest="verbose", default=True,
  20. # help="don't print status messages to stdout")
  21. (options, args) = parser.parse_args()
  22. print("option",options)
  23. print(options.sendto)
  24. def unpack_art_dmx(data):
  25. dmx = []
  26. for i in range(len(data[18:]) ):
  27. x=data[18+i]
  28. #print("x",x)
  29. #print( "data",b'!B', data[18+i])
  30. #x=struct.unpack( b'!B',data[18+i])
  31. #print( "data",b'!B', data[18+i],x)
  32. #x=x[0]
  33. dmx += [x]
  34. return dmx
  35. class Socket():
  36. def __init__(self,bind='',port=6454):
  37. self.__port =port
  38. self.__bind =bind
  39. self.__poll = 0
  40. self.__data = []
  41. self.__addr = "NONE"
  42. #self.__hosts = {"host":{"9":[0]*512}}
  43. self.__hosts = {}
  44. self.hosts = self.__hosts
  45. self.open()
  46. self._poll_clean_time = time.time()
  47. self._poll_clean_count = 0
  48. def open(self):
  49. try:
  50. print("connecting to ArtNet bind:",self.__bind,"Port",self.__port)
  51. self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  52. self.sock.bind((self.__bind, self.__port))
  53. fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK)
  54. #self.sock.setblocking(0)
  55. except socket.error as e:
  56. print("Socket ",self.__bind,self.__port, "ERR: {0} ".format(e.args))
  57. #raw_input()
  58. #sys.exit()
  59. def poll_clean(self):
  60. if self._poll_clean_time+(1/25.) <= time.time():
  61. self._poll_clean_time = time.time()
  62. self._poll_clean()
  63. x = self._poll_clean_count
  64. self._poll_clean_count = 0
  65. return x
  66. def _poll_clean(self):
  67. while 1:
  68. try:
  69. self.__data, self.__addr = self.sock.recvfrom(self.__port)
  70. self._poll_clean_count += 1
  71. #return 1
  72. except socket.timeout as e:
  73. err = e.args[0]
  74. if err == 'timed out':
  75. time.sleep(1)
  76. print('recv timed out, retry later')
  77. else:
  78. print(e)
  79. break
  80. except socket.error as e:
  81. break
  82. def poll(self):
  83. if not self.__poll:
  84. try:
  85. self.__data, self.__addr = self.sock.recvfrom(self.__port)
  86. data, addr = (self.__data,self.__addr)
  87. self.host = addr[0]
  88. head = data[:18]
  89. rawdmx = data[18:]
  90. #print([head],addr)
  91. self.univ = -1
  92. try:
  93. self.head = struct.unpack("!8sHBBBBHBB" , head )
  94. except Exception as e:
  95. pass#print( "======E09823" , e)
  96. univ = self.head[6]/255 # /512 # * 512
  97. self.univ = int(univ)
  98. if self.host.startswith("127."): #allways recive localhost on port
  99. self.__poll = 1
  100. return 1
  101. elif not options.recive:
  102. self.__poll = 1
  103. return 1
  104. elif self.host.startswith(options.recive):
  105. self.__poll = 1
  106. return 1
  107. else:
  108. self.__poll = 0
  109. addr = str(addr)
  110. univ = str(univ)
  111. if self.__poll:
  112. if addr not in self.__hosts:
  113. self.__hosts[addr] = {}
  114. if univ not in self.__hosts[addr]:
  115. self.__hosts[addr][univ] = {}
  116. self.__hosts[addr][univ] = {"head":head,"addr":addr,"univ":univ,"dmx":rawdmx}
  117. self.hosts = self.__hosts
  118. except socket.timeout as e:
  119. err = e.args[0]
  120. if err == 'timed out':
  121. time.sleep(1)
  122. print('recv timed out, retry later')
  123. else:
  124. print(e)
  125. except socket.error as e:
  126. pass
  127. def recive(self):
  128. if self.__poll:
  129. self.__poll = 0
  130. data, addr = (self.__data,self.__addr)
  131. #print( self.univ,self.head)
  132. self.dmx = unpack_art_dmx(data)
  133. return { "host":self.host,"dmx":self.dmx,"univ":self.univ,"head":self.head,"data":data,"addr":addr}
  134. x=0
  135. y=0
  136. running = True
  137. xsocket = Socket()
  138. import pygame
  139. import pygame.gfxdraw
  140. pygame.init()
  141. screen = pygame.display.set_mode((780, 610))
  142. pygame.display.set_caption("pygame: DMX OSZI")
  143. pygame.mouse.set_visible(1)
  144. pygame.key.set_repeat(1, 30)
  145. clock = pygame.time.Clock()
  146. pygame.init()
  147. class Trans():
  148. def __init__(self,y=150):
  149. self.y = 150
  150. self.s = 0.25
  151. def get_y(self,y):
  152. return int((y*self.s)+(self.y*self.s))*-1
  153. import copy
  154. import _thread as thread
  155. class E():
  156. def __init__(self):
  157. self.sdata = {}
  158. self.lock = thread.allocate_lock()
  159. def loop(self):
  160. sdata = {}
  161. print("loop")
  162. while 1:
  163. flag = 0
  164. while xsocket.poll():
  165. xx = xsocket.recive()
  166. k = xx["host"] +":"+ str(xx["head"][6])
  167. sdata[k] = xx
  168. flag = 1
  169. if flag:
  170. try:
  171. self.lock.acquire()
  172. self.sdata = copy.deepcopy(sdata)
  173. finally:
  174. self.lock.release()
  175. time.sleep(0.001)
  176. def get(self):
  177. try:
  178. self.lock.acquire()
  179. x = self.sdata #= copy.deepcopy(asdata)
  180. self.sdata = {}
  181. return x
  182. finally:
  183. self.lock.release()
  184. e = E()
  185. thread.start_new_thread(e.loop,())
  186. T = Trans()
  187. import sys
  188. font = pygame.font.SysFont("FreeSans", 12) #,color=(255,0,0))
  189. def get_value(sdata=[] ,univ=0,dmx=[1,121]):
  190. data=[]
  191. for k in sdata:
  192. xx = sdata[k]
  193. _univ = int(xx["head"][6] /256)
  194. if xx["host"].startswith('2.0.0.') and _univ == univ:
  195. for d in dmx:
  196. y = xx["dmx"][d-1]
  197. data.append(y)
  198. return data
  199. class OSZI():
  200. def __init__(self):
  201. self._x=0
  202. self.sdata={}
  203. self.lz = time.time()
  204. self.c=0
  205. def draw(self,screen,data):#,c,x,y,T):
  206. x=int(self._x)
  207. if time.time() > self.lz:
  208. self.lz = time.time()+6
  209. self._x=0
  210. x=0
  211. rec = pygame.Rect(x+1,T.get_y(10),30,245) # clear balken
  212. pygame.draw.rect(screen,(10,10,0),rec)
  213. T.y=-260
  214. c=0
  215. for d in data:
  216. y=d
  217. pygame.gfxdraw.pixel(screen,x,T.get_y(255),(255,0,0))
  218. pygame.gfxdraw.pixel(screen,x,T.get_y(0),(10,10,25))
  219. rec = pygame.Rect(x+4,T.get_y(0),20,-80) # clear balken
  220. pygame.draw.rect(screen,(c,210,110),rec)
  221. rec = pygame.Rect(x+2,T.get_y(0),30,-80) # clear balken
  222. pygame.draw.rect(screen,(c,10,110),rec)
  223. text = font.render( str(y), True, (0,0,0))
  224. pygame.draw.circle(screen,(255,155,0),(x,T.get_y(y)),2)
  225. c+=50
  226. if c >255:
  227. c=255
  228. T.y-=275
  229. #_x+=3.5*2
  230. self._x+=1.5*2
  231. def read_event():
  232. running = True
  233. for event in pygame.event.get():
  234. if event.type == pygame.QUIT:
  235. running = False
  236. if event.type == pygame.KEYDOWN:
  237. print(event.type)
  238. if event.key == pygame.K_ESCAPE:
  239. pygame.event.post(pygame.event.Event(pygame.QUIT))
  240. return running
  241. class GRID():
  242. def __init__(self):
  243. self.grid_timer = time.time()
  244. def draw(self,xsdata):
  245. grid_timer = self.grid_timer
  246. if grid_timer > time.time():
  247. return
  248. grid_timer=time.time()+.0215
  249. for d in xsdata:
  250. xx=sdata[d]
  251. univ = xx["head"][6] //256 #/ 255
  252. if xx["host"].startswith('2.0.0.'):
  253. if univ == 0:
  254. rx=308
  255. ry=10
  256. rec = pygame.Rect(rx,ry,600,600) # clear balken
  257. pygame.draw.rect(screen,(20,20,20),rec)
  258. text = font.render( str(univ).rjust(3," "), True, (255,255,255))
  259. screen.blit(text, ( rx-10, ry ) )
  260. line = []
  261. for i,dmx in enumerate(xx["dmx"]):
  262. text = font.render( str(dmx).rjust(3," "), True, (255,255,255))
  263. screen.blit(text, ( rx+10, ry+10 ) )
  264. rx+=29
  265. if (i+1) % 20 == 0:
  266. rx=308
  267. ry+=11
  268. elif univ == 1:
  269. rx=8
  270. ry=310
  271. rec = pygame.Rect(rx,ry,600,600) # clear balken
  272. pygame.draw.rect(screen,(10,30,10),rec)
  273. text = font.render( str(univ).rjust(3," "), True, (255,255,255))
  274. screen.blit(text, ( rx-10, ry ) )
  275. line = []
  276. for i,dmx in enumerate(xx["dmx"]):
  277. text = font.render( str(dmx).rjust(3," "), True, (255,200,255))
  278. screen.blit(text, ( rx+10, ry+10 ) )
  279. rx+=29
  280. if (i+1) % 20 == 0:
  281. rx=8
  282. ry+=11
  283. _ips = {}
  284. def print_ips(sdata):
  285. if int(time.time()*10) % 20 == 0:
  286. for k in sdata:
  287. if k in _ips:
  288. _ips[k] += 1
  289. else:
  290. _ips[k] = 0
  291. print(k.ljust(15," "),_ips[k])
  292. print()
  293. grid_a = GRID()
  294. oszi_a = OSZI()
  295. while running:
  296. clock.tick(15)
  297. #clock.tick(225)
  298. sdata = e.get()
  299. xsdata = copy.deepcopy(sdata)
  300. print_ips(sdata)
  301. data = get_value(sdata,univ=1,dmx=[21,142,261,263])
  302. running = read_event()
  303. oszi_a.draw(screen,data) #,c,x,y,T)
  304. grid_a.draw(xsdata)
  305. pygame.display.flip()