Example #1
0
def runsendhandler(ser):
    # print('looking for message to send')
    try:
        lastqueuedmessage = pilib.getfirsttimerow(pilib.motesdatabase, 'queuedmessages', 'queuedtime')[0]
    except IndexError:
        # no rows
        # print('we have an error getting a queued message. Could be just no message.')
        pass
    else:
        print('I HAVE A MESSAE')
        # send queued message

        pilib.log(pilib.seriallog, 'Sending serial message: ' + lastqueuedmessage['message'], 1, 1)
        try:
            # print('going to send message:')
            # print(lastqueuedmessage['message'])
            ser.write(lastqueuedmessage['message'].encode())
            # sendserialmessage(ser, lastqueuedmessage['message'])
        except:
             pilib.log(pilib.seriallog, 'Error sending message', 1, 1)
        else:
            pilib.log(pilib.seriallog, 'Success sending message', 1, 1)

            conditionnames = ['queuedtime', 'message']
            conditionvalues = [lastqueuedmessage['queuedtime'], lastqueuedmessage['message']]
            delquery = pilib.makedeletesinglevaluequery('queuedmessages', {'conditionnames':conditionnames, 'conditionvalues':conditionvalues})
            pilib.sqlitequery(pilib.motesdatabase, delquery)
            pilib.sqliteinsertsingle(pilib.motesdatabase, 'sentmessages', [lastqueuedmessage['queuedtime'], pilib.gettimestring(), lastqueuedmessage['message']])
    return
