Browse Source

Working event implementation and threaded device reads.

pyserial_fix
Scott Petersen 11 years ago
parent
commit
7c794fc498
7 changed files with 199 additions and 24 deletions
  1. +1
    -0
      .gitignore
  2. +1
    -0
      pyad2usb/__init__.py
  3. +85
    -24
      pyad2usb/ad2usb.py
  4. +1
    -0
      pyad2usb/event/__init__.py
  5. +71
    -0
      pyad2usb/event/event.py
  6. +1
    -0
      pyftdi
  7. +39
    -0
      test.py

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
*.pyc

+ 1
- 0
pyad2usb/__init__.py View File

@@ -0,0 +1 @@
__all__ = ['AD2USB', 'Device']

+ 85
- 24
pyad2usb/ad2usb.py View File

@@ -3,37 +3,59 @@ from pyftdi.pyftdi.usbtools import *
import time
import usb.core
import usb.util
from .event import event
import threading

class NoDeviceError(Exception):
pass

class AD2USB(object):
@classmethod
def find_all(cls):
cls.__devices = Device.find_all()
on_test = event.Event('testing')

on_open = event.Event('Called when the device has been opened')
on_close = event.Event('Called when the device has been closed')
on_read = event.Event('Called when a line has been read from the device')
on_write = event.Event('Called when data has been written to the device')

__devices = []

return cls.__devices
@classmethod
def find_all(cls):
cls.__devices = Device.find_all()

def __init__(self):
self._device = None
return cls.__devices

AD2USB.find_all()
def __init__(self):
self._device = None

def __del__(self):
pass
AD2USB.find_all()
pass

def open(self, device=None):
if len(cls.__devices) == 0:
raise NoDeviceError
def __del__(self):
pass

if device is None:
self._device = cls.__devices[0]
else
self._device = device
def open(self, device=None):
if len(self.__devices) == 0:
raise NoDeviceError

self._device.open()
if device is None:
device = self.__devices[0]

def close(self):
self._device.close()
self._device = None
self._device = Device(serial=device[2], description=device[4])

self._wire_events()

self._device.open()

def close(self):
self._device.close()
self._device = None

def _wire_events(self):
self._device.on_open += self.on_open
self._device.on_close += self.on_close
self._device.on_read += self.on_read
self._device.on_write += self.on_write


class Device(object):
@@ -41,14 +63,19 @@ class Device(object):
FTDI_PRODUCT_ID = 0x6001
BAUDRATE = 115200

on_open = event.Event('Called when the device has been opened')
on_close = event.Event('Called when the device has been closed')
on_read = event.Event('Called when a line has been read from the device')
on_write = event.Event('Called when data has been written to the device')

@staticmethod
def find_all():
devices = []

try:
devices = Ftdi.find_all([(FTDI_VENDOR_ID, FTDI_PRODUCT_ID)], nocache=True)
devices = Ftdi.find_all([(Device.FTDI_VENDOR_ID, Device.FTDI_PRODUCT_ID)], nocache=True)
except usb.core.USBError, e:
pass
print e

return devices

@@ -59,8 +86,13 @@ class Device(object):
self._description = description
self._buffer = ''
self._device = Ftdi()
self._running = False

self._read_thread = Device.ReadThread(self)

def open(self, baudrate=BAUDRATE, interface=0, index=0):
self._running = True

self._device.open(self._vendor_id,
self._product_id,
interface,
@@ -68,24 +100,34 @@ class Device(object):
self._serial_number,
self._description)

self.device.set_baudrate(baudrate)
self._device.set_baudrate(baudrate)
self._read_thread.start()

self.on_open((self._serial_number, self._description))

def close(self):
try:
self._running = False
self._read_thread.stop()

self._device.close()
except FtdiError, e:
pass

self.on_close()

def write(self, data):
self._device.write_data(data)

self.on_write(data)

def read_line(self, timeout=0.0):
start_time = time.time()
got_line = False
ret = None

try:
while 1:
while self._running:
buf = self._device.read_data(1)
self._buffer += buf

@@ -112,4 +154,23 @@ class Device(object):
ret = self._buffer
self._buffer = ''

self.on_read(ret)

return ret

class ReadThread(threading.Thread):
def __init__(self, device):
threading.Thread.__init__(self)
self._device = device
self._running = False

def stop(self):
self._running = False

def run(self):
self._running = True

while self._running:
self._device.read_line()

time.sleep(0.25)

+ 1
- 0
pyad2usb/event/__init__.py View File

@@ -0,0 +1 @@
__all__ = ['Event']

+ 71
- 0
pyad2usb/event/event.py View File

@@ -0,0 +1,71 @@
# event.py (improved)

class Event(object):

def __init__(self, doc=None):
self.__doc__ = doc

def __get__(self, obj, objtype=None):
if obj is None:
return self
return EventHandler(self, obj)

def __set__(self, obj, value):
pass


class EventHandler(object):

def __init__(self, event, obj):

self.event = event
self.obj = obj

def _getfunctionlist(self):

"""(internal use) """

try:
eventhandler = self.obj.__eventhandler__
except AttributeError:
eventhandler = self.obj.__eventhandler__ = {}
return eventhandler.setdefault(self.event, [])

def add(self, func):

"""Add new event handler function.

Event handler function must be defined like func(sender, earg).
You can add handler also by using '+=' operator.
"""

self._getfunctionlist().append(func)
return self

def remove(self, func):

"""Remove existing event handler function.

You can remove handler also by using '-=' operator.
"""

self._getfunctionlist().remove(func)
return self

def fire(self, earg=None):

"""Fire event and call all handler functions

You can call EventHandler object itself like e(earg) instead of
e.fire(earg).
"""

for func in self._getfunctionlist():
if type(func) == EventHandler:
func.fire(earg)
else:
func(self.obj, earg)

__iadd__ = add
__isub__ = remove
__call__ = fire

+ 1
- 0
pyftdi View File

@@ -0,0 +1 @@
../../pyftdi/pyftdi/

+ 39
- 0
test.py View File

@@ -0,0 +1,39 @@
import pyad2usb.ad2usb
import time
import signal

running = True

def signal_handler(signal, frame):
global running

running = False

def handle_open(sender, args):
print 'opened', args

def handle_close(sender, args):
print 'closed', args

def handle_read(sender, args):
print 'read', args

def handle_write(sender, args):
print 'write', args

signal.signal(signal.SIGINT, signal_handler)

#pyad2usb.ad2usb.AD2USB.find_all()

wut = pyad2usb.ad2usb.AD2USB()
wut.on_open += handle_open
wut.on_close += handle_close
wut.on_read += handle_read
wut.on_write += handle_write

wut.open()

while running:
time.sleep(0.1)

wut.close()

Loading…
Cancel
Save