def readline(self): """ Try reading a code from the input device and return it as string """ if self.__inputDevice is None: self.open() if self.__inputDevice is None: return None line = '' try: while True: event = self.__inputDevice.read_one() if event is None and line == '': # There are blank events in between characters, so we don't want # to break if we've started reading them break # start a new read. if event is None or event.type != ecodes.EV_KEY: continue data = categorize(event) # catch only keyup, and not Enter if data.keystate == 0 and data.scancode != 42: if data.scancode == 28: # looking return key to be pressed if len(line) < self.__minCodeLength: logger.warning( 'ignoring to small code: {0}'.format(line)) break else: logger.debug('code read: \'{0}\''.format(line)) return line else: line += self.__scancodes[data.scancode] except: logger.error('Parsing input stream failed!') self.close() return None
def createTable(self, tableName, fields, primaryKey=""): """ Create a table of given name with given fields name = SQLite table name, MUST NOT contain special chars+whitespaces fields = array of SQL table field names and type: e.g.: ['id INTEGER', 'msg', 'price REAL', 'name TEXT'] Return True on successs, False on any error """ if tableName is None: logger.error('Invalid table name "{0}" given!'.format(tableName)) return False if fields is None: logger.error('Invalid table fields "{0}" given!'.format(fields)) return False if self.tableExists(tableName) is True: logger.warning('DB table "{0}" cannot be created! ' 'Table already exists!'.format(tableName)) return False fieldStr = None for field in fields: if fieldStr is None: fieldStr = '{0}'.format(field) else: fieldStr = '{0}, {1}'.format(fieldStr, field) sqls = [] sqls.append('CREATE TABLE {0} ({1})'.format(tableName, fieldStr)) if primaryKey and not primaryKey.isspace(): sqls.append('CREATE UNIQUE INDEX index_{0}_{1} ' 'ON {0}({1})'.format(tableName, primaryKey)) retval = self._exec_queries(sqls) return True if retval is not None else False
def close(self): """ Close the input device and wait 1 second """ try: if self.__inputDevice is not None: self.__inputDevice.close() self.__inputDevice = None logger.debug('RFID input device closed') time.sleep(1.0) # prevent timing issues except: logger.warning('Error while closing RFID input device!')
def writeEntry(self, tableName, primaryKey, values={}): """ Insert or update a table entry with given values tableName - name of target table for insert/update of entry primaryKey - name of table primary key or selector column values - dictionary with field:value pairs of entry to write Return True on success, False on any error """ if tableName is None: logger.error('Invalid table name given!') return False if primaryKey is None: logger.error('Invalid table entry primary key given!') return False if values is False or primaryKey not in values: logger.error('Invalid table entry primary key given!') return False id = values[primaryKey] if self.tableExists(tableName) is False: logger.warning('Entry cannot be written! ' 'Table does not exist!'.format(tableName)) return False sqls = [ 'SELECT * FROM {0} WHERE {1} ' '= \'{2}\''.format(tableName, primaryKey, id) ] retval = self._exec_queries(sqls) if len(retval) and retval[0] is not None: logger.debug('Updating entry {0}="{1}"'.format(primaryKey, id)) sqls = [ 'UPDATE {0} SET {1} WHERE {2} = \'{3}\''.format( tableName, ', '.join("%s='%s'" % (k, v) for k, v in values.items()), primaryKey, id) ] else: logger.debug('Inserting new entry {0}="{1}"'.format( primaryKey, id)) sqls = [ 'INSERT INTO {0} ({1}) VALUES ({2})'.format( tableName, ', '.join("{0}".format(k) for k in values.keys()), ', '.join("'{0}'".format(values[k]) for k in values.keys())) ] retval = self._exec_queries(sqls) return True if retval is not None else False
def start(self): """ Starts the timer thread to execute _handle_timeout() and trigger the timeoutEvent """ if self._timer is not None: if self._timer.is_alive(): logger.warning('timer is already running!' ' cancelling timer to start new one.') self.stop() self._timer = threading.Timer(self.timeoutSeconds, self._handle_timeout) self._timer.start() logger.info('timer started')
def __update_sensors(self): """ Check for 1wire drivers and read available sensors """ try: # open 1-wire slaves list to read sensor ids file = open('/sys/devices/w1_bus_master1/w1_master_slaves') w1_slaves = file.read().splitlines() file.close() self.__sensors = w1_slaves if w1_slaves[0] is None: logger.warning('no 1-wire sensors found!') else: for s in w1_slaves: logger.debug('sensor found: {}'.format(s)) except: logger.error('Unable to read 1-wire device list!')
def toggle_output(self, port, value=-1): if port not in self._registered_outs: logger.warning('Cannot toggle unregistered GPIO {0}!'.format(port)) return if value is -1: value = GPIO.input(port) logger.debug('toggle GPIO {0} from {1} to {2}'.format( port, self._states[value], self._states[not value])) value = not value elif self.invertedLevels: value = not value state = GPIO.HIGH if value > 0 else GPIO.LOW GPIO.output(port, state) logger.debug('set GPIO {0} to {1}'.format(port, self._states[state])) time.sleep(0.01)
def stop(self): """ Close all valves (relays), stop timers and display warning """ try: logger.warning('stopping and locking shower control...') self.__running = False if self._showerTimer: self._showerTimer.stop() if self._relays: self._relays.toggle_output(self._gpio_cold_water, False) self._relays.toggle_output(self._gpio_warm_water, False) if self._display: self.show_message_error() except Exception as error: logger.error( 'Error during stopping main control! {0}'.format(error))
def deleteTable(self, tableName): """ Delete the given table Return True on success, False on any error """ if tableName is None: logger.error('Invalid table name "{0}" given!'.format(tableName)) return False if self.tableExists(tableName) is False: logger.warning('DB table "{0}" cannot be deleted! ' 'Table does not exist!'.format(tableName)) return False sqls = ['DROP TABLE {0}'.format(tableName)] retval = self._exec_queries(sqls) return True if retval is not None else False
def run(self): """ Handle card reader events and logic for shower control """ if self._cardReader is None: logger.error('No card reader available! Aborting!') self.stop() return if self._relays is None: logger.error('No I/O control for relays available! Aborting!') self.stop() return try: logger.debug('running main control loop...') self.show_message_ready() shower_active = False start_time = None while self.__running: code = self._cardReader.readline( ) # codes must be read to be cleared from buffer if shower_active: # a shower process was started code = None minutes_left = 0 # TODO: add minutes left calc here if self._showerTimer is None: logger.warning( 'No timer found! Stopped shower process!') shower_active = False self.show_message_ready() else: if not self._showerTimer.is_finished(): self.show_message_processing(minutes_left) else: logger.debug('stopped shower process on timeout') shower_active = False self.show_message_stop() if self._relays: self._relays.toggle_output( self._gpio_cold_water, False) self._relays.toggle_output( self._gpio_warm_water, False) time.sleep(6.0) self.show_message_ready() elif code is not None: # wait for request to start new shower process logger.debug('found a code: \'{0}\''.format( code)) # TODO: add validator here self.show_message_processing(self.shower_time // 60) shower_active = True if self._relays: self._relays.toggle_output(self._gpio_cold_water, True) self._relays.toggle_output(self._gpio_warm_water, True) if self._showerTimer: self._showerTimer.start() time.sleep(0.2) logger.debug('stopping main control loop...') except Exception as error: logger.error('Error in main control loop! {0}'.format(error))