def stop(self): self.run = False # write to pipe to abort os.write(self.pipe[1], bytes(str(rcpy.EXITING), 'UTF-8')) # sleep and destroy pipe time.sleep(1) rcpy.destroy_pipe(self.pipe) self.pipe = None
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)