Ejemplo n.º 1
0
 def __del__(self):
     """ Close all devices and stop timers """
     try:
         self.stop()
     except Exception as error:
         logger.error(
             'Error in destructor of main control! {0}'.format(error))
Ejemplo n.º 2
0
    def open(self):
        """
        Open an input event device for reading

        Tries to open the device path given to the constructor
        or search for all available input event devices.
        """
        device_paths = []
        if len(self.__inputDevicePath):
            device_paths = ["{0}".format(self.__inputDevicePath)]
        else:
            device_paths = glob.glob(
                '/dev/input/event*')  # search all available devices
        for path in device_paths:
            try:
                self.close()
                self.__inputDevice = InputDevice(path)
                self.__deviceOpenRetries = 0
                self.__inputDevicePath = path
                logger.debug('Opened RFID reader device \'{0}\''.format(path))
                time.sleep(1.0)  # prevent timing issues
                return
            except:
                if self.__deviceOpenRetries < 1:
                    logger.error(
                        'Unable to open USB RFID reader \'{0}\'!'.format(path))
                self.__inputDevice = None
                self.__deviceOpenRetries += 1
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    def _exec_queries(self, sqlQueries=[]):
        """ Execute given SQL statements

        Return results as one extended array
        """
        results = []
        sql = ""
        if self._dbfile is None:
            logger.error('Cannot execute SQL query! '
                         'Database filename "{0}" invalid!'.format(
                             self._dbfile))
            return results

        try:
            with sqlite3.connect(self._dbfile) as connection:
                cursor = connection.cursor()
                for query in sqlQueries:
                    sql = query
                    for row in cursor.execute(sql):
                        results.append(row)
                        if 0:
                            logger.debug('added query "{0}" results "{1}" '
                                         'to return value'.format(sql, row))
                    logger.debug('executed query "{0}"'.format(sql))
        except sqlite3.OperationalError as err:
            logger.error('{0}! query: {1}'.format(err, sql))
            return None
        return results
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
 def clear(self):
     """ Clears all text from LCD """
     try:
         if self.__outputDevice is not None:
             self.__outputDevice.lcd_clear()
     except:
         logger.error('Clearing lcd display failed!')
         self.close()
Ejemplo n.º 7
0
 def backlight(self, on=True):
     """ Switch LCD backlight on/off """
     try:
         if self.__outputDevice is not None:
             self.__outputDevice.lcd_backlight('ON' if on else 'OFF')
     except:
         logger.error('Switching display backlight failed!')
         self.close()
Ejemplo n.º 8
0
 def show(self, text, line=1):
     """ Displays given text on LCD at given line (1..n) """
     try:
         if self.__outputDevice is None:
             self.open()
         if self.__outputDevice is not None:
             self.__outputDevice.lcd_display_string(text, line)
     except:
         logger.error('Showing text on lcd failed!')
         self.close()
Ejemplo n.º 9
0
 def start(self):
     """ Init timers, reader and display user message """
     self.__running = True
     Thread.start(self)
     try:
         logger.debug('starting shower control...')
         time.sleep(1.0)
     except Exception as error:
         logger.error(
             'Error during starting main control! {0}'.format(error))
Ejemplo n.º 10
0
 def open(self):
     """ Open connection to LCD display """
     try:
         self.__outputDevice = lcddriver.lcd()
         if self.__outputDevice is None:
             raise RuntimeWarning
         self.__outputDevice.lcd_clear()
         time.sleep(1.0)  # prevent timing issues
     except:
         if self.__deviceOpenRetries < 1:
             logger.error('Unable to open HD44780 LCD display!')
         self.__outputDevice = None
         self.__deviceOpenRetries += 1
Ejemplo n.º 11
0
 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!')
Ejemplo n.º 12
0
    def tableExists(self, tableName):
        """ Check if given table exists

        Return True for existing table, False on any error
        """
        if tableName is None:
            logger.error('Invalid table name "{0}" given!'.format(tableName))
            return False

        sqls = [
            'SELECT name FROM sqlite_master '
            'WHERE type=\'table\' AND name=\'{0}\''.format(tableName)
        ]
        retval = self._exec_queries(sqls)
        return True if len(retval) and retval[0] is not None else False
Ejemplo n.º 13
0
    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))
Ejemplo n.º 14
0
    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