Example #2
0
def application(environ, start_response):

    import cgi
    import json

    import os, sys, inspect

    # Set top folder to allow import of modules

    top_folder = os.path.split(os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0])))[0]
    if top_folder not in sys.path:
        sys.path.insert(0,top_folder)

    import cupid.pilib as pilib
    import cupid.controllib as controllib

    post_env = environ.copy()
    post_env['QUERY_STRING'] = ''
    post = cgi.FieldStorage(
        fp=environ['wsgi.input'],
        environ=post_env,
        keep_blank_values=True
    )

    formname=post.getvalue('name')
    output = {}
    output['message'] = 'Output Message: '
    d = {}
    for k in post.keys():
        d[k] = post.getvalue(k)

    status = '200 OK'
    wsgiauth = False
    authverified = False

    if wsgiauth:
        # Verfiy that session login information is legit: hashed password, with salt and username, match
        # hash stored in database.
        import hashlib
        from pilib import salt

        try:
            userdata = pilib.datarowtodict(pilib.usersdatabase, 'users', pilib.sqlitequery(pilib.usersdatabase, "select * from users where name='" + d['sessionuser'] + "'")[0])
        except:
            output['message'] += 'error in user sqlite query. '
            # unsuccessful authentication

        # Get session hpass to verify credentials
        hashedpassword = d['sessionhpass']
        hname = hashlib.new('sha1')
        hname.update(d['sessionuser'])
        hashedname = hname.hexdigest()
        hentry = hashlib.new('md5')
        hentry.update(hashedname + salt + hashedpassword)
        hashedentry = hentry.hexdigest()
        if hashedentry == userdata['password']:
            # successful auth
            output['message'] += 'Password verified. '
            authverified = True
    else:
        output['message'] += 'WSGI authorization not enabled. '

    if authverified or not wsgiauth:
        # Perform requested actions
        if 'action' in d:
            action = d['action']
            output['message'] += 'Found action. '
            if action == 'runquery':
                output['message'] += 'Query keyword found. '
                if 'query' in d:  # Take plain single query
                    result = pilib.sqlitequery(d['database'], d['query'])
                    output['response'] = result
                    output['message'] += 'Query executed. '
                elif 'queryarray[]' in d:  # Take query array, won't find
                    result = []
                    queryarray = d['queryarray[]']
                    for query in queryarray:
                        result.append(pilib.sqlitequery(d['database'], query))
                    output['response'] = result
                    output['message'] += 'Query array executed. '
            elif action == 'testmodule':
                output['message'] += 'Testing module: '
                if 'modulename' in d:
                    import cupid.cupidunittests
                    output['message'] += d['modulename']
                    output['data'] = cupid.cupidunittests.testmodule(d['modulename'])
                else:
                    output['message'] += 'Modulename not found. '
            elif action == 'testfunction':
                output['message'] += 'Testing function: '
                if 'testname' in d:
                    import cupid.cupidunittests
                    output['message'] += d['testname']
                    # output['data'] = cupid.tests.testfunction(d['testname'])
                    output['data'] = cupid.cupidunittests.testfunction(d['testname'])
                    # output['data'] = str(cupid.tests.testfunction('systemstatus'))
                else:
                    output['message'] += 'Testname not found. '
            elif action == 'dump':
                if 'database' in d and 'tablelist' in d and 'outputfile' in d:
                    pilib.sqlitedatadump(d['database'],d['tablelist'],d['outputfile'])
                    output['message'] = 'data dumped'
                elif 'database' in d and 'tablename' in d and 'outputfile' in d:
                    pilib.sqlitedatadump(d['database'],[d['tablename']],d['outputfile'])
                    output['message'] = 'data dumped'
                else:
                    data = 'keys not present for dump'
            elif action in ['userdelete', 'useradd', 'usermodify']:

                # Ensure that we are authorized for this action
                if userdata['authlevel'] >= 4:
                    output['message'] += 'User selected has sufficient authorizations. '
                    if action == 'userdelete':
                        try:
                            pilib.sqlitequery(pilib.usersdatabase, "delete from users where name='" + d['usertodelete'] + "'")
                        except:
                            output['message'] += 'Error in delete query. '
                        else:
                            output['message'] += 'Successful delete query. '
                    elif action == 'usermodify':
                        if 'usertomodify' in d:
                            querylist=[]
                            if 'newpass' in d:
                                # Get session hpass to verify credentials
                                hashedpassword = d['newpass']
                                hname = hashlib.new('sha1')
                                hname.update(d['usertomodify'])
                                hashedname = hname.hexdigest()
                                hentry = hashlib.new('md5')
                                hentry.update(hashedname + salt + hashedpassword)
                                hashedentry = hentry.hexdigest()
                                querylist.append('update users set password='******'" + d['usertomodify'] + "'")
                            if 'newemail' in d:
                                querylist.append("update users set email='" + d['newemail'] + "' where name='" + d['usertomodify'] + "'")
                            if 'newauthlevel' in d:
                                querylist.append("update users set authlevel='" + d['newauthlevel'] + "' where name='" + d['usertomodify'] + "'")

                            try:
                                pilib.sqlitemultquery(pilib.usersdatabase, querylist)
                            except:
                                output['message'] += 'Error in modify/add query: ' + ",".join(querylist)
                            else:
                                output['message'] += 'Successful modify/add query. ' + ",".join(querylist)
                        else:
                            output['message'] += 'Need usertomodify in query. '
                    elif action == 'useradd':
                        try:
                            username = d['newusername']
                        except:
                            username = '******'
                        try:
                            newemail = d['newemail']
                        except:
                            newemail = '*****@*****.**'
                        try:
                            newauthlevel = d['newauthlevel']
                        except:
                            newauthlevel = 0
                            query = "insert into users values(NULL,'" + username + "','','" + newemail + "',''," + str(newauthlevel) + ")"
                        try:
                            pilib.sqlitequery(pilib.usersdatabase, query)
                        except:
                            output['message'] += "Error in useradd sqlite query: " + query + ' . '
                        else:
                            output['message'] += "Successful query: " + query + ' . '
                    else:
                        output['message'] += 'Unable to verify password. '
                else:
                    output['message'] = 'insufficient authorization level for current user. '
            elif action == 'getfiletext':
                try:
                    filepath = d['filepath']
                    if 'numlines' in d:
                        numlines = int(d['numlines'])
                    else:
                        numlines = 9999
                    output['message'] += 'Using numlines: ' + str(numlines) + ' for read action. '
                    if 'startposition' in d:
                        startposition = d['startposition']
                    else:
                        startposition = 'end'
                    output['message'] += 'Reading from position ' + startposition + '. '
                except KeyError:
                    output['message'] += 'Sufficient keys for action getfile text do not exist. '
                except:
                    output['message'] += 'Uncaught error in getfiletext. '
                else:
                    try:
                        file = open(filepath)
                        lines = file.readlines()
                    except:
                        output['message'] += 'Error reading file in getfiletext action. '
                    else:
                        output['data'] = []
                        if startposition == 'end':
                            try:
                                output['data'] = pilib.tail(file, numlines)[0]
                            except:
                                output['message'] += 'Error in tail read. '
                        else:
                            linecount = 0
                            for line in lines:
                                linecount += 1
                                if linecount > numlines:
                                    break
                                else:
                                    output['data'].append(line)
            elif action == 'getmbtcpdata':
                try:
                    clientIP = d['clientIP']
                    register = d['register']
                    length = d['length']
                except KeyError:
                    output['message'] += 'Sufficient keys do not exist for the command. Requires clientIP, register, and length. '
                else:
                    from cupid.netfun import readMBcodedaddresses
                    # try:
                    output['response'] = readMBcodedaddresses(clientIP, int(register), int(length))
            elif action == 'queuemessage':
                output['message'] += 'Queue message. '
                if 'message' in d:
                    try:
                        pilib.sqliteinsertsingle(pilib.motesdatabase, 'queuedmessages', [pilib.gettimestring(), d['message']])
                    except Exception, e:
                        output['message'] += 'Error in queue insert query: ' + str(e)
                    else:
                        output['message'] += 'Message insert successful'
                else:
                    output['message'] += 'No message present. '
            elif action == 'setsystemflag' and 'systemflag' in d:
                database = pilib.systemdatadatabase
                pilib.setsinglevalue(database, 'systemflags', 'value', 1, "name=\'" + d['systemflag'] + "'")
            elif action == 'rundaemon':
                from cupiddaemon import rundaemon
                rundaemon()

            elif action == 'setvalue':
                pilib.log(pilib.controllog, "Setting value in wsgi", 1, 1)
                # we use the auxiliary 'setsinglecontrolvalue' to add additional actions to update
                if all(k in d for k in ('database', 'table', 'valuename', 'value')):
                    output['message'] += 'Carrying out setvalue. '
                    if 'condition' in d:
                        pilib.setsinglecontrolvalue(d['database'], d['table'], d['valuename'], d['value'], d['condition'])
                    elif 'index' in d:
                        condition = 'rowid= ' + d['index']
                        pilib.setsinglecontrolvalue(d['database'], d['table'], d['valuename'], d['value'], condition)
                    else:
                        pilib.setsinglecontrolvalue(d['database'], d['table'], d['valuename'], d['value'])
                else:
                    output['message'] += 'Insufficient data for setvalue '
            elif action == 'updateioinfo':
                if all(k in d for k in ['database', 'ioid', 'value']):
                    query = pilib.makesqliteinsert('ioinfo', [d['ioid'], d['value']], ['id', 'name'])
                    try:
                        pilib.sqliteinsertsingle(pilib.controldatabase, 'ioinfo', [d['ioid'], d['value']], ['id', 'name'])
                    except:
                        output['message'] += 'Error in updateioinfo query execution: ' + query +'. '
                        output['message'] += 'ioid: ' + d['ioid'] + ' . '
                    else:
                        output['message'] += 'Executed updateioinfo query. '
                else:
                    output['message'] += 'Insufficient data for updateioinfo query ! '

            # These are all very specific actions that could be rolled up or built into classes
            elif action == 'spchange' and 'database' in d:
                output['message'] += 'Spchanged. '
                if 'subaction' in d:
                    if d['subaction'] == 'incup':
                        controllib.incsetpoint(d['database'], d['channelname'])
                        output['message'] += 'incup. '
                    if d['subaction'] == 'incdown':
                        controllib.decsetpoint(d['database'], d['channelname'])
                        output['message'] += 'incdown. '
                    if d['subaction'] == 'setvalue':
                        controllib.setsetpoint(d['database'], d['channelname'], d['value'])
                        output['message'] += 'Setvalue: ' + d['database'] + ' ' + d['channelname'] + ' ' + d['value']
                else:
                    output['message'] += 'subaction not found. '
            elif action == 'togglemode' and 'database' in d:
                controllib.togglemode(d['database'], d['channelname'])
            elif action == 'setmode' and 'database' in d:
                controllib.setmode(d['database'], d['channelname'], d['mode'])
            elif action == 'setrecipe':
                controllib.setrecipe(d['database'], d['channelname'], d['recipe'])
            elif action == 'setcontrolinput':
                controllib.setcontrolinput(d['database'], d['channelname'], d['controlinput'])
            elif action == 'setchannelenabled':
                controllib.setchannelenabled(d['database'], d['channelname'], d['newstatus'])
            elif action == 'setchanneloutputsenabled':
                controllib.setchanneloutputsenabled(d['database'], d['channelname'], d['newstatus'])
            elif action == 'manualactionchange' and 'database' in d and 'channelname' in d and 'subaction' in d:
                curchanmode = pilib.controllib.getmode(d['database'], d['channelname'])
                if curchanmode == 'manual':
                    if d['subaction'] == 'poson':
                        controllib.setaction(d['database'], d['channelname'], '100.0')
                    elif d['subaction'] == 'negon':
                        controllib.setaction(d['database'], d['channelname'], '-100.0')
                    else:
                        controllib.setaction(d['database'], d['channelname'], '0.0')
            elif action == 'setposoutput' and 'database' in d and 'channelname' in d and 'outputname' in d:
                controllib.setposout(d['database'], d['channelname'], d['outputname'])
            elif action == 'setnegoutput' and 'database' in d and 'channelname' in d:
                controllib.setnegout(d['database'], d['channelname'], d['outputname'])
            elif action == 'actiondown' and 'database' in d and 'channelname' in d:
                curchanmode = controllib.getmode(d['database'], d['channelname'])
                if curchanmode == "manual":
                    curaction = int(controllib.getaction(d['database'], d['channelname']))
                    if curaction == 100:
                        nextvalue = 0
                    elif curaction == 0:
                        nextvalue = -100
                    elif curaction == -100:
                        nextvalue = -100
                    else:
                        nextvalue = 0
                    controllib.setaction(d['database'], d['channelname'], d['nextvalue'])
            elif action == 'actionup' and 'database' in d and 'channelname' in d:
                curchanmode = controllib.getmode(d['database'], d['channelname'])
                if curchanmode == "manual":
                    curaction = int(controllib.getaction(d['database'], d['channelname']))
                    if curaction == 100:
                        nextvalue = 100
                    elif curaction == 0:
                        nextvalue = 100
                    elif curaction == -100:
                        nextvalue = 0
                    else:
                        nextvalue = 0
                    controllib.setaction(d['database'], d['channelname'], nextvalue)
            elif action == 'deletechannelbyname' and 'database' in d and 'channelname' in d:
                pilib.sqlitequery(d['database'], 'delete channelname from channels where name=\"' + d['channelname'] + '\"')

            else:
                output['message'] += 'Action keyword present(' + action + '), but not handled. '

        else:
            output['message'] += 'action keyword not present. '
Example #3
0
def processremotedata(datadict, stringmessage):
    import cupid.pilib as pilib
    if 'nodeid' in datadict:

        # We are going to search for keywords. Message type will not be explicitly declared so
        # as not to waste precious message space in transmission. Or we could tack these on in
        # the gateway, but we won't yet.

        # Then we have to construct a query where we will replace a unique item
        # This will take the form :
        #   update or replace in remotes where nodeid=3 and msgtype='iovalue' and iopin=3
        #   update or repalce in remotes where nodeid=2 and msgtype='owdev' and owrom='28XXXXXXXXXXXXXX'
        #               (and later which IO on this device)
        #   update or replace in remotes where nodeid=2 and msgtype='chanstat' channum=1
        #               (need to see if all channel variables can be fit into one message:
        #               channum, sv,pv,mode,state
        runquery = False
        nodeid = datadict['nodeid']
        querylist = []

        # Command responses, including value requests
        if 'cmd' in datadict:
            if datadict['cmd'] == 'lp':
                # Remove command key and process remaining data
                del datadict['cmd']
                motetablename = 'node_' + nodeid + '_status'

                # Create table if it doesn't exist
                query = 'create table if not exists \'' + motetablename + '\' ( time text, message text primary key, value text)'
                pilib.sqlitequery(pilib.motesdatabase, query)

                for key in datadict:
                    thetime = pilib.gettimestring()
                    if key in ['iov', 'iov2', 'iov3', 'pv', 'pv2', 'sv', 'sv2', 'iomd', 'ioen', 'iordf', 'iorpf', 'chen', 'chmd', 'chnf', 'chpf', 'chdb', 'chsv', 'chsv2', 'chpv', 'chpv2']:
                        # We need to process these specially, going back to the original message
                        values = datadict[key]
                        valuelist = values.split('|')
                        print(valuelist)
                        index = 0
                        if key in ['iov', 'iov2', 'iov3']:
                            base = 'iov_'
                            if key == 'iov2':
                                index = 5
                            elif key == 'iov3':
                                index = 9
                        elif key in ['pv', 'pv2']:
                            base = 'pv_'
                            if key == 'pv2':
                                index = 5
                        elif key in ['sv', 'sv2']:
                            base = 'sv_'
                            if key == 'sv2':
                                index = 5
                        else:
                            base = key + '_'

                        querylist = []
                        for value in valuelist:
                            querylist.append(pilib.makesqliteinsert(motetablename, [thetime, base + str(index), value]))
                            index += 1
                        pilib.sqlitemultquery(pilib.motesdatabase, querylist)

                    # Update table entry. Each entry has a unique key
                    # updatetime, keyname, data
                    else:
                        pilib.sqliteinsertsingle(pilib.motesdatabase, motetablename, [thetime, key, datadict[key]])
                        print('inserted ' + thetime + ' ' + key + ' ' + datadict[key])

        # This is for values that are reported by the node
        elif 'ioval' in datadict:
            # check to see if entry exists with node and ionum. Need to generalize these.
            # Might make sense to put then into an ID to compare. Other database, compatible?
            # iovalue type message
            try:
                msgtype = 'iovalue'
                keyvalue = datadict['iopin']
                keyvaluename = 'iopin'
            except:
                print('oops')
            else:
                runquery = True

        elif 'owdev' in datadict:
            try:
                msgtype = 'owdev'
                keyvalue = datadict['owrom'][2:]
                keyvaluename = 'owrom'
                if len(keyvalue) != 16:
                    raise NameError('invalid ROM length')
                else:
                    for romcbar in keyvalue:
                        hexchars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d','e','f']
                        if romcbar not in hexchars:
                            raise NameError('Invalid ROM hex character')
            except:
                print("oops")
            else:
                runquery = True
        elif 'chan' in datadict:
            # insert or update remotes database value
            # first need to get existing entry if one exists
            msgtype = 'channel'
            keyvalue = str(int(datadict['chan'])) # Zeroes bad
            keyvaluename = str(int(datadict['chan']))

            # conditions = '"nodeid"=2 and "msgtype"=\'channel\' and "keyvalue"=\'' + keyvalue + '\'"'

            # Should be able to offer all conditions, but it is not working for some reason, so we will
            # iterate over list to find correct enty

            conditions = '"nodeid"=\''+ datadict['nodeid'] + '\' and "msgtype"=\'channel\''
            chanentries = pilib.readalldbrows(pilib.controldatabase, 'remotes', conditions)

            # parse through to get data from newdata
            newdata = {}
            for key, value in datadict.iteritems():
                if key not in ['chan','nodeid']:
                    newdata[key] = value

            updateddata = newdata.copy()

            # This does not take time into account. This should not be an issue, as there should only be one entry
            for chanentry in chanentries:
                if (str(int(chanentry['keyvalue']))) == keyvalue:
                    print('I FOUND')

                    # newdata  = {'fakedatatype':'fakedata', 'anotherfakedatatype':'morefakedata'}
                    olddata = pilib.parseoptions(chanentry['data'])

                    olddata.update(updateddata)
                    updateddata = olddata.copy()

                    newqueries = []
                    conditions += ' and "keyvalue"=\'' + keyvalue +"\'"

            # Ok, so here we are. We have either added new data to old data, or we have the new data alone.
            # We take our dictionary and convert it back to json and put it in the text entry

            updatedjsonentry = pilib.dicttojson(updateddata)

            conditions += 'and "keyvalue"=\'' + keyvalue +'\''
            deletequery = pilib.makedeletesinglevaluequery('remotes',conditions)

            # hardcode this for now, should supply valuename list.
            addquery = pilib.makesqliteinsert('remotes',[datadict['nodeid'],'channel',keyvalue,'channel',updatedjsonentry,pilib.gettimestring()])

            pilib.sqlitemultquery(pilib.controldatabase, [deletequery, addquery])

            # pass
        elif 'scalevalue' in datadict:
            querylist.append('create table if not exists scalevalues (value float, time string)')
            querylist.append(pilib.makesqliteinsert('scalevalues',[datadict['scalevalue'], pilib.gettimestring()],['value','time']))
            pilib.sqlitemultquery(pilib.logdatabase, querylist)

        if runquery:
            deletequery = pilib.makedeletesinglevaluequery('remotes', {'conditionnames': ['nodeid', 'keyvalue', 'keyvaluename'], 'conditionvalues': [nodeid ,keyvalue, keyvaluename]})
            insertquery = pilib.makesqliteinsert('remotes',  [nodeid, msgtype, keyvaluename, keyvalue, stringmessage.replace('\x00', ''), pilib.gettimestring()], ['nodeid', 'msgtype', 'keyvaluename', 'keyvalue', 'data', 'time'])
            querylist.append(deletequery)
            querylist.append(insertquery)
            pilib.sqlitemultquery(pilib.controldatabase, querylist)

            return
        else:
            # print('not running query')
            pass
Example #4
0
def lograwmessages(message):
    from cupid.pilib import sqliteinsertsingle, motesdatabase, gettimestring
    # try:
    strmessage = str(message).replace('\x00','').strip()
    print(repr(strmessage))
    sqliteinsertsingle(motesdatabase, 'readmessages', [gettimestring(), strmessage])
Example #5
0
def monitor(port='/dev/ttyAMA0', baudrate=115200, timeout=1, checkstatus=True):
    import serial
    import cupid.pilib as pilib
    from time import mktime, localtime

    data = []

    if checkstatus:
        systemstatus = pilib.readonedbrow(pilib.controldatabase, 'systemstatus')[0]
        runhandler = systemstatus['serialhandlerenabled']
        checktime = mktime(localtime())
        checkfrequency = 15  # seconds
        if runhandler:
           pilib.log(pilib.iolog, "Starting monitoring of serial port", 1, pilib.iologlevel)
        else:
            pilib.log(pilib.iolog, "Not starting monitoring of serial port. How did I get here?", 1, pilib.iologlevel)
    else:
        runhandler = True

    if runhandler:
        ser = serial.Serial(port=port, baudrate=baudrate, timeout=timeout)
        print("Monitoring serial port " + ser.name)
    else:
        print('not monitoring serial port ')
    while runhandler:
        ch = ser.read(1)
        if len(ch) == 0:
            # rec'd nothing print all
            if len(data) > 0:
                s = ''
                for x in data:
                    s += '%s' % x # ord(x)

                # Here for diagnostics
                # print '%s [len = %d]' % (s, len(data))

                # now process data
                # print(s)
                # print(s.split('\n'))
                try:
                    # print('*************** processing datadict')
                    datadicts, messages = processserialdata(s)
                    # print('ALL MY DATADICTS')
                    # print(datadicts)
                    # print('END OF DICTS')
                except IOError:
                    print('error processing message')
                except Exception as ex:
                    template = "An exception of type {0} occured. Arguments:\n{1!r}"
                    message = template.format(type(ex).__name__, ex.args)
                    print message
                else:
                    for datadict, message in zip(datadicts, messages):
                        if datadict:
                            print("datadict: ")
                            print(datadict)
                            # print("message: ")
                            # print(message)

                            publish = False
                            for k in datadict:
                                # print(k + datadict[k])
                                if k not in ['nodeid','RX_RSSI']:
                                    pass
                            # if 'cmd' in datadict:
                            publish = True
                            if publish:
                                print('publishing message')
                                statusresult = lograwmessages(message)

                            pilib.sizesqlitetable(pilib.motesdatabase, 'readmessages', 1000)

                            statusresult = processremotedata(datadict, message)
                        else:
                            if message:
                                print('message: ')
                                print(message)
                        # except:
                        #     print('error processing returned datadict, message:')
                            # print(message)
                        # else:
                        #     print("message parse was successful")
                        #     print(message)
            else:
                # no data, let's see if we should send message
                try:
                    lastqueuedmessage = pilib.getfirsttimerow(pilib.motesdatabase, 'queuedmessages', 'queuedtime')[0]
                except IndexError:
                    # no rows
                    # print('we have an error getting a queued message. Could be just no message.')
                    pass
                else:
                    # send queued message
                    print(lastqueuedmessage)
                    try:
                        print('going to send message:')
                        print(lastqueuedmessage['message'])
                        ser.write(lastqueuedmessage['message'].encode())
                        # sendserialmessage(ser, lastqueuedmessage['message'])
                    except:
                        print('oops')
                    else:
                        print('that worked out. remove message from queue')
                        conditionnames = ['queuedtime', 'message']
                        conditionvalues = [lastqueuedmessage['queuedtime'], lastqueuedmessage['message']]
                        delquery = pilib.makedeletesinglevaluequery('queuedmessages', {'conditionnames':conditionnames, 'conditionvalues':conditionvalues})
                        pilib.sqlitequery(pilib.motesdatabase, delquery)
                        print('move to sent messages')
                        pilib.sqliteinsertsingle(pilib.motesdatabase, 'sentmessages', [lastqueuedmessage['queuedtime'], pilib.gettimestring(), lastqueuedmessage['message']])
            data = []

        else:
            data.append(ch)

        if checkstatus:
            thetime = mktime(localtime())
            if thetime-checktime > checkfrequency:
                print('checking control status')
                systemstatus = pilib.readonedbrow(pilib.controldatabase, 'systemstatus')[0]
                runserialhandler = systemstatus['serialhandlerenabled']
                if runserialhandler:
                    checktime = thetime
                    pilib.log(pilib.iolog, 'Continuing serialhandler based on status check',3,pilib.iologlevel)
                else:
                    runhandler=False
                    pilib.log(pilib.iolog, 'Aborting serialhandler based on status check',3,pilib.iologlevel)