def __init__(self, input, event, debounce = 0, timeout = None, target = None, vargs = (), kwargs = {}): super().__init__() self.input = input self.event = event self.target = target self.vargs = vargs self.kwargs = kwargs self.timeout = timeout self.debounce = 0 self.pipe = rcpy.create_pipe()
def read(self, timeout=None, pipe=None): # create pipe if necessary destroy_pipe = False if pipe is None: pipe = rcpy.create_pipe() destroy_pipe = True # request both edges and get file descriptor self.release() self.request(type=gpiod.LINE_REQ_EV_BOTH_EDGES) fdescriptor = self.line.event_get_fd() try: with os.fdopen(fdescriptor, 'rb', buffering=0) as f: # create poller poller = select.poll() poller.register( f, select.POLLPRI | select.POLLIN | select.POLLHUP | select.POLLERR) # listen to state change as well state_r_fd, state_w_fd = pipe poller.register( state_r_fd, select.POLLIN | select.POLLHUP | select.POLLERR) while rcpy.get_state() != rcpy.EXITING: # wait for events if timeout: # can fail if timeout is given events = poller.poll(timeout) if len(events) == 0: raise InputTimeout( 'Input did not change in more than {} ms'. format(timeout)) else: # timeout = None, never fails events = poller.poll() # check flags for fd, flag in events: # state change if fd is state_r_fd: # get state state = int(os.read(state_r_fd, 1)) if state == rcpy.EXITING: # exit! return # input event if fd == f.fileno(): # read event event = self.line.event_read() # Handle inputs if flag & (select.POLLIN | select.POLLPRI): # release line self.release() self.request(type=gpiod.LINE_REQ_DIR_IN) # return read value return self.get() elif flag & (select.POLLHUP | select.POLLERR): # raise exception raise Exception( 'Could not read input {}'.format(self)) finally: # release line self.release() self.request(type=gpiod.LINE_REQ_DIR_IN) # destroy pipe if destroy_pipe: rcpy.destroy_pipe(pipe)
def read(pin, timeout = None, pipe = None): # create pipe if necessary destroy_pipe = False if pipe is None: pipe = rcpy.create_pipe() destroy_pipe = True # open stream filename = SYSFS_GPIO_DIR + '/gpio{}/value'.format(pin) with open(filename, 'rb', buffering = 0) as f: # create poller poller = select.poll() f.read() poller.register(f, select.POLLPRI | select.POLLHUP | select.POLLERR) # listen to state change as well state_r_fd, state_w_fd = pipe poller.register(state_r_fd, select.POLLIN | select.POLLHUP | select.POLLERR) while rcpy.get_state() != rcpy.EXITING: # wait for events if timeout: # can fail if timeout is given events = poller.poll(timeout) if len(events) == 0: # destroy pipe if destroy_pipe: rcpy.destroy_pipe(pipe) # raise timeout exception raise InputTimeout('Input did not change in more than {} ms'.format(timeout)) else: # timeout = None, never fails events = poller.poll() for fd, flag in events: # state change if fd is state_r_fd: # get state state = int(os.read(state_r_fd, 1)) if state == rcpy.EXITING: # exit! if destroy_pipe: rcpy.destroy_pipe(pipe) return # input event if fd is f.fileno(): # Handle inputs if flag & (select.POLLIN | select.POLLPRI): # destroy pipe if destroy_pipe: rcpy.destroy_pipe(pipe) # return read value return get(pin) elif flag & (select.POLLHUP | select.POLLERR): # destroy pipe if destroy_pipe: rcpy.destroy_pipe(pipe) # raise exception raise Exception('Could not read pin {}'.format(pin)) # destroy pipe if destroy_pipe: rcpy.destroy_pipe(pipe)