Ejemplo n.º 15
0
 def __init__(self, shower_id=1, shower_seconds=420):
     """ Init card reader, display and I/O controls """
     Thread.__init__(self)
     try:
         if shower_seconds < 30:
             logger.error('invalid shower time given! time must be > 30s')
             raise AttributeError()
         self.shower_id = shower_id
         self.shower_time = shower_seconds
         self._cardReader = UsbRfidReader()
         self._showerTimer = IOControlTimer(self.shower_time)
         self._relays = RelayControl(
             [self._gpio_cold_water, self._gpio_warm_water])
         self._display = LcdControl()
         self.__running = False
         time.sleep(1.0)
         logger.debug('shower control ready')
     except Exception as error:
         logger.error(
             'Error during init of main control! {0}'.format(error))
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
0
                        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


# command line execution
if __name__ == '__main__':
    rfidReader = UsbRfidReader('/dev/input/event2', 10)
    while True:
        try:
            code = rfidReader.readline()
            if code is not None:
                logger.debug('found a code: \'{0}\''.format(code))
            time.sleep(0.5)
        except KeyboardInterrupt:
            logger.debug('Key pressed - finishing now...')
            break
        except:
            logger.error('Unknown error received. Reading aborted!')
            break
Ejemplo n.º 18
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" PiShower project
    @copyright  Christian Daehn (c) 2006, http://3dh.de
    @license    MIT license
"""

import time
from pishowerutils import logger

try:
    import RPi.GPIO as GPIO
except RuntimeError:
    logger.error('Error importing RPi.GPIO! Superuser privileges needed!')
    quit(-1)


class RelayControl:
    """ Easy GPIO control to toggle relais """
    invertedLevels = True
    _state_on = GPIO.LOW
    _state_off = GPIO.HIGH
    _registered_outs = []

    def __init__(self, outports=[], inverted=True):
        """ Init GPIO interface """
        self.invertedLevels = inverted
        if not inverted:
            self._state_on, self._state_off = self._state_off, self._state_on
        self._states = {self._state_on: 'ON', self._state_off: 'OFF'}
Ejemplo n.º 19
0
    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))
Ejemplo n.º 20
0
        if self._display:
            self._display.show('Duschzeit {0:3d}min'.format(shower_time), 1)
            self._display.show('>>> Karte OK <<<', 2)

    def show_message_error(self):
        if self._display:
            self._display.show('Dusche {0}     AUS'.format(self.shower_id), 1)
            self._display.show('>>> STOERUNG <<<', 2)

    def show_message_stop(self):
        if self._display:
            self._display.show('Dusche {0}  BELEGT'.format(self.shower_id), 1)
            self._display.show('>>> GESPERRT <<<', 2)


# exec tests
if __name__ == "__main__":
    try:
        main = PiShowerMain(1, 40)
        main.start()

        while main.is_alive():
            time.sleep(0.2)

    except KeyboardInterrupt:
        logger.debug('Key pressed - finishing now...')
    except Exception as error:
        logger.error('Error in main control! {0}'.format(error))
    finally:
        main.stop()
Ejemplo n.º 21
0
                            logger.debug('added query "{0}" results "{1}" '
                                         'to return value'.format(sql, row))
                    logger.debug('executed query "{0}"'.format(sql))
        except sqlite3.OperationalError as err:
            logger.error('{0}! query: {1}'.format(err, sql))
            return None
        return results


# Run minimal test
if __name__ == '__main__':
    db = DBConnection()
    if db.tableExists('user'):
        db.deleteTable('user')
    else:
        logger.error('check for existing table failed!')
    db.createTable('user', ['id INTEGER', 'name', 'firstname', 'age INTEGER'])

    db.writeEntry('user', 'id', {
        'id': 2,
        'name': 'Wurst',
        'firstname': 'Hans',
        'age': 24
    })
    db.writeEntry('user', 'id', {
        'id': 2,
        'name': 'Wurst',
        'firstname': 'Hänschen',
        'age': 30
    })
Ejemplo n.º 22
0
    @copyright  Christian Daehn (c) 2006, http://3dh.de
    @license    MIT license
"""

import os
import sys
import time
from pishowerutils import logger

try:
    scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
    os.chdir(scriptPath)
    sys.path.append("./hd44780")
    import lcddriver
except RuntimeError:
    logger.error('Error importing hd44780 lcddriver!')
    quit(-1)


class LcdControl:
    """ Easy output to HD44780 based LCD displays """
    __outputDevice = None
    __deviceOpenRetries = 0

    def __init__(self):
        """ Init display interface """
        self.open()

    def __del__(self):
        """ Clear display interface """
        self.close()