PageRenderTime 150ms CodeModel.GetById 32ms RepoModel.GetById 2ms app.codeStats 2ms

/src/LabJackPython.py

https://github.com/arch-web-labs/LabJackPython
Python | 3579 lines | 3334 code | 92 blank | 153 comment | 24 complexity | 48d0b0c530feeeaea6134fb86703de43 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. """
  2. Multi-Platform Python wrapper that implements functions from the LabJack
  3. Windows UD Driver, and the Exodriver.
  4. This python wrapper is intended to make working with your LabJack device easy. The functions contained in this module are helper and device agnostic functions. This module provides the base Device class which the U3, U6, and UE9 classes inherit from.
  5. A typical user should start with their device's module, such as u3.py.
  6. """
  7. # We use the 'with' keyword to manage the thread-safe device lock. It's built-in on 2.6; 2.5 requires an import.
  8. from __future__ import with_statement
  9. import collections
  10. import ctypes
  11. import os
  12. import struct
  13. from decimal import Decimal
  14. import socket
  15. import Modbus
  16. import atexit # For auto-closing devices
  17. import threading # For a thread-safe device lock
  18. LABJACKPYTHON_VERSION = "10-22-2012"
  19. SOCKET_TIMEOUT = 3
  20. LJSOCKET_TIMEOUT = 62
  21. BROADCAST_SOCKET_TIMEOUT = 1
  22. MAX_USB_PACKET_LENGTH = 64
  23. NUMBER_OF_UNIQUE_LABJACK_PRODUCT_IDS = 5
  24. class LabJackException(Exception):
  25. """Custom Exception meant for dealing specifically with LabJack Exceptions.
  26. Error codes are either going to be a LabJackUD error code or a -1. The -1 implies
  27. a python wrapper specific error.
  28. WINDOWS ONLY
  29. If errorString is not specified then errorString is set by errorCode
  30. """
  31. def __init__(self, ec = 0, errorString = ''):
  32. self.errorCode = ec
  33. self.errorString = errorString
  34. if not self.errorString:
  35. try:
  36. pString = ctypes.create_string_buffer(256)
  37. staticLib.ErrorToString(ctypes.c_long(self.errorCode), ctypes.byref(pString))
  38. self.errorString = pString.value
  39. except:
  40. self.errorString = str(self.errorCode)
  41. def __str__(self):
  42. return self.errorString
  43. # Raised when a low-level command raises an error.
  44. class LowlevelErrorException(LabJackException): pass
  45. # Raised when the return value of OpenDevice is null.
  46. class NullHandleException(LabJackException):
  47. def __init__(self):
  48. self.errorString = "Couldn't open device. Please check that the device you are trying to open is connected."
  49. def errcheck(ret, func, args):
  50. """
  51. Whenever a function is called through ctypes, the return value is passed to
  52. this function to be checked for errors.
  53. Support for errno didn't come until 2.6, so Python 2.5 people should
  54. upgrade.
  55. """
  56. if ret == -1:
  57. try:
  58. ec = ctypes.get_errno()
  59. raise LabJackException(ec, "Exodriver returned error number %s" % ec)
  60. except AttributeError:
  61. raise LabJackException(-1, "Exodriver returned an error, but LabJackPython is unable to read the error code. Upgrade to Python 2.6 for this functionality.")
  62. else:
  63. return ret
  64. def _loadLinuxSo():
  65. """
  66. Attempts to load the liblabjackusb.so for Linux.
  67. """
  68. try:
  69. l = ctypes.CDLL("liblabjackusb.so", use_errno=True)
  70. except TypeError:
  71. l = ctypes.CDLL("liblabjackusb.so")
  72. l.LJUSB_Stream.errcheck = errcheck
  73. l.LJUSB_Read.errcheck = errcheck
  74. return l
  75. def _loadMacDylib():
  76. """
  77. Attempts to load the liblabjackusb.dylib for Mac OS X.
  78. """
  79. try:
  80. l = ctypes.CDLL("liblabjackusb.dylib", use_errno=True)
  81. except TypeError:
  82. l = ctypes.CDLL("liblabjackusb.dylib")
  83. l.LJUSB_Stream.errcheck = errcheck
  84. l.LJUSB_Read.errcheck = errcheck
  85. return l
  86. def _loadLibrary():
  87. """_loadLibrary()
  88. Returns a ctypes dll pointer to the library.
  89. """
  90. if(os.name == 'posix'):
  91. try:
  92. return _loadLinuxSo()
  93. except OSError, e:
  94. pass # We may be on Mac.
  95. except Exception, e:
  96. raise LabJackException("Could not load the Linux SO for some reason other than it not being installed. Ethernet connectivity only.\n\n The error was: %s" % e)
  97. try:
  98. return _loadMacDylib()
  99. except OSError, e:
  100. raise LabJackException("Could not load the Exodriver driver. Ethernet connectivity only.\n\nCheck that the Exodriver is installed, and the permissions are set correctly.\nThe error message was: %s" % e)
  101. except Exception, e:
  102. raise LabJackException("Could not load the Mac Dylib for some reason other than it not being installed. Ethernet connectivity only.\n\n The error was: %s" % e)
  103. if(os.name == 'nt'):
  104. try:
  105. return ctypes.windll.LoadLibrary("labjackud")
  106. except Exception, e:
  107. raise LabJackException("Could not load labjackud driver. Ethernet connectivity availability only.\n\n The error was: %s" % e)
  108. try:
  109. staticLib = _loadLibrary()
  110. except LabJackException, e:
  111. print "%s: %s" % ( type(e), e )
  112. staticLib = None
  113. # Attempt to load the windows Skymote library.
  114. try:
  115. skymoteLib = ctypes.windll.LoadLibrary("liblabjackusb")
  116. except:
  117. skymoteLib = None
  118. class Device(object):
  119. """Device(handle, localId = None, serialNumber = None, ipAddress = "", type = None)
  120. Creates a simple 0 with the following functions:
  121. write(writeBuffer) -- Writes a buffer.
  122. writeRegister(addr, value) -- Writes a value to a modbus register
  123. read(numBytes) -- Reads until a packet is received.
  124. readRegister(addr, numReg = None, format = None) -- Reads a modbus register.
  125. ping() -- Pings the device. Returns true if communication worked.
  126. close() -- Closes the device.
  127. reset() -- Resets the device.
  128. """
  129. def __init__(self, handle, localId = None, serialNumber = None, ipAddress = "", devType = None):
  130. # Not saving the handle as a void* causes many problems on 64-bit machines.
  131. if isinstance(handle, int):
  132. self.handle = ctypes.c_void_p(handle)
  133. else:
  134. self.handle = handle
  135. self.localId = localId
  136. self.serialNumber = serialNumber
  137. self.ipAddress = ipAddress
  138. self.devType = devType
  139. self.debug = False
  140. self.streamConfiged = False
  141. self.streamStarted = False
  142. self.streamPacketOffset = 0
  143. self._autoCloseSetup = False
  144. self.modbusPrependZeros = True
  145. self.deviceLock = threading.Lock()
  146. self.deviceName = "LabJack"
  147. def _writeToLJSocketHandle(self, writeBuffer, modbus):
  148. #if modbus is True and self.modbusPrependZeros:
  149. # writeBuffer = [ 0, 0 ] + writeBuffer
  150. packFormat = "B" * len(writeBuffer)
  151. tempString = struct.pack(packFormat, *writeBuffer)
  152. if modbus:
  153. self.handle.modbusSocket.send(tempString)
  154. else:
  155. self.handle.crSocket.send(tempString)
  156. return writeBuffer
  157. def _writeToUE9TCPHandle(self, writeBuffer, modbus):
  158. packFormat = "B" * len(writeBuffer)
  159. tempString = struct.pack(packFormat, *writeBuffer)
  160. if modbus is True:
  161. if self.handle.modbus is None:
  162. raise LabJackException("Modbus port is not available. Please upgrade to UE9 Comm firmware 1.43 or higher.")
  163. self.handle.modbus.send(tempString)
  164. else:
  165. self.handle.data.send(tempString)
  166. return writeBuffer
  167. def _writeToExodriver(self, writeBuffer, modbus):
  168. if modbus is True and self.modbusPrependZeros:
  169. writeBuffer = [ 0, 0 ] + writeBuffer
  170. newA = (ctypes.c_byte*len(writeBuffer))(0)
  171. for i in range(len(writeBuffer)):
  172. newA[i] = ctypes.c_byte(writeBuffer[i])
  173. writeBytes = staticLib.LJUSB_Write(self.handle, ctypes.byref(newA), len(writeBuffer))
  174. if(writeBytes != len(writeBuffer)):
  175. raise LabJackException( "Could only write %s of %s bytes." % (writeBytes, len(writeBuffer) ) )
  176. return writeBuffer
  177. def _writeToUDDriver(self, writeBuffer, modbus):
  178. if self.devType == 0x501:
  179. newA = (ctypes.c_byte*len(writeBuffer))(0)
  180. for i in range(len(writeBuffer)):
  181. newA[i] = ctypes.c_byte(writeBuffer[i])
  182. writeBytes = skymoteLib.LJUSB_IntWrite(self.handle, 1, ctypes.byref(newA), len(writeBuffer))
  183. if(writeBytes != len(writeBuffer)):
  184. raise LabJackException( "Could only write %s of %s bytes." % (writeBytes, len(writeBuffer) ) )
  185. else:
  186. if modbus is True and self.devType == 9:
  187. dataWords = len(writeBuffer)
  188. writeBuffer = [0, 0xF8, 0, 0x07, 0, 0] + writeBuffer #modbus low-level function
  189. if dataWords % 2 != 0:
  190. dataWords = (dataWords+1)/2
  191. writeBuffer.append(0)
  192. else:
  193. dataWords = dataWords/2
  194. writeBuffer[2] = dataWords
  195. setChecksum(writeBuffer)
  196. elif modbus is True and self.modbusPrependZeros:
  197. writeBuffer = [ 0, 0 ] + writeBuffer
  198. eGetRaw(self.handle, LJ_ioRAW_OUT, 0, len(writeBuffer), writeBuffer)
  199. return writeBuffer
  200. def write(self, writeBuffer, modbus = False, checksum = True):
  201. """write([writeBuffer], modbus = False)
  202. Writes the data contained in writeBuffer to the device. writeBuffer must be a list of
  203. bytes.
  204. """
  205. if self.handle is None:
  206. raise LabJackException("The device handle is None.")
  207. if checksum:
  208. setChecksum(writeBuffer)
  209. if(isinstance(self.handle, LJSocketHandle)):
  210. wb = self._writeToLJSocketHandle(writeBuffer, modbus)
  211. elif(isinstance(self.handle, UE9TCPHandle)):
  212. wb = self._writeToUE9TCPHandle(writeBuffer, modbus)
  213. else:
  214. if os.name == 'posix':
  215. wb = self._writeToExodriver(writeBuffer, modbus)
  216. elif os.name == 'nt':
  217. wb = self._writeToUDDriver(writeBuffer, modbus)
  218. if self.debug: print "Sent: ", hexWithoutQuotes(wb)
  219. def read(self, numBytes, stream = False, modbus = False):
  220. """read(numBytes, stream = False, modbus = False)
  221. Blocking read until a packet is received.
  222. """
  223. readBytes = 0
  224. if self.handle is None:
  225. raise LabJackException("The device handle is None.")
  226. if(isinstance(self.handle, LJSocketHandle)):
  227. return self._readFromLJSocketHandle(numBytes, modbus, stream)
  228. elif(isinstance(self.handle, UE9TCPHandle)):
  229. return self._readFromUE9TCPHandle(numBytes, stream, modbus)
  230. else:
  231. if(os.name == 'posix'):
  232. return self._readFromExodriver(numBytes, stream, modbus)
  233. elif os.name == 'nt':
  234. return self._readFromUDDriver(numBytes, stream, modbus)
  235. def _readFromLJSocketHandle(self, numBytes, modbus, spont = False):
  236. """
  237. Reads from LJSocket. Returns the result as a list.
  238. """
  239. if modbus:
  240. rcvString = self.handle.modbusSocket.recv(numBytes)
  241. elif spont:
  242. rcvString = self.handle.spontSocket.recv(numBytes)
  243. else:
  244. rcvString = self.handle.crSocket.recv(numBytes)
  245. readBytes = len(rcvString)
  246. packFormat = "B" * readBytes
  247. rcvDataBuff = struct.unpack(packFormat, rcvString)
  248. return list(rcvDataBuff)
  249. def _readFromUE9TCPHandle(self, numBytes, stream, modbus):
  250. if stream is True:
  251. rcvString = self.handle.stream.recv(numBytes)
  252. return rcvString
  253. else:
  254. if modbus is True:
  255. if self.handle.modbus is None:
  256. raise LabJackException("Modbus port is not available. Please upgrade to UE9 Comm firmware 1.43 or higher.")
  257. rcvString = self.handle.modbus.recv(numBytes)
  258. else:
  259. rcvString = self.handle.data.recv(numBytes)
  260. readBytes = len(rcvString)
  261. packFormat = "B" * readBytes
  262. rcvDataBuff = struct.unpack(packFormat, rcvString)
  263. return list(rcvDataBuff)
  264. def _readFromExodriver(self, numBytes, stream, modbus):
  265. newA = (ctypes.c_byte*numBytes)()
  266. if(stream):
  267. readBytes = staticLib.LJUSB_Stream(self.handle, ctypes.byref(newA), numBytes)
  268. if readBytes == 0:
  269. return ''
  270. # return the byte string in stream mode
  271. return struct.pack('b' * readBytes, *newA)
  272. else:
  273. readBytes = staticLib.LJUSB_Read(self.handle, ctypes.byref(newA), numBytes)
  274. # return a list of integers in command/response mode
  275. return [(newA[i] & 0xff) for i in range(readBytes)]
  276. def _readFromUDDriver(self, numBytes, stream, modbus):
  277. if self.devType == 0x501:
  278. newA = (ctypes.c_byte*numBytes)()
  279. readBytes = skymoteLib.LJUSB_IntRead(self.handle, 0x81, ctypes.byref(newA), numBytes)
  280. return [(newA[i] & 0xff) for i in range(readBytes)]
  281. else:
  282. if modbus is True and self.devType == 9:
  283. tempBuff = [0] * (8 + numBytes + numBytes%2)
  284. eGetBuff = list()
  285. eGetBuff = eGetRaw(self.handle, LJ_ioRAW_IN, 0, len(tempBuff), tempBuff)[1]
  286. #parse the modbus response out (reponse is the Modbus extended low=level function)
  287. retBuff = list()
  288. if len(eGetBuff) >= 9 and eGetBuff[1] == 0xF8 and eGetBuff[3] == 0x07:
  289. #figuring out the length of the modbus response
  290. mbSize = len(eGetBuff) - 8
  291. if len(eGetBuff) >= 14:
  292. mbSize = min(mbSize, eGetBuff[13] + 6)
  293. i = min(mbSize, numBytes)
  294. i = max(i, 0)
  295. retBuff = eGetBuff[8:8+i] #getting the response only
  296. return retBuff
  297. tempBuff = [0] * numBytes
  298. if stream:
  299. return eGetRaw(self.handle, LJ_ioRAW_IN, 1, numBytes, tempBuff)[1]
  300. return eGetRaw(self.handle, LJ_ioRAW_IN, 0, numBytes, tempBuff)[1]
  301. def readRegister(self, addr, numReg = None, format = None, unitId = None):
  302. """ Reads a specific register from the device and returns the value.
  303. Requires Modbus.py
  304. readHoldingRegister(addr, numReg = None, format = None)
  305. addr: The address you would like to read
  306. numReg: Number of consecutive addresses you would like to read
  307. format: the unpack format of the returned value ( '>f' or '>I')
  308. Modbus is supported for UE9s over USB from Comm Firmware 1.50 and above.
  309. """
  310. pkt, numBytes = self._buildReadRegisterPacket(addr, numReg, unitId)
  311. response = self._modbusWriteRead(pkt, numBytes)
  312. return self._parseReadRegisterResponse(response, numBytes, addr, format, numReg)
  313. def _buildReadRegisterPacket(self, addr, numReg, unitId):
  314. """
  315. self._buildReadRegisterPacket(addr, numReg)
  316. Builds a raw modbus "Read Register" packet to be written to a device
  317. returns a tuple:
  318. ( < Packet as a list >, < number of bytes to read > )
  319. """
  320. # Calculates the number of registers for that request, or if numReg is
  321. # specified, checks that it is a valid number.
  322. numReg = Modbus.calcNumberOfRegisters(addr, numReg = numReg)
  323. pkt = Modbus.readHoldingRegistersRequest(addr, numReg = numReg, unitId = unitId)
  324. pkt = [ ord(c) for c in pkt ]
  325. numBytes = 9 + (2 * int(numReg))
  326. return (pkt, numBytes)
  327. def _parseReadRegisterResponse(self, response, numBytes, addr, format, numReg = None):
  328. """
  329. self._parseReadRegisterReponse(reponse, numBytes, addr, format)
  330. Takes a "Read Register" response and converts it to a value
  331. returns the value
  332. """
  333. if len(response) != numBytes:
  334. raise LabJackException(9001, "Got incorrect number of bytes from device. Expected %s bytes, got %s bytes. The packet recieved was: %s" % (numBytes, len(response),response))
  335. if isinstance(response, list):
  336. packFormat = ">" + "B" * numBytes
  337. response = struct.pack(packFormat, *response)
  338. if format == None:
  339. format = Modbus.calcFormat(addr, numReg)
  340. value = Modbus.readHoldingRegistersResponse(response, payloadFormat=format)
  341. return value
  342. def writeRegister(self, addr, value, unitId = None):
  343. """
  344. Writes a value to a register. Returns the value to be written, if successful.
  345. Requires Modbus.py
  346. writeRegister(self, addr, value)
  347. addr: The address you want to write to.
  348. value: The value, or list of values, you want to write.
  349. if you cannot write to that register, a LabJackException is raised.
  350. Modbus is not supported for UE9's over USB. If you try it, a LabJackException is raised.
  351. """
  352. pkt, numBytes = self._buildWriteRegisterPacket(addr, value, unitId)
  353. response = self._modbusWriteRead(pkt, numBytes)
  354. return self._parseWriteRegisterResponse(response, pkt, value)
  355. def _buildWriteRegisterPacket(self, addr, value, unitId):
  356. """
  357. self._buildWriteRegisterPacket(addr, value)
  358. Builds a raw modbus "Write Register" packet to be written to a device
  359. returns a tuple:
  360. ( < Packet as a list >, < number of bytes to read > )
  361. """
  362. if type(value) is list:
  363. return self._buildWriteMultipleRegisters(addr, value, unitId)
  364. fmt = Modbus.calcFormat(addr)
  365. if fmt != '>H':
  366. return self._buildWriteFloatToRegister(addr, value, unitId, fmt)
  367. request = Modbus.writeRegisterRequest(addr, value, unitId)
  368. request = [ ord(c) for c in request ]
  369. numBytes = 12
  370. return request, numBytes
  371. def _buildWriteFloatToRegister(self, addr, value, unitId, fmt = '>f'):
  372. numReg = 2
  373. if not isinstance(value, int) and not isinstance(value, float):
  374. raise TypeError("Value must be a float or int.")
  375. # Function, Address, Num Regs, Byte count, Data
  376. payload = struct.pack('>BHHB', 0x10, addr, 0x02, 0x04) + struct.pack(fmt, value)
  377. request = Modbus._buildHeaderBytes(length = len(payload)+1, unitId = unitId)
  378. request += payload
  379. request = [ ord(c) for c in request ]
  380. numBytes = 12
  381. return (request, numBytes)
  382. def _buildWriteMultipleRegisters(self, startAddr, values, unitId = None):
  383. request = Modbus.writeRegistersRequest(startAddr, values, unitId)
  384. request = [ ord(c) for c in request ]
  385. numBytes = 12
  386. return (request, numBytes)
  387. def _parseWriteRegisterResponse(self, response, request, value):
  388. response = list(response)
  389. if request[2] != 0 and request[3] != 0:
  390. protoID = (request[2] << 8) + request[3]
  391. raise Modbus.ModbusException("Got an unexpected protocol ID: %s (expected 0). Please make sure that you have the latest firmware. UE9s need a Comm Firmware of 1.50 or greater.\n\nThe packet you received: %s" % (protoID, hexWithoutQuotes(response)))
  392. if request[7] != response[7]:
  393. raise LabJackException(9002, "Modbus error number %s raised while writing to register. Make sure you're writing to an address that allows writes.\n\nThe packet you received: %s" % (response[8], hexWithoutQuotes(response)))
  394. return value
  395. def setDIOState(self, IOnum, state):
  396. value = (int(state) & 0x01)
  397. self.writeRegister(6000+IOnum, value)
  398. return True
  399. def _modbusWriteRead(self, request, numBytes):
  400. with self.deviceLock:
  401. self.write(request, modbus = True, checksum = False)
  402. try:
  403. result = self.read(numBytes, modbus = True)
  404. if self.debug: print "Response: ", hexWithoutQuotes(result)
  405. return result
  406. except LabJackException:
  407. self.write(request, modbus = True, checksum = False)
  408. result = self.read(numBytes, modbus = True)
  409. if self.debug: print "Response: ", hexWithoutQuotes(result)
  410. return result
  411. def _checkCommandBytes(self, results, commandBytes):
  412. """
  413. Checks all the stuff from a command
  414. """
  415. size = len(commandBytes)
  416. if len(results) == 0:
  417. raise LabJackException("Got a zero length packet.")
  418. elif results[0] == 0xB8 and results[1] == 0xB8:
  419. raise LabJackException("Device detected a bad checksum.")
  420. elif results[1:(size+1)] != commandBytes:
  421. raise LabJackException("Got incorrect command bytes.\nExpected: %s\nGot: %s\nFull packet: %s" % (hexWithoutQuotes(commandBytes), hexWithoutQuotes(results[1:(size+1)]), hexWithoutQuotes(results)))
  422. elif not verifyChecksum(results):
  423. raise LabJackException("Checksum was incorrect.")
  424. elif results[6] != 0:
  425. raise LowlevelErrorException(results[6], "\nThe %s returned an error:\n %s" % (self.deviceName , lowlevelErrorToString(results[6])) )
  426. def _writeRead(self, command, readLen, commandBytes, checkBytes = True, stream=False, checksum = True):
  427. # Acquire the device lock.
  428. with self.deviceLock:
  429. self.write(command, checksum = checksum)
  430. result = self.read(readLen, stream=False)
  431. if self.debug: print "Response: ", hexWithoutQuotes(result)
  432. if checkBytes:
  433. self._checkCommandBytes(result, commandBytes)
  434. return result
  435. def ping(self):
  436. try:
  437. if self.devType == LJ_dtUE9:
  438. writeBuffer = [0x70, 0x70]
  439. self.write(writeBuffer)
  440. try:
  441. self.read(2)
  442. except LabJackException:
  443. self.write(writeBuffer)
  444. self.read(2)
  445. return True
  446. if self.devType == LJ_dtU3:
  447. writeBuffer = [0, 0xf8, 0x01, 0x2a, 0, 0, 0, 0]
  448. writeBuffer = setChecksum(writeBuffer)
  449. self.write(writeBuffer)
  450. self.read(40)
  451. return True
  452. return False
  453. except Exception, e:
  454. print e
  455. return False
  456. def open(self, devType, Ethernet=False, firstFound = True, serial = None, localId = None, devNumber = None, ipAddress = None, handleOnly = False, LJSocket = None):
  457. """
  458. Device.open(devType, Ethernet=False, firstFound = True, serial = None, localId = None, devNumber = None, ipAddress = None, handleOnly = False, LJSocket = None)
  459. Open a device of type devType.
  460. """
  461. if self.handle is not None:
  462. raise LabJackException(9000,"Open called on a device with a handle. Please close the device, and try again. Your device is probably already open.\nLook for lines of code that look like this:\nd = u3.U3()\nd.open() # Wrong! Device is already open.")
  463. ct = LJ_ctUSB
  464. if Ethernet:
  465. ct = LJ_ctETHERNET
  466. if LJSocket is not None:
  467. ct = LJ_ctLJSOCKET
  468. d = None
  469. if devNumber:
  470. d = openLabJack(devType, ct, firstFound = False, devNumber = devNumber, handleOnly = handleOnly, LJSocket = LJSocket)
  471. elif serial:
  472. d = openLabJack(devType, ct, firstFound = False, pAddress = serial, handleOnly = handleOnly, LJSocket = LJSocket)
  473. elif localId:
  474. d = openLabJack(devType, ct, firstFound = False, pAddress = localId, handleOnly = handleOnly, LJSocket = LJSocket)
  475. elif ipAddress:
  476. d = openLabJack(devType, ct, firstFound = False, pAddress = ipAddress, handleOnly = handleOnly, LJSocket = LJSocket)
  477. elif LJSocket:
  478. d = openLabJack(devType, ct, handleOnly = handleOnly, LJSocket = LJSocket)
  479. elif firstFound:
  480. d = openLabJack(devType, ct, firstFound = True, handleOnly = handleOnly, LJSocket = LJSocket)
  481. else:
  482. raise LabJackException("You must use first found, or give a localId, devNumber, or IP Address")
  483. self.handle = d.handle
  484. if not handleOnly:
  485. self._loadChangedIntoSelf(d)
  486. self._registerAtExitClose()
  487. def _loadChangedIntoSelf(self, d):
  488. for key, value in d.changed.items():
  489. self.__setattr__(key, value)
  490. def _registerAtExitClose(self):
  491. if not self._autoCloseSetup:
  492. # Only need to register auto-close once per device.
  493. atexit.register(self.close)
  494. self._autoCloseSetup = True
  495. def close(self):
  496. """close()
  497. This function is not specifically supported in the LabJackUD driver
  498. for Windows and so simply calls the UD function Close. For Mac and unix
  499. drivers, this function MUST be performed when finished with a device.
  500. The reason for this close is because there can not be more than one program
  501. with a given device open at a time. If a device is not closed before
  502. the program is finished it may still be held open and unable to be used
  503. by other programs until properly closed.
  504. For Windows, Linux, and Mac
  505. """
  506. if isinstance(self.handle, UE9TCPHandle) or isinstance(self.handle, LJSocketHandle):
  507. self.handle.close()
  508. elif os.name == 'posix':
  509. staticLib.LJUSB_CloseDevice(self.handle)
  510. elif self.devType == 0x501:
  511. skymoteLib.LJUSB_CloseDevice(self.handle)
  512. self.handle = None
  513. def reset(self):
  514. """Reset the LabJack device.
  515. For Windows, Linux, and Mac
  516. Sample Usage:
  517. >>> u3 = OpenLabJack(LJ_dtU3, LJ_ctUSB, "0", 1)
  518. >>> u3.reset()
  519. @type None
  520. @param Function takes no arguments
  521. @rtype: None
  522. @return: Function returns nothing.
  523. @raise LabJackException:
  524. """
  525. if os.name == 'nt':
  526. staticLib = ctypes.windll.LoadLibrary("labjackud")
  527. ec = staticLib.ResetLabJack(self.handle)
  528. if ec != 0: raise LabJackException(ec)
  529. elif os.name == 'posix':
  530. sndDataBuff = [0] * 4
  531. #Make the reset packet
  532. sndDataBuff[0] = 0x9B
  533. sndDataBuff[1] = 0x99
  534. sndDataBuff[2] = 0x02
  535. try:
  536. self.write(sndDataBuff)
  537. rcvDataBuff = self.read(4)
  538. if(len(rcvDataBuff) != 4):
  539. raise LabJackException(0, "Unable to reset labJack 2")
  540. except Exception, e:
  541. raise LabJackException(0, "Unable to reset labjack: %s" % str(e))
  542. def breakupPackets(self, packets, numBytesPerPacket):
  543. """
  544. Name: Device.breakupPackets
  545. Args: packets, a string or list of packets
  546. numBytesPerPacket, how big each packe is
  547. Desc: This function will break up a list into smaller chunks and return
  548. each chunk one at a time.
  549. >>> l = range(15)
  550. >>> for packet in d.breakupPackets(l, 5):
  551. ... print packet
  552. [ 0, 1, 2, 3, 4 ]
  553. [ 5, 6, 7, 8, 9 ]
  554. [ 10, 11, 12, 13, 14]
  555. """
  556. start, end = 0, numBytesPerPacket
  557. while end <= len(packets):
  558. yield packets[start:end]
  559. start, end = end, end + numBytesPerPacket
  560. def samplesFromPacket(self, packet):
  561. """
  562. Name: Device.samplesFromPacket
  563. Args: packet, a packet of stream data
  564. Desc: This function breaks a packet into all the two byte samples it
  565. contains and returns them one at a time.
  566. >>> packet = range(16) # fake packet with 1 sample in it
  567. >>> for sample in d.samplesFromPacket(packet):
  568. ... print sample
  569. [ 12, 13 ]
  570. """
  571. HEADER_SIZE = 12
  572. FOOTER_SIZE = 2
  573. BYTES_PER_PACKET = 2
  574. l = str(packet)
  575. l = l[HEADER_SIZE:]
  576. l = l[:-FOOTER_SIZE]
  577. while len(l) > 0:
  578. yield l[:BYTES_PER_PACKET]
  579. l = l[BYTES_PER_PACKET:]
  580. def streamStart(self):
  581. """
  582. Name: Device.streamStart()
  583. Args: None
  584. Desc: Starts streaming on the device.
  585. Note: You must call streamConfig() before calling this function.
  586. """
  587. if not self.streamConfiged:
  588. raise LabJackException("Stream must be configured before it can be started.")
  589. if self.streamStarted:
  590. raise LabJackException("Stream already started.")
  591. command = [ 0xA8, 0xA8 ]
  592. results = self._writeRead(command, 4, [], False, False, False)
  593. if results[2] != 0:
  594. raise LowlevelErrorException(results[2], "StreamStart returned an error:\n %s" % lowlevelErrorToString(results[2]) )
  595. self.streamStarted = True
  596. def streamData(self, convert=True):
  597. """
  598. Name: Device.streamData()
  599. Args: convert, should the packets be converted as they are read.
  600. set to False to get much faster speeds, but you will
  601. have to process the results later.
  602. Desc: Reads stream data from a LabJack device. See our stream example
  603. to get an idea of how this function should be called. The return
  604. value of streamData is a dictionary with the following keys:
  605. * errors: The number of errors in this block.
  606. * numPackets: The number of USB packets collected to return this
  607. block.
  608. * missed: The number of readings that were missed because of
  609. buffer overflow on the LabJack.
  610. * firstPacket: The PacketCounter value in the first USB packet.
  611. * result: The raw bytes returned from read(). The only way to get
  612. data if called with convert = False.
  613. * AINi, where i is an entry in the passed in PChannels. If called
  614. with convert = True, this is a list of all the readings
  615. in this block.
  616. Note: You must start the stream by calling streamStart() before calling
  617. this function.
  618. """
  619. if not self.streamStarted:
  620. raise LabJackException("Please start streaming before reading.")
  621. numBytes = 14 + (self.streamSamplesPerPacket * 2)
  622. while True:
  623. result = self.read(numBytes * self.packetsPerRequest, stream = True)
  624. if len(result) == 0:
  625. yield None
  626. continue
  627. numPackets = len(result) // numBytes
  628. errors = 0
  629. missed = 0
  630. firstPacket = ord(result[10])
  631. for i in range(numPackets):
  632. e = ord(result[11+(i*numBytes)])
  633. if e != 0:
  634. errors += 1
  635. if self.debug and e != 60 and e != 59: print e
  636. if e == 60:
  637. missed += struct.unpack('<I', result[6+(i*numBytes):10+(i*numBytes)] )[0]
  638. returnDict = dict(numPackets = numPackets, result = result, errors = errors, missed = missed, firstPacket = firstPacket )
  639. if convert:
  640. returnDict.update(self.processStreamData(result, numBytes = numBytes))
  641. yield returnDict
  642. def streamStop(self):
  643. """
  644. Name: Device.streamStop()
  645. Args: None
  646. Desc: Stops streaming on the device.
  647. """
  648. command = [ 0xB0, 0xB0 ]
  649. results = self._writeRead(command, 4, [], False, False, False)
  650. if results[2] != 0:
  651. raise LowlevelErrorException(results[2], "StreamStop returned an error:\n %s" % lowlevelErrorToString(results[2]) )
  652. self.streamStarted = False
  653. def getName(self):
  654. """
  655. Name: Device.getName()
  656. Args: None
  657. Desc: Returns the name of a device.
  658. Always returns a unicode string.
  659. Works as of the following firmware versions:
  660. U6 - 1.00
  661. U3 - 1.22
  662. UE9 - 2.00
  663. >>> d = u3.U3()
  664. >>> d.open()
  665. >>> d.getName()
  666. u'My LabJack U3'
  667. """
  668. name = list(self.readRegister(58000, format='B'*48, numReg = 24))
  669. if name[1] == 3:
  670. # Old style string
  671. name = "My %s" % self.deviceName
  672. if self.debug: print "Old UTF-16 name detected, replacing with %s" % name
  673. self.setName(name)
  674. name = name.decode("UTF-8")
  675. else:
  676. try:
  677. end = name.index(0x00)
  678. name = struct.pack("B"*end, *name[:end]).decode("UTF-8")
  679. except ValueError:
  680. name = "My %s" % self.deviceName
  681. if self.debug: print "Invalid name detected, replacing with %s" % name
  682. self.setName(name)
  683. name = name.decode("UTF-8")
  684. return name
  685. def setName(self, name = "My LabJack U3"):
  686. """
  687. Name: Device.setName(name = ""My LabJack U3")
  688. Args: name, the name you'd like to assign the the U3
  689. Desc: Writes a new name to the device.
  690. Names a limited to 30 characters or less.
  691. Works as of the following firmware versions:
  692. U6 - 1.00
  693. U3 - 1.22
  694. UE9 - 2.00
  695. >>> d = u3.U3()
  696. >>> d.open()
  697. >>> d.getName()
  698. u'My LabJack U3'
  699. >>> d.setName("Johann")
  700. >>> d.getName()
  701. u'Johann'
  702. """
  703. strLen = len(name)
  704. if strLen > 47:
  705. raise LabJackException("The name is too long, must be less than 48 characters.")
  706. newname = name.encode('UTF-8')
  707. bl = list(struct.unpack("B"*strLen, newname)) + [0x00]
  708. strLen += 1
  709. if strLen%2 != 0:
  710. bl = bl + [0x00]
  711. strLen += 1
  712. bl = struct.unpack(">"+"H"*(strLen/2), struct.pack("B" * strLen, *bl))
  713. self.writeRegister(58000, list(bl))
  714. name = property(getName, setName)
  715. def setDefaults(self, SetToFactoryDefaults = False):
  716. """
  717. Name: Device.setDefaults(SetToFactoryDefaults = False)
  718. Args: SetToFactoryDefaults, set to True reset to factory defaults.
  719. Desc: Executing this function causes the current or last used values
  720. (or the factory defaults) to be stored in flash as the power-up
  721. defaults.
  722. >>> myU6 = U6()
  723. >>> myU6.setDefaults()
  724. """
  725. command = [ 0 ] * 8
  726. #command[0] = Checksum8
  727. command[1] = 0xF8
  728. command[2] = 0x01
  729. command[3] = 0x0E
  730. #command[4] = Checksum16 (LSB)
  731. #command[5] = Checksum16 (MSB)
  732. command[6] = 0xBA
  733. command[7] = 0x26
  734. if SetToFactoryDefaults:
  735. command[6] = 0x82
  736. command[7] = 0xC7
  737. self._writeRead(command, 8, [ 0xF8, 0x01, 0x0E ] )
  738. def setToFactoryDefaults(self):
  739. return self.setDefaults(SetToFactoryDefaults = True)
  740. validDefaultBlocks = range(8)
  741. def readDefaults(self, BlockNum, ReadCurrent = False):
  742. """
  743. Name: Device.readDefaults(BlockNum)
  744. Args: BlockNum, which block to read. Must be 0-7.
  745. ReadCurrent, True = read current configuration
  746. Desc: Reads the power-up defaults from flash.
  747. >>> myU6 = U6()
  748. >>> myU6.readDefaults(0)
  749. [ 0, 0, ... , 0]
  750. """
  751. if BlockNum not in self.validDefaultBlocks:
  752. raise LabJackException("Defaults must be in range 0-7")
  753. byte7 = (int(bool(ReadCurrent)) << 7) + BlockNum
  754. command = [ 0, 0xF8, 0x01, 0x0E, 0, 0, 0, byte7 ]
  755. result = self._writeRead(command, 40, [ 0xF8, 0x11, 0x0E ])
  756. return result[8:]
  757. def readCurrent(self, BlockNum):
  758. self.readDefaults(BlockNum, ReadCurrent = True)
  759. def loadGenericDevice(self, device):
  760. """ Take a generic Device object, and loads it into the current object.
  761. The generic Device is consumed in the process.
  762. """
  763. self.handle = device.handle
  764. self._loadChangedIntoSelf(device)
  765. self._registerAtExitClose()
  766. device = None
  767. # --------------------- BEGIN LabJackPython ---------------------------------
  768. def setChecksum(command):
  769. """Returns a command with checksums places in the proper locations
  770. For Windows, Mac, and Linux
  771. Sample Usage:
  772. >>> from LabJackPython import *
  773. >>> command = [0] * 12
  774. >>> command[1] = 0xf8
  775. >>> command[2] = 0x03
  776. >>> command[3] = 0x0b
  777. >>> command = SetChecksum(command)
  778. >>> command
  779. [7, 248, 3, 11, 0, 0, 0, 0, 0, 0, 0, 0]
  780. @type command: List
  781. @param command: The command by which to calculate the checksum
  782. @rtype: List
  783. @return: A command list with checksums in the proper locations.
  784. """
  785. if len(command) < 8:
  786. raise LabJackException("Command does not contain enough bytes.")
  787. try:
  788. a = command[1]
  789. a = (a & 0x78) >> 3
  790. #Check if the command is an extended command
  791. if a == 15:
  792. command = setChecksum16(command)
  793. command = setChecksum8(command, 6)
  794. return command
  795. else:
  796. command = setChecksum8(command, len(command))
  797. return command
  798. except LabJackException, e:
  799. raise e
  800. except Exception, e:
  801. raise LabJackException("SetChecksum Exception:" + str(e))
  802. def verifyChecksum(buffer):
  803. """Verifies the checksum of a given buffer using the traditional U3/UE9 Command Structure.
  804. """
  805. buff0 = buffer[0]
  806. buff4 = buffer[4]
  807. buff5 = buffer[5]
  808. tempBuffer = setChecksum(buffer)
  809. if (buff0 == tempBuffer[0]) and (buff4 == tempBuffer[4]) \
  810. and (buff5 == tempBuffer[5]):
  811. return True
  812. return False
  813. # 1 = LJ_ctUSB
  814. def listAll(deviceType, connectionType = 1):
  815. """listAll(deviceType, connectionType) -> [[local ID, Serial Number, IP Address], ...]
  816. Searches for all devices of a given type over a given connection type and returns a list
  817. of all devices found.
  818. WORKS on WINDOWS, MAC, UNIX
  819. """
  820. if connectionType == LJ_ctLJSOCKET:
  821. ipAddress, port = deviceType.split(":")
  822. port = int(port)
  823. serverSocket = socket.socket()
  824. serverSocket.connect((ipAddress, port))
  825. serverSocket.settimeout(10)
  826. f = serverSocket.makefile(bufsize = 0)
  827. f.write("scan\r\n")
  828. l = f.readline().strip()
  829. try:
  830. status, numLines = l.split(' ')
  831. except ValueError:
  832. raise Exception("Got invalid line from server: %s" % l)
  833. if status.lower().startswith('ok'):
  834. lines = []
  835. marked = None
  836. for i in range(int(numLines)):
  837. l = f.readline().strip()
  838. dev = parseline(l)
  839. lines.append(dev)
  840. f.close()
  841. serverSocket.close()
  842. #print "Result of scan:"
  843. #print lines
  844. return lines
  845. if deviceType == 12:
  846. if U12DriverPresent():
  847. u12Driver = ctypes.windll.LoadLibrary("ljackuw")
  848. # Setup all the ctype arrays
  849. pSerialNumbers = (ctypes.c_long * 127)(0)
  850. pIDs = (ctypes.c_long * 127)(0)
  851. pProdID = (ctypes.c_long * 127)(0)
  852. pPowerList = (ctypes.c_long * 127)(0)
  853. pCalMatrix = (ctypes.c_long * 2540)(0)
  854. pNumFound = ctypes.c_long()
  855. pFcdd = ctypes.c_long(0)
  856. pHvc = ctypes.c_long(0)
  857. #Output dictionary
  858. deviceList = {}
  859. ec = u12Driver.ListAll(ctypes.cast(pProdID, ctypes.POINTER(ctypes.c_long)),
  860. ctypes.cast(pSerialNumbers, ctypes.POINTER(ctypes.c_long)),
  861. ctypes.cast(pIDs, ctypes.POINTER(ctypes.c_long)),
  862. ctypes.cast(pPowerList, ctypes.POINTER(ctypes.c_long)),
  863. ctypes.cast(pCalMatrix, ctypes.POINTER(ctypes.c_long)),
  864. ctypes.byref(pNumFound),
  865. ctypes.byref(pFcdd),
  866. ctypes.byref(pHvc))
  867. if ec != 0: raise LabJackException(ec)
  868. for i in range(pNumFound.value):
  869. deviceList[pSerialNumbers[i]] = { 'SerialNumber' : pSerialNumbers[i], 'Id' : pIDs[i], 'ProdId' : pProdID[i], 'powerList' : pPowerList[i] }
  870. return deviceList
  871. else:
  872. return {}
  873. if(os.name == 'nt'):
  874. if deviceType == 0x501:
  875. if skymoteLib is None:
  876. raise ImportError("Couldn't load liblabjackusb.dll. Please install, and try again.")
  877. num = skymoteLib.LJUSB_GetDevCount(0x501)
  878. deviceList = dict()
  879. for i in range(num):
  880. try:
  881. device = openLabJack(0x501, 1, firstFound = False, pAddress = None, devNumber = i+1)
  882. device.close()
  883. deviceList[str(device.serialNumber)] = device.__dict__
  884. except LabJackException:
  885. pass
  886. return deviceList
  887. pNumFound = ctypes.c_long()
  888. pSerialNumbers = (ctypes.c_long * 128)()
  889. pIDs = (ctypes.c_long * 128)()
  890. pAddresses = (ctypes.c_double * 128)()
  891. #The actual return variables so the user does not have to use ctypes
  892. serialNumbers = []
  893. ids = []
  894. addresses = []
  895. ec = staticLib.ListAll(deviceType, connectionType,
  896. ctypes.byref(pNumFound),
  897. ctypes.cast(pSerialNumbers, ctypes.POINTER(ctypes.c_long)),
  898. ctypes.cast(pIDs, ctypes.POINTER(ctypes.c_long)),
  899. ctypes.cast(pAddresses, ctypes.POINTER(ctypes.c_long)))
  900. if ec != 0 and ec != 1010: raise LabJackException(ec)
  901. deviceList = dict()
  902. for i in xrange(pNumFound.value):
  903. if pSerialNumbers[i] != 1010:
  904. deviceValue = dict(localId = pIDs[i], serialNumber = pSerialNumbers[i], ipAddress = DoubleToStringAddress(pAddresses[i]), devType = deviceType)
  905. deviceList[pSerialNumbers[i]] = deviceValue
  906. return deviceList
  907. if(os.name == 'posix'):
  908. if deviceType == LJ_dtUE9:
  909. return __listAllUE9Unix(connectionType)
  910. if deviceType == LJ_dtU3:
  911. return __listAllU3Unix()
  912. if deviceType == 6:
  913. return __listAllU6Unix()
  914. if deviceType == 0x501:
  915. return __listAllBridgesUnix()
  916. def isHandleValid(handle):
  917. if(os.name == 'nt'):
  918. return True
  919. else:
  920. return staticLib.LJUSB_IsHandleValid(handle)
  921. def deviceCount(devType = None):
  922. """Returns the number of devices connected. """
  923. if(os.name == 'nt'):
  924. if devType is None:
  925. numdev = len(listAll(3))
  926. numdev += len(listAll(9))
  927. numdev += len(listAll(6))
  928. if skymoteLib is not None:
  929. numdev += len(listAll(0x501))
  930. return numdev
  931. else:
  932. return len(listAll(devType))
  933. else:
  934. if devType == None:
  935. numdev = staticLib.LJUSB_GetDevCount(3)
  936. numdev += staticLib.LJUSB_GetDevCount(9)
  937. numdev += staticLib.LJUSB_GetDevCount(6)
  938. numdev += staticLib.LJUSB_GetDevCount(0x501)
  939. return numdev
  940. else:
  941. return staticLib.LJUSB_GetDevCount(devType)
  942. def getDevCounts():
  943. if os.name == "nt":
  944. # Right now there is no good way to count all the U12s on a Windows box
  945. return { 3 : len(listAll(3)), 6 : len(listAll(6)), 9 : len(listAll(9)), 1 : 0, 0x501 : len(listAll(0x501))}
  946. else:
  947. devCounts = (ctypes.c_uint*NUMBER_OF_UNIQUE_LABJACK_PRODUCT_IDS)()
  948. devIds = (ctypes.c_uint*NUMBER_OF_UNIQUE_LABJACK_PRODUCT_IDS)()
  949. n = ctypes.c_uint(NUMBER_OF_UNIQUE_LABJACK_PRODUCT_IDS)
  950. r = staticLib.LJUSB_GetDevCounts(ctypes.byref(devCounts), ctypes.byref(devIds), n)
  951. returnDict = dict()
  952. for i in range(NUMBER_OF_UNIQUE_LABJACK_PRODUCT_IDS):
  953. returnDict[int(devIds[i])] = int(devCounts[i])
  954. return returnDict
  955. def openAllLabJacks():
  956. if os.name == "nt":
  957. # Windows doesn't provide a nice way to open all the devices.
  958. devs = dict()
  959. devs[3] = listAll(3)
  960. devs[6] = listAll(6)
  961. devs[9] = listAll(9)
  962. devs[0x501] = listAll(0x501)
  963. devices = list()
  964. for prodId, numConnected in devs.items():
  965. for i, serial in enumerate(numConnected.keys()):
  966. d = Device(None, devType = prodId)
  967. if prodId == 0x501:
  968. d.open(prodId, devNumber = i)
  969. d = _makeDeviceFromHandle(d.handle, prodId)
  970. else:
  971. d.open(prodId, serial = serial)
  972. d = _makeDeviceFromHandle(d.handle, prodId)
  973. devices.append(d)
  974. else:
  975. maxHandles = 10
  976. devHandles = (ctypes.c_void_p*maxHandles)()
  977. devIds = (ctypes.c_uint*maxHandles)()
  978. n = ctypes.c_uint(maxHandles)
  979. numOpened = staticLib.LJUSB_OpenAllDevices(ctypes.byref(devHandles), ctypes.byref(devIds), n)
  980. devices = list()
  981. for i in range(numOpened):
  982. devices.append(_makeDeviceFromHandle(devHandles[i], int(devIds[i])))
  983. return devices
  984. def _openLabJackUsingLJSocket(deviceType, firstFound, pAddress, LJSocket, handleOnly ):
  985. if LJSocket is not '':
  986. ip, port = LJSocket.split(":")
  987. port = int(port)
  988. handle = LJSocketHandle(ip, port, deviceType, firstFound, pAddress)
  989. else:
  990. handle = LJSocketHandle('localhost', 6000, deviceType, firstFound, pAddress)
  991. return handle
  992. def _openLabJackUsingUDDriver(deviceType, connectionType, firstFound, pAddress, devNumber ):
  993. if devNumber is not None:
  994. devs = listAll(deviceType)
  995. pAddress = devs.keys()[(devNumber-1)]
  996. handle = ctypes.c_long()
  997. pAddress = str(pAddress)
  998. ec = staticLib.OpenLabJack(deviceType, connectionType,
  999. pAddress, firstFound, ctypes.byref(handle))
  1000. if ec != 0: raise LabJackException(ec)
  1001. devHandle = handle.value
  1002. return devHandle
  1003. def _openLabJackUsingExodriver(deviceType, firstFound, pAddress, devNumber):
  1004. devType = ctypes.c_ulong(deviceType)
  1005. openDev = staticLib.LJUSB_OpenDevice
  1006. openDev.restype = ctypes.c_void_p
  1007. if(devNumber != None):
  1008. handle = openDev(devNumber, 0, devType)
  1009. if handle <= 0:
  1010. raise NullHandleException()
  1011. return handle
  1012. elif(firstFound):
  1013. handle = openDev(1, 0, devType)
  1014. if handle <= 0:
  1015. print "handle: %s" % handle
  1016. raise NullHandleException()
  1017. return handle
  1018. else:
  1019. numDevices = staticLib.LJUSB_GetDevCount(deviceType)
  1020. for i in range(numDevices):
  1021. handle = openDev(i + 1, 0, devType)
  1022. try:
  1023. if handle <= 0:
  1024. raise NullHandleException()
  1025. device = _makeDeviceFromHandle(handle, deviceType)
  1026. except:
  1027. continue
  1028. if device.localId == pAddress or device.serialNumber == pAddress or device.ipAddress == pAddress:
  1029. return device
  1030. else:
  1031. device.close()
  1032. raise LabJackException(LJE_LABJACK_NOT_FOUND)
  1033. def _openUE9OverEthernet(firstFound, pAddress, devNumber):
  1034. if firstFound is not True and pAddress is not None:
  1035. #Check if valid IP address and attempt to get TCP handle
  1036. try:
  1037. socket.inet_aton(pAddress)
  1038. return UE9TCPHandle(pAddress)
  1039. except:
  1040. pass
  1041. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  1042. s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
  1043. s.settimeout(BROADCAST_SOCKET_TIMEOUT)
  1044. sndDataBuff = [0] * 6
  1045. sndDataBuff[0] = 0x22
  1046. sndDataBuff[1] = 0x78
  1047. sndDataBuff[3] = 0xa9
  1048. outBuff = ""
  1049. for item in sndDataBuff:
  1050. outBuff += chr(item)
  1051. s.sendto(outBuff, ("255.255.255.255", 52362))
  1052. try:
  1053. count = 1
  1054. while True:
  1055. rcvDataBuff = s.recv(128)
  1056. rcvDataBuff = [ord(val) for val in rcvDataBuff]
  1057. if verifyChecksum(rcvDataBuff):
  1058. #Parse the packet
  1059. macAddress = rcvDataBuff[28:34]
  1060. macAddress

Large files files are truncated, but you can click here to view the full file