artnet_read.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import os
  2. import fcntl
  3. import time
  4. import socket
  5. import struct
  6. import random
  7. import copy
  8. import _thread as thread
  9. import sys
  10. def unpack_art_dmx(data):
  11. dmx = ["x"]*512
  12. for i in range(len(data[18:]) ):
  13. x=data[18+i]
  14. #print("x",x)
  15. #print( "data",b'!B', data[18+i])
  16. #x=struct.unpack( b'!B',data[18+i])
  17. #print( "data",b'!B', data[18+i],x)
  18. #x=x[0]
  19. dmx[i] = x
  20. return dmx
  21. class Socket():
  22. def __init__(self,bind='',port=6454,options_recive=""):
  23. self.__port =port
  24. self.__bind =bind
  25. self.options_recive=options_recive
  26. self.__poll = 0
  27. self.__data = []
  28. self.__addr = "NONE"
  29. #self.__hosts = {"host":{"9":[0]*512}}
  30. self.__hosts = {}
  31. self.hosts = self.__hosts
  32. self.open()
  33. self._poll_clean_time = time.time()
  34. self._poll_clean_count = 0
  35. def open(self):
  36. try:
  37. print("connecting to ArtNet bind:",self.__bind,"Port",self.__port)
  38. self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  39. self.sock.bind((self.__bind, self.__port))
  40. fcntl.fcntl(self.sock, fcntl.F_SETFL, os.O_NONBLOCK)
  41. #self.sock.setblocking(0)
  42. except socket.error as e:
  43. print("Socket ",self.__bind,self.__port, "ERR: {0} ".format(e.args))
  44. #raw_input()
  45. #sys.exit()
  46. def poll_clean(self):
  47. if self._poll_clean_time+(1/25.) <= time.time():
  48. self._poll_clean_time = time.time()
  49. self._poll_clean()
  50. x = self._poll_clean_count
  51. self._poll_clean_count = 0
  52. return x
  53. def _poll_clean(self):
  54. while 1:
  55. try:
  56. self.__data, self.__addr = self.sock.recvfrom(self.__port)
  57. self._poll_clean_count += 1
  58. #return 1
  59. except socket.timeout as e:
  60. err = e.args[0]
  61. if err == 'timed out':
  62. time.sleep(1)
  63. print('recv timed out, retry later')
  64. else:
  65. print(e)
  66. break
  67. except socket.error as e:
  68. break
  69. def poll(self ):
  70. if not self.__poll:
  71. try:
  72. self.__data, self.__addr = self.sock.recvfrom(self.__port)
  73. data, addr = (self.__data,self.__addr)
  74. self.host = addr[0]
  75. head = data[:18]
  76. rawdmx = data[18:]
  77. #print([head],addr)
  78. self.univ = -1
  79. try:
  80. self.head = struct.unpack("!8sHBBBBHBB" , head )
  81. except Exception as e:
  82. pass#print( "======E09823" , e)
  83. univ = self.head[6]/255 # /512 # * 512
  84. self.univ = int(univ)
  85. if self.host.startswith("127."): #allways recive localhost on port
  86. self.__poll = 1
  87. return 1
  88. elif not self.options_recive:
  89. self.__poll = 1
  90. return 1
  91. elif self.host.startswith(self.options_recive):
  92. self.__poll = 1
  93. return 1
  94. else:
  95. self.__poll = 0
  96. addr = str(addr)
  97. univ = str(univ)
  98. if self.__poll:
  99. if addr not in self.__hosts:
  100. self.__hosts[addr] = {}
  101. if univ not in self.__hosts[addr]:
  102. self.__hosts[addr][univ] = {}
  103. self.__hosts[addr][univ] = {"head":head,"addr":addr,"univ":univ,"dmx":rawdmx}
  104. self.hosts = self.__hosts
  105. except socket.timeout as e:
  106. err = e.args[0]
  107. if err == 'timed out':
  108. time.sleep(1)
  109. print('recv timed out, retry later')
  110. else:
  111. print(e)
  112. except socket.error as e:
  113. pass
  114. def recive(self):
  115. if self.__poll:
  116. self.__poll = 0
  117. data, addr = (self.__data,self.__addr)
  118. #print( self.univ,self.head)
  119. self.dmx = unpack_art_dmx(data)
  120. return { "host":self.host,"dmx":self.dmx,"univ":self.univ,"head":self.head,"data":data,"addr":addr}
  121. def get_value(sdata=[] ,univ=0,dmx=[1,121]):
  122. data=[]
  123. for k in sdata:
  124. xx = sdata[k]
  125. _univ = int(xx["head"][6] /256)
  126. if xx["host"].startswith('2.0.0.') and _univ == univ:
  127. for d in dmx:
  128. y = xx["dmx"][d-1]
  129. data.append(y)
  130. return data
  131. class ArtNetRead():
  132. def __init__(self):
  133. self.sdata = {}
  134. self.xsocket = Socket()
  135. self.lock = thread.allocate_lock()
  136. def loop(self):
  137. sdata = {}
  138. print("loop")
  139. while 1:
  140. flag = 0
  141. while self.xsocket.poll():
  142. xx = self.xsocket.recive()
  143. k = xx["host"] +":"+ str(xx["head"][6])
  144. sdata[k] = xx
  145. flag = 1
  146. if flag:
  147. try:
  148. self.lock.acquire()
  149. self.sdata = copy.deepcopy(sdata)
  150. finally:
  151. self.lock.release()
  152. time.sleep(0.001)
  153. def get(self):
  154. try:
  155. self.lock.acquire()
  156. x = self.sdata #= copy.deepcopy(asdata)
  157. self.sdata = {}
  158. return x
  159. finally:
  160. self.lock.release()
  161. if __name__ == "__main__":
  162. e = ArtNetRead()
  163. thread.start_new_thread(e.loop,())