예제 #1
0
                            GPIO.setup(int(output['address']), GPIO.OUT)
                            GPIO.output(int(output['address']), F)


                            # Insert entry into control log
                pilib.sqliteinsertsingle(pilib.logdatabase, logtablename,
                                         [time, controlinput, controlvalue, setpointvalue, action, algorithm,
                                          channel['enabled'], statusmessage])

                # Size log 
                pilib.sizesqlitetable(pilib.logdatabase, logtablename, logpoints)
        else:
            statusmessage += 'Channel not enabled. '

        # Set status message for channel
        pilib.sqlitequery(pilib.controldatabase,
                          'update channels set statusmessage=\'' + statusmessage + '\'' + 'where channelindex=' + channelindex)

        # Set update time for channel 
        pilib.sqlitequery(pilib.controldatabase,
                          'update channels set controlupdatetime=\'' + time + '\'' + 'where channelindex=' + channelindex)

    # Wait for delay time 
    #print('sleeping')

    spilights.updatelightsfromdb(pilib.controldatabase, 'indicators')
    sleep(systemstatus['picontrolfreq'])

    # We do this system status again to refresh settings
    systemstatus = pilib.readalldbrows(pilib.controldatabase, 'systemstatus')[0]
예제 #2
0
def runboot():
    import subprocess
    from time import sleep

    import pilib
    import spilights
    from iiutilities import utility, dblib, datalib

    try:
        pilib.set_all_wal(False)
    except:
        print('error setting wal mode')

    interfaces = pilib.dbs.control.read_table('interfaces')

    # Clear out status bits, if for no other reason to see the LEDs come on
    for statusvalue in [
            'systemstatusstatus', 'hamachistatus', 'picontrolstatus',
            'updateiostatus', 'serialhandlerstatus'
    ]:
        dblib.setsinglevalue(pilib.dirs.dbs.system, 'systemstatus',
                             statusvalue, 0)

    systemstatus = dblib.readonedbrow(pilib.dirs.dbs.system, 'systemstatus')[0]

    # Queue a message indicating we are rebooting
    # TODO: Make this an actions option, or put it somewhere.
    # try:
    import socket
    hostname = socket.gethostname()

    message = 'CuPID is booting:\r\n\r\n'
    notifications_email = '*****@*****.**'
    subject = 'CuPID : ' + hostname + ' : booting'
    notification_database = pilib.cupidDatabase(pilib.dirs.dbs.notifications)
    system_database = pilib.cupidDatabase(pilib.dirs.dbs.system)

    currenttime = datalib.gettimestring()
    notification_database.insert(
        'queued', {
            'type': 'email',
            'message': message,
            'options': 'email:' + notifications_email + ',subject:' + subject,
            'queuedtime': currenttime
        })
    system_database.set_single_value('notifications',
                                     'lastnotification',
                                     currenttime,
                                     condition="item='boot'")

    # except Exception as e:
    #     error_message = 'EXCEPTION in notification: {}'.format(e.message)
    #     print (error_message)
    #     utility.log(pilib.dirs.logs.system, error_message)
    # else:
    #     utility.log(pilib.dirs.logs.system, 'Boot notificaiton complete. ')

    # Start pigpiod

    subprocess.call(['killall', 'pigpiod'])
    sleep(1)
    utility.log(pilib.dirs.logs.system, 'boot: starting pigpio daemon', 3,
                pilib.loglevels.system)
    subprocess.call(['/usr/local/bin/pigpiod'])

    # Start webserver

    subprocess.call(['killall', 'nginx'])
    subprocess.call(['killall', 'uwsgi'])
    subprocess.call(['killall', 'apache2'])

    if systemstatus['webserver'] == 'apache':
        utility.log(pilib.dirs.logs.system, 'boot: starting apache', 3,
                    pilib.loglevels.system)
        subprocess.call(['service', 'apache2', 'start'])
    elif systemstatus['webserver'] == 'nginx':
        utility.log(pilib.dirs.logs.system, 'boot: starting nginx', 3,
                    pilib.loglevels.system)
        subprocess.call(['service', 'nginx', 'start'])

    # Run uwsgi daemon if nginx is running

    try:
        result = subprocess.check_output(['service', 'nginx',
                                          'status']).decode('utf-8')
    except subprocess.CalledProcessError as e:
        result = ''
        # print('I AM FAILING')
        # print e.output

    if result:
        utility.log(pilib.dirs.logs.system,
                    'boot: starting uwsgi based on nginx call', 0)
        subprocess.call([
            'uwsgi', '--emperor', '/usr/lib/iicontrollibs/wsgi/',
            '--daemonize', '/var/log/cupid/uwsgi.log'
        ])
    else:
        # print(' I KNOW NGINX IS NOT RUNNING')
        pass
    # Mount 1wire master

    subprocess.call(['killall', 'owfs'])
    subprocess.call(['killall', 'owserver'])
    subprocess.call(['killall', 'owhttpd'])

    runi2cowfs = True
    runusbowfs = False

    temp_unit = 'C'
    for interface in interfaces:
        if interface['enabled']:
            from iiutilities.datalib import parseoptions
            options_dict = parseoptions(interface['options'])
            if 'tempunit' in options_dict:
                if options_dict['tempunit'] in [
                        'F', 'f', 'Fahrenheit', 'fahrenheit'
                ]:
                    temp_unit = 'F'

            if interface['interface'] == 'I2C' and interface[
                    'type'] == 'DS2483':
                runi2cowfs = True
            if interface['interface'] == 'USB' and interface[
                    'type'] == 'DS9490':
                runusbowfs = True

            if interface['interface'] == 'SPI1' and type == 'CuPIDlights':
                spilights.updatelightsfromdb(pilib.dirs.dbs.control,
                                             'indicators', 1)
            if interface['interface'] == 'SPI0' and type == 'CuPIDlights':
                spilights.updatelightsfromdb(pilib.dirs.dbs.control,
                                             'indicators', 0)

    if runi2cowfs or runusbowfs:
        if runi2cowfs:
            utility.log(pilib.dirs.logs.system, 'boot: Running i2c owserver',
                        3, pilib.loglevels.system)
            try:
                if temp_unit == 'F':
                    subprocess.call([
                        '/opt/owfs/bin/owserver', '-F', '--i2c=/dev/i2c-1:ALL',
                        '-p', '4304'
                    ])
                else:
                    subprocess.call([
                        '/opt/owfs/bin/owserver', '--i2c=/dev/i2c-1:ALL', '-p',
                        '4304'
                    ])
            except:
                utility.log(pilib.dirs.logs.system,
                            'boot: error running i2c owserver', 1,
                            pilib.loglevels.system)
        if runusbowfs:
            utility.log(pilib.dirs.logs.system, 'boot: Running usb owserver',
                        3, pilib.loglevels.system)
            try:
                if temp_unit == 'F':
                    subprocess.call(
                        ['/opt/owfs/bin/owserver', '-F', '-u', '-p', '4304'])
                else:
                    subprocess.call(
                        ['/opt/owfs/bin/owserver', '-u', '-p', '4304'])
            except:
                utility.log(pilib.dirs.logs.system,
                            'error running usb owserver', 1,
                            pilib.loglevels.system)

        utility.log(pilib.dirs.logs.system,
                    'boot: Running owfs/owserver mount', 3,
                    pilib.loglevels.system)
        try:
            if temp_unit == 'F':
                subprocess.call(
                    ['/opt/owfs/bin/owfs', '-F', '-s', '4304', '/var/1wire/'])
            else:
                subprocess.call(
                    ['/opt/owfs/bin/owfs', '-s', '4304', '/var/1wire/'])
        except:
            utility.log(pilib.dirs.logs.system, 'boot: error running owfs', 1,
                        pilib.loglevels.system)

        utility.log(pilib.dirs.logs.system,
                    'boot: Running owhttpd/owserver mount', 3,
                    pilib.loglevels.system)
        try:
            if temp_unit == 'F':
                subprocess.call([
                    '/opt/owfs/bin/owhttpd', '-F', '-s', '4304', '-p', '4305'
                ])
            else:
                subprocess.call(
                    ['/opt/owfs/bin/owhttpd', '-s', '4304', '-p', '4305'])
        except:
            utility.log(pilib.dirs.logs.system, 'boot: error running owhttpd',
                        1, pilib.loglevels.system)

    else:
        utility.log(pilib.dirs.logs.system, 'boot: not running owfs', 3,
                    pilib.loglevels.system)

    # Run netstart script if enabled
    if systemstatus['netconfigenabled']:
        from netconfig import runconfig
        utility.log(pilib.dirs.logs.system, 'boot: running boot netconfig', 2,
                    pilib.loglevels.system)
        runconfig(onboot=True)
예제 #3
0
def updateiodata(database, **kwargs):
    # This recreates all input and output tables based on the interfaces table.
    # Thus way we don't keep around stale data values. We could at some point incorporate
    # a retention feature that keeps them around in case they disappear temporarily.
    # It also reads the elements if they are enabled and it's time to read them

    import pilib
    import traceback

    if 'piobject' in kwargs:
        pi = kwargs['piobject']
    else:
        import pigpio
        pi = pigpio.pi()

    allowedGPIOaddresses = [18, 23, 24, 25, 4, 17, 27, 22, 5, 6, 13, 19, 26, 16, 20, 21]

    logconfig = pilib.getlogconfig()

    tables = pilib.gettablenames(pilib.controldatabase)
    if 'interfaces' in tables:
        interfaces = pilib.readalldbrows(pilib.controldatabase, 'interfaces')
    else:
        pilib.log(pilib.iolog, 'interfaces table not found. Exiting', 1,
                               logconfig['iologlevel'])
        return
    if 'inputs' in tables:
        previnputs = pilib.readalldbrows(pilib.controldatabase, 'inputs')

        # Make list of IDs for easy indexing
        previnputids = []
        for input in previnputs:
            previnputids.append(input['id'])
    else:
        previnputs = []
        previnputids = []

    if 'outputs' in tables:
        prevoutputs = pilib.readalldbrows(pilib.controldatabase, 'outputs')

        # Make list of IDs for easy indexing
        prevoutputids = []
        prevoutputvalues = []
        for output in prevoutputs:
            prevoutputids.append(output['id'])
            prevoutputvalues.append(output['value'])
    else:
        prevoutputs = {}
        prevoutputids = []

    if 'defaults' in tables:
        defaults = pilib.readalldbrows(pilib.controldatabase, 'defaults')[0]
        defaultinputpollfreq = defaults['inputpollfreq']
        defaultoutputpollfreq = defaults['outputpollfreq']
    else:
        defaults = []
        defaultinputpollfreq = 60
        defaultoutputpollfreq = 60

    if 'indicators' in tables:
        indicatornames = []
        previndicators = pilib.readalldbrows(pilib.controldatabase, 'indicators')
        for indicator in previndicators:
            indicatornames.append(indicator['name'])
    else:
        previndicators = []
        indicatornames = []

    # We drop all inputs and outputs and recreate
    # Add all into one query so there is no time when the IO don't exist.

    querylist = []
    querylist.append('delete from inputs')
    querylist.append('delete from outputs')

    # This is temporary. Clearing the table here and adding entries below can result in a gap in time
    # where there are no database indicator entries. This is not too much of a problem with indicators, as we
    # update the hardware explicitly after we add the entries. If the interface queries the table during
    # this period, however, we could end up with an apparently empty table.
    # TODO: FIX update on indicators in updateio

    # We drop this table, so that if SP1 has been disabled, the entries do not appear as valid indicators
    pilib.sqlitequery(pilib.controldatabase, 'delete from indicators')

    owfsupdate = False
    for interface in interfaces:
        if interface['interface'] == 'I2C':
            pilib.log(pilib.iolog, 'Processing I2C interface ' + interface['name'], 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.log(pilib.iolog, 'I2C Interface ' + interface['name'] + ' enabled', 3,
                                       logconfig['iologlevel'])
                if interface['type'] == 'DS2483':
                    pilib.log(pilib.iolog, 'Interface type is DS2483', 3,
                                           logconfig['iologlevel'])
                    owfsupdate = True
            else:
                 pilib.log(pilib.iolog, 'I2C Interface ' + interface['name'] + ' disabled', 3,
                                       logconfig['iologlevel'])
        elif interface['interface'] == 'USB':
            pilib.log(pilib.iolog, 'Processing USB interface ' + interface['name'], 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.log(pilib.iolog, 'USB Interface ' + interface['name'] + ' enabled', 3,
                                       logconfig['iologlevel'])
                if interface['type'] == 'DS9490':
                    pilib.log(pilib.iolog, 'Interface type is DS9490', 3,
                                           logconfig['iologlevel'])
                    owfsupdate = True
            else:
                 pilib.log(pilib.iolog, 'USB Interface ' + interface['name'] + ' disabled', 3,
                                       logconfig['iologlevel'])
        elif interface['interface'] == 'MOTE':

            #determine and then update id based on fields
            entryid = interface['interface'] + '_' + interface['type'] + '_' + interface['address']
            condition = '"interface"=\'' + interface['interface'] + '\' and "type"=\'' + interface['type'] + '\' and "address"=\'' + interface['address'] + '\''

            print(condition)
            pilib.setsinglevalue(pilib.controldatabase, 'interfaces', 'id', entryid, condition)

            pilib.log(pilib.iolog, 'Processing Mote interface' + interface['name'] + ', id:' + entryid, 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.log(pilib.iolog, 'Mote Interface ' + interface['name'] + ', id:' + entryid + ' enabled', 3,
                                       logconfig['iologlevel'])

                # Grab mote entries from remotes table
                # nodeid and keyvalue are keyed into address in remotes table
                # keyvalues are :
                #   channel: channel number
                #   iovalue: ionumber
                #   owdev: ROM

                # This would look like, for example
                # 1:1 for a nodeid:channel scenario for a controller
                split = interface['address'].split(':')
                nodeid = split[0]
                keyvalue = split[1]

                # so we used to enable an interface and then take all entries from a node
                # Now, we have to explicitly add an interface for each device, unless the keychar * is used as the
                # keyvalue. This will allow us to insert all automatically, for example for owdevs or iovals from a
                # node.

                # This pulls out all mote entries that have nodeid and keyvalue that match the interface address
                # We should just find one, ideally
                if keyvalue == '*':
                    pass
                else:
                    condition = "\"nodeid\"='" + nodeid + "' and \"keyvalue\"='" + keyvalue + "'"
                    nodeentries = pilib.dynamicsqliteread(pilib.controldatabase, 'remotes', condition=condition)

                print("WE FOUND MOTE")
                print(condition)
                print(len(nodeentries))

                if interface['type'] == 'channel':
                    print('channel')
                    if len(nodeentries) == 1:
                        print('one entry found')

                        nodeentry = nodeentries[0]
                        nodedata = pilib.parseoptions(nodeentry['data'])

                        # Find existing channel so we can get existing data, settings, etc., and retain channel ordering
                        newchanneldata = {'name':interface['name'], 'controlvalue':nodedata['pv'], 'setpointvalue':nodedata['sv'],'controlvaluetime':pilib.gettimestring(), 'data':nodeentry['data'], 'type':'remote'}
                        newchannel = {}
                        existingchannels = pilib.readalldbrows(pilib.controldatabase, 'channels')
                        for channel in existingchannels:
                            if channel['name'] == interface['name']:
                                print('updating')
                                print(channel)
                                newchannel.update(channel)
                                print(newchannel)
                        newchannel.update(newchanneldata)
                        print(newchannel)

                        keys = []
                        values = []
                        for key, value in newchannel.iteritems():
                            keys.append(key)
                            values.append(value)


                        query = pilib.makesqliteinsert('channels',values, keys)
                        # print(query)
                        pilib.sqlitequery(pilib.controldatabase,query)
                    else:
                        print('multiple entries found for channel. not appropriate')
                else:
                    pass
                    # Create queries for table insertion
                    # TODO: process mote pollfreq, ontime, offtime
                    moteentries = []
                    for nodeentry in nodeentries:

                        # THis breaks out all of the strictly json-encoded data.
                        datadict = pilib.parseoptions(nodeentry['data'])
                        try:
                            entrytype = nodeentry['msgtype']

                            # now treat each mote type entry specially
                            # if entrytype == 'channel':

                            entryid = 'MOTE' + str(nodeentry['nodeid']) + '_' + nodeentry['keyvaluename'] + '_' + nodeentry['keyvalue']

                            entrymetareturn = pilib.dynamicsqliteread(pilib.controldatabase, 'ioinfo', condition="\"id\"='" + entryid + "'")
                            try:
                                entrymeta = entrymetareturn[0]
                            except:
                                entrymeta = []

                            # print(entrymeta)

                            entryoptions={}
                            if entrymeta:
                                entryname = entrymeta['name']
                                if entrymeta['options']:
                                    entryoptions = pilib.parseoptions(entrymeta['options'])
                            else:
                                entryname = '[MOTE' + str(nodeentry['nodeid']) + '] ' + nodeentry['keyvaluename'] + ':' + nodeentry['keyvalue']
                        except KeyError:
                            print('OOPS KEY ERROR')
                        else:
                            if entrytype == 'iovalue':
                                if 'scale' in entryoptions:
                                    entryvalue = str(float(entryoptions['scale']) * float(datadict['ioval']))
                                elif 'formula' in entryoptions:
                                    x = float(datadict['ioval'])
                                    try:
                                        entryvalue = eval(entryoptions['formula'])
                                    except:
                                        entryvalue = float(datadict['ioval'])
                                else:
                                    entryvalue = float(datadict['ioval'])
                            elif entrytype == 'owdev':
                                if 'owtmpasc' in datadict:
                                    if 'scale' in entryoptions:
                                        entryvalue = str(float(entryoptions['scale']) * float(datadict['owtmpasc']))
                                    elif 'formula' in entryoptions:
                                        x = float(datadict['owtmpasc'])
                                        try:
                                            entryvalue = eval(entryoptions['formula'])
                                        except:
                                            entryvalue = float(datadict['owtmpasc'])
                                    else:
                                        entryvalue = datadict['owtmpasc']
                                else:
                                    entryvalue = -1
                            else:
                                entryvalue = -1


                            moteentries.append('insert into inputs values (\'' + entryid + '\',\'' + interface['interface'] + '\',\'' +
                                interface['type'] + '\',\'' + str(address) + '\',\'' + entryname + '\',\'' + str(entryvalue) + "','','" +
                                 nodeentry['time'] + '\',\'' + str(15) + "','" + '' + "','" + '' + "')")
                    # print('querylist')
                    # print(moteentries)
                    querylist.extend(moteentries)

            else:
                pilib.log(pilib.iolog, 'Mote Interface ' + interface['name'] + ' disnabled', 3,
                                       logconfig['iologlevel'])
        elif interface['interface'] == 'LAN':
            pilib.log(pilib.iolog, 'Processing LAN interface' + interface['name'], 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.log(pilib.iolog, 'LAN Interface ' + interface['name'] + ' enabled', 3,
                                       logconfig['iologlevel'])
                if interface['type'] == 'MBTCP':
                    pilib.log(pilib.iolog, 'Interface ' + interface['name'] + ' type is MBTCP',
                                           3, logconfig['iologlevel'])

                    try:
                        mbentries = processMBinterface(interface, prevoutputs, prevoutputids, previnputs, previnputids, defaults, logconfig)
                    except:
                        pilib.log(pilib.iolog,
                                               'Error processing MBTCP interface ' + interface['name'], 0,
                                               logconfig['iologlevel'])
                        errorstring = traceback.format_exc()
                        pilib.log(pilib.iolog,
                                               'Error of kind: ' + errorstring, 0,
                                               logconfig['iologlevel'])
                    else:
                        pilib.log(pilib.iolog,
                                               'Done processing MBTCP interface ' + interface['name'], 3,
                                               logconfig['iologlevel'])
                        querylist.extend(mbentries)
            else:
                pilib.log(pilib.iolog, 'LAN Interface ' + interface['name'] + ' disabled', 3,
                                       logconfig['iologlevel'])
        elif interface['interface'] == 'GPIO':
            try:
                address = int(interface['address'])
            except KeyError:
                pilib.log(pilib.iolog, 'GPIO address key not found for ' + interface['name'], 1,
                                       logconfig['iologlevel'])
                continue
            if interface['enabled']:

                pilib.log(pilib.iolog, 'Processing GPIO interface ' + str(interface['address']), 3,
                                       logconfig['iologlevel'])

                if address in allowedGPIOaddresses:
                    pilib.log(pilib.iolog, 'GPIO address' + str(address) + ' allowed. Processing.', 4,
                                           logconfig['iologlevel'])
                    GPIOentries = processGPIOinterface(interface, prevoutputs, prevoutputvalues, prevoutputids,
                                                               previnputs, previnputids, defaults, logconfig, piobject=pi)
                    if GPIOentries:
                                querylist.extend(GPIOentries)
                else:
                    pilib.log(pilib.iolog,
                                           'GPIO address' + str(address) + ' not allowed. Bad things can happen. ', 4,
                                           logconfig['iologlevel'])

            else:
                pilib.log(pilib.iolog, 'GPIO address' + str(address) + ' disabled. Doing nothing.', 4,
                                               logconfig['iologlevel'])
        elif interface['interface'] == 'SPI0':
            pilib.log(pilib.iolog, 'Processing SPI0', 1, logconfig['iologlevel'])
            if interface['enabled']:
                pilib.log(pilib.iolog, 'SPI0 enabled', 1, logconfig['iologlevel'])
                if interface['type'] == 'SPITC':
                    pilib.log(pilib.iolog, 'Processing SPITC on SPI0', 3, logconfig['iologlevel'])
                    import readspi

                    tcdict = readspi.getpigpioMAX31855temp(0,0)

                    # Convert to F for now
                    spitcentries = readspi.recordspidata(database, {'SPITC1' :tcdict['tctemp']*1.8+32})
                    querylist.extend(spitcentries)

                if interface['type'] == 'CuPIDlights':
                    import spilights

                    spilightsentries, setlist = spilights.getCuPIDlightsentries('indicators', 0, previndicators)
                    querylist.extend(spilightsentries)
                    spilights.updatelightsfromdb(pilib.controldatabase, 'indicators', 0)
                    spilights.setspilights(setlist, 0)
            else:
                pilib.log(pilib.iolog, 'SPI0 not enabled', 1, logconfig['iologlevel'])

        elif interface['interface'] == 'SPI1':
            pilib.log(pilib.iolog, 'Processing SPI1', 1, logconfig['iologlevel'])
            if interface['enabled']:
                pilib.log(pilib.iolog, 'SPI1 enabled', 1, logconfig['iologlevel'])
                if interface['type'] == 'CuPIDlights':
                    pilib.log(pilib.iolog, 'Processing CuPID Lights on SPI1', 1, logconfig['iologlevel'])
                    import spilights

                    spilightsentries, setlist = spilights.getCuPIDlightsentries('indicators', 1, previndicators)
                    querylist.extend(spilightsentries)
                    spilights.setspilights(setlist, 1)
            else:
                pilib.log(pilib.iolog, 'SPI1 disaabled', 1, logconfig['iologlevel'])

    # Set tables
    querylist.append(pilib.makesinglevaluequery('systemstatus', 'lastiopoll', pilib.gettimestring()))

    if owfsupdate:
        from owfslib import runowfsupdate
        pilib.log(pilib.iolog, 'Running owfsupdate', 1, logconfig['iologlevel'])
        devices, owfsentries = runowfsupdate(execute=False)
        querylist.extend(owfsentries)
    else:
        pilib.log(pilib.iolog, 'owfsupdate disabled', 3, logconfig['iologlevel'])

    pilib.log(pilib.iolog, 'Executing query:  ' + str(querylist), 5, logconfig['iologlevel'])
    try:
        # print(querylist)
        pilib.sqlitemultquery(pilib.controldatabase, querylist)
    except:
        errorstring = traceback.format_exc()
        pilib.log(pilib.iolog, 'Error executing query, message:  ' + errorstring, 0, logconfig['iologlevel'])
        pilib.log(pilib.errorlog, 'Error executing updateio query, message:  ' + errorstring)
        pilib.log(pilib.errorlog, 'Query:  ' + str(querylist))
예제 #4
0
import subprocess
import pilib
import spilights

interfaces = pilib.readalldbrows(pilib.controldatabase, 'interfaces')

runi2cowfs = False
runusbowfs = False
for interface in interfaces:
    if interface['interface'] == 'I2C' and interface['type'] == 'DS2483':
        runi2cowfs = True
    if interface['interface'] == 'USB' and interface['type'] == 'DS9490':
        runusbowfs = True

    if interface['interface'] == 'SPI1' and type == 'CuPIDlights':
        spilights.updatelightsfromdb(pilib.controldatabase, 'indicators', 1)
    if interface['interface'] == 'SPI0' and type == 'CuPIDlights':
        spilights.updatelightsfromdb(pilib.controldatabase, 'indicators', 0)

if runi2cowfs or runusbowfs:
    if runi2cowfs:
        subprocess.call([
            '/opt/owfs/bin/owserver', '-F', '--i2c=/dev/i2c-1:ALL', '-p',
            '4304'
        ])
    if runusbowfs:
        subprocess.call(['/opt/owfs/bin/owserver', '-F', '-u', '-p', '4304'])

    subprocess.call(['/opt/owfs/bin/owfs', '-F', '-s', '4304', '/var/1wire/'])
    subprocess.call(
        ['/opt/owfs/bin/owhttpd', '-F', '-s', '4304', '-p', '4305'])
예제 #5
0
def updateiodata(database):
    # This recreates all input and output tables based on the interfaces table.
    # Thus way we don't keep around stale data values. We could at some point incorporate
    # a retention feature that keeps them around in case they disappear temporarily.
    # It also reads the elements if they are enabled and it's time to read them

    import pilib
    import traceback
    import RPi.GPIO as GPIO

    allowedGPIOaddresses = [18, 23, 24, 25, 4, 17, 21, 22]

    logconfig = pilib.getlogconfig()

    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    tables = pilib.gettablenames(pilib.controldatabase)
    if 'interfaces' in tables:
        interfaces = pilib.readalldbrows(pilib.controldatabase, 'interfaces')
    else:
        pilib.writedatedlogmsg(pilib.iolog, 'interfaces table not found. Exiting', 1,
                               logconfig['iologlevel'])
        return
    if 'inputs' in tables:
        previnputs = pilib.readalldbrows(pilib.controldatabase, 'inputs')

        # Make list of IDs for easy indexing
        previnputids = []
        for input in previnputs:
            previnputids.append(input['id'])
    else:
        previnputs = []
        previnputids = []

    if 'outputs' in tables:
        prevoutputs = pilib.readalldbrows(pilib.controldatabase, 'outputs')

        # Make list of IDs for easy indexing
        prevoutputids = []
        prevoutputvalues = []
        for output in prevoutputs:
            prevoutputids.append(output['id'])
            prevoutputvalues.append(output['value'])
    else:
        prevoutputs = {}
        prevoutputids = []

    if 'defaults' in tables:
        defaults = pilib.readalldbrows(pilib.controldatabase, 'defaults')[0]
        defaultinputpollfreq = defaults['inputpollfreq']
        defaultoutputpollfreq = defaults['outputpollfreq']
    else:
        defaults = []
        defaultinputpollfreq = 60
        defaultoutputpollfreq = 60

    if 'indicators' in tables:
        indicatornames = []
        previndicators = pilib.readalldbrows(pilib.controldatabase, 'indicators')
        for indicator in previndicators:
            indicatornames.append(indicator['name'])
    else:
        previndicators = []
        indicatornames = []

    # We drop all inputs and outputs and recreate
    # Add all into one query so there is no time when the IO don't exist.

    querylist = []
    querylist.append('delete from inputs')
    querylist.append('delete from outputs')

    # This is temporary. Clearing the table here and adding entries below can result in a gap in time
    # where there are no database indicator entries. This is not too much of a problem with indicators, as we
    # update the hardware explicitly after we add the entries. If the interface queries the table during
    # this period, however, we could end up with an apparently empty table.
    # TODO: FIX update on indicators in updateio

    pilib.sqlitequery(pilib.controldatabase, 'delete from indicators')

    owfsupdate = False
    for interface in interfaces:
        if interface['interface'] == 'I2C':
            pilib.writedatedlogmsg(pilib.iolog, 'Processing I2C interface' + interface['name'], 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.writedatedlogmsg(pilib.iolog, 'I2C Interface ' + interface['name'] + ' enabled', 3,
                                       logconfig['iologlevel'])
                if interface['type'] == 'DS2483':
                    pilib.writedatedlogmsg(pilib.iolog, 'Interface type is DS2483', 3,
                                           logconfig['iologlevel'])
                    owfsupdate = True
        elif interface['interface'] == 'USB':
            pilib.writedatedlogmsg(pilib.iolog, 'Processing USB interface' + interface['name'], 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.writedatedlogmsg(pilib.iolog, 'USB Interface ' + interface['name'] + ' enabled', 3,
                                       logconfig['iologlevel'])
                if interface['type'] == 'DS9490':
                    pilib.writedatedlogmsg(pilib.iolog, 'Interface type is DS9490', 3,
                                           logconfig['iologlevel'])
                    owfsupdate = True
        elif interface['interface'] == 'MOTE':
            pilib.writedatedlogmsg(pilib.iolog, 'Processing Mote interface' + interface['name'], 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.writedatedlogmsg(pilib.iolog, 'Mote Interface ' + interface['name'] + ' enabled', 3,
                                       logconfig['iologlevel'])

                # Grab mote entries from remotes table
                nodeaddress = int(interface['address'])
                nodeentries = pilib.dynamicsqliteread(pilib.controldatabase, 'remotes', condition="\"nodeid\"='" + str(nodeaddress) + "'")

                # Create queries for table insertion
                # TODO: process mote pollfreq, ontime, offtime
                moteentries = []
                for nodeentry in nodeentries:

                    datadict = pilib.parseoptions(nodeentry['data'])
                    try:
                        entrytype = nodeentry['msgtype']
                        entryid = 'MOTE' + str(nodeentry['nodeid']) + '_' + nodeentry['keyvaluename'] + '_' + nodeentry['keyvalue']


                        entrymetareturn = pilib.dynamicsqliteread(pilib.controldatabase, 'ioinfo', condition="\"id\"='" + entryid + "'")
                        try:
                            entrymeta = entrymetareturn[0]
                        except:
                            entrymeta = []

                        # print(entrymeta)

                        entryoptions={}
                        if entrymeta:
                            entryname = entrymeta['name']
                            if entrymeta['options']:
                                entryoptions = pilib.parseoptions(entrymeta['options'])
                        else:
                            entryname = '[MOTE' + str(nodeentry['nodeid']) + '] ' + nodeentry['keyvaluename'] + ':' + nodeentry['keyvalue']
                    except KeyError:
                        print('OOPS KEY ERROR')
                    else:
                        if entrytype == 'iovalue':
                            if 'scale' in entryoptions:
                                entryvalue = str(float(entryoptions['scale']) * float(datadict['iovalue']))
                            else:
                                entryvalue = datadict['iovalue']
                        elif entrytype == 'owdev':
                            if 'owtmpasc' in datadict:
                                if 'scale' in entryoptions:
                                    entryvalue = str(float(entryoptions['scale']) * float(datadict['owtmpasc']))
                                else:
                                    entryvalue = datadict['owtmpasc']
                            else:
                                entryvalue = -1
                        else:
                            entryvalue = -1

                        moteentries.append('insert into inputs values (\'' + entryid + '\',\'' + interface['interface'] + '\',\'' +
            interface['type'] + '\',\'' + str(address) + '\',\'' + entryname + '\',\'' + str(entryvalue) + "','','" +
            nodeentry['time'] + '\',\'' + str(15) + "','" + '' + "','" + '' + "')")
                # print('querylist')
                # print(moteentries)
                querylist.extend(moteentries)

        elif interface['interface'] == 'LAN':
            pilib.writedatedlogmsg(pilib.iolog, 'Processing LAN interface' + interface['name'], 3,
                                   logconfig['iologlevel'])
            if interface['enabled']:
                pilib.writedatedlogmsg(pilib.iolog, 'LAN Interface ' + interface['name'] + ' enabled', 3,
                                       logconfig['iologlevel'])
                if interface['type'] == 'MBTCP':
                    pilib.writedatedlogmsg(pilib.iolog, 'Interface ' + interface['name'] + ' type is MBTCP',
                                           3, logconfig['iologlevel'])

                    try:
                        mbentries = processMBinterface(interface, prevoutputs, prevoutputids, previnputs, previnputids, defaults, logconfig)
                    except:
                        pilib.writedatedlogmsg(pilib.iolog,
                                               'Error processing MBTCP interface ' + interface['name'], 0,
                                               logconfig['iologlevel'])
                        errorstring = traceback.format_exc()
                        pilib.writedatedlogmsg(pilib.iolog,
                                               'Error of kind: ' + errorstring, 0,
                                               logconfig['iologlevel'])
                    else:
                        pilib.writedatedlogmsg(pilib.iolog,
                                               'Done processing MBTCP interface ' + interface['name'], 3,
                                               logconfig['iologlevel'])
                        querylist.extend(mbentries)


        elif interface['interface'] == 'GPIO':
            try:
                address = int(interface['address'])
            except KeyError:
                pilib.writedatedlogmsg(pilib.iolog, 'GPIO address key not found for ' + interface['name'], 1,
                                       logconfig['iologlevel'])
                continue

            pilib.writedatedlogmsg(pilib.iolog, 'Processing GPIO interface ' + str(interface['address']), 3,
                                   logconfig['iologlevel'])

            if address in allowedGPIOaddresses:
                pilib.writedatedlogmsg(pilib.iolog, 'GPIO address' + str(address) + ' allowed', 4,
                                       logconfig['iologlevel'])

                # Check if interface is enabled
                if interface['enabled']:
                    GPIOentries = processGPIOinterface(interface, prevoutputs, prevoutputvalues, prevoutputids,
                                                       previnputs, previnputids, defaults, logconfig)
                    querylist.extend(GPIOentries)
                else:
                    pilib.writedatedlogmsg(pilib.iolog, 'GPIO address' + str(address) + ' disabled', 4,
                                           logconfig['iologlevel'])
                    GPIO.setup(address, GPIO.IN)
            else:
                pilib.writedatedlogmsg(pilib.iolog,
                                       'GPIO address' + str(address) + ' not allowed. Bad things can happen. ', 4,
                                       logconfig['iologlevel'])
        elif interface['interface'] == 'SPI0':
            pilib.writedatedlogmsg(pilib.iolog, 'Processing SPI0', 1, logconfig['iologlevel'])
            if interface['type'] == 'SPITC':
                import readspi

                spidata = readspi.readspitc(0)
                spitcentries = readspi.recordspidata(database, spidata)
                querylist.extend(spitcentries)

            if interface['type'] == 'CuPIDlights':
                import spilights

                spilightsentries, setlist = spilights.getCuPIDlightsentries('indicators', 0, previndicators)
                querylist.extend(spilightsentries)
                spilights.updatelightsfromdb(pilib.controldatabase, 'indicators', 0)
                spilights.setspilights(setlist, 0)

        elif interface['interface'] == 'SPI1':
            pilib.writedatedlogmsg(pilib.iolog, 'Processing SPI1', 1, logconfig['iologlevel'])

            if interface['type'] == 'CuPIDlights':
                import spilights

                spilightsentries, setlist = spilights.getCuPIDlightsentries('indicators', 1, previndicators)
                querylist.extend(spilightsentries)
                spilights.setspilights(setlist, 1)

    # Set tables
    querylist.append(pilib.makesinglevaluequery('systemstatus', 'lastiopoll', pilib.gettimestring()))

    if owfsupdate:
        from owfslib import runowfsupdate

        devices, owfsentries = runowfsupdate(execute=False)
        querylist.extend(owfsentries)

    pilib.writedatedlogmsg(pilib.iolog, 'Executing query:  ' + str(querylist), 5, logconfig['iologlevel'])
    try:
        pilib.sqlitemultquery(pilib.controldatabase, querylist)
    except:
        errorstring = traceback.format_exc()
        pilib.writedatedlogmsg(pilib.iolog, 'Error executing query, message:  ' + errorstring, 0, logconfig['iologlevel'])
        pilib.writedatedlogmsg(pilib.errorlog, 'Error executing updateio query, message:  ' + errorstring)
        pilib.writedatedlogmsg(pilib.errorlog, 'Query:  ' + str(querylist))
예제 #6
0
def updateiodata(database):
    # This recreates all input and output tables based on the interfaces table.
    # Thus way we don't keep around stale data values. We could at some point incorporate
    # a retention feature that keeps them around in case they disappear temporarily.
    # It also reads the elements if they are enabled and it's time to read them

    import pilib
    import RPi.GPIO as GPIO

    allowedGPIOaddresses = [18, 23, 24, 25, 4, 17, 21, 22]

    dontrun = False
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    tables = pilib.gettablenames(pilib.controldatabase)
    if 'interfaces' in tables:
        interfaces = pilib.readalldbrows(pilib.controldatabase, 'interfaces')
    else:
        print('interfaces table not found. Exiting')
        return
    if 'inputs' in tables:
        previnputs = pilib.readalldbrows(pilib.controldatabase, 'inputs')

        # Make list of IDs for easy indexing
        previnputids = []
        for input in previnputs:
            previnputids.append(input['id'])
    else:
        previnputs = []
        previnputids = []

    if 'outputs' in tables:
        prevoutputs = pilib.readalldbrows(pilib.controldatabase, 'outputs')

        # Make list of IDs for easy indexing
        prevoutputids = []
        prevoutputvalues = []
        for output in prevoutputs:
            prevoutputids.append(output['id'])
            prevoutputvalues.append(output['value'])
    else:
        prevoutputs = {}
        prevoutputids = []

    if 'defaults' in tables:
        defaults = pilib.readalldbrows(pilib.controldatabase, 'defaults')[0]
        defaultinputpollfreq = defaults['inputpollfreq']
        defaultoutputpollfreq = defaults['outputpollfreq']
    else:
        defaults = []
        defaultinputpollfreq = 60
        defaultoutputpollfreq = 60

    # We drop all inputs and outputs and recreate
    # Add all into one query so there is no time when the IO don't exist.

    querylist = []
    querylist.append('delete from inputs')
    querylist.append('delete from outputs')
    pilib.sqlitemultquery(pilib.controldatabase, querylist)

    querylist = []
    for interface in interfaces:
        if interface['interface'] == 'I2C':
            if interface['enabled']:
                # print('processing enabled I2C')
                if interface['type'] == 'DS2483':
                    from owfslib import runowfsupdate
                    runowfsupdate()


        elif interface['interface'] == 'GPIO':

            options = pilib.parseoptions(interface['options'])

            # TODO : respond to more option, like pullup and pulldown

            address = int(interface['address'])

            if address in allowedGPIOaddresses:

                # Check if interface is enabled

                if interface['enabled']:

                    # Get name from ioinfo table to give it a colloquial name
                    gpioname = pilib.sqlitedatumquery(database, 'select name from ioinfo where id=\'' +
                                                                interface['id'] + '\'')
                    polltime = pilib.gettimestring()

                    # Append to inputs and update name, even if it's an output (can read status as input)

                    if options['mode'] == 'output':
                        GPIO.setup(address, GPIO.OUT)

                        # Set the value of the gpio.
                        # Get previous value if exists
                        if interface['id'] in prevoutputids:
                            value = prevoutputvalues[prevoutputids.index(interface['id'])]
                        else:
                            value = 0
                        if value == 1:
                            GPIO.output(address, True)
                        else:
                            GPIO.output(address, False)

                        # Get output settings and keep them if the GPIO previously existed
                        if interface['id'] in prevoutputids:
                            pollfreq = prevoutputs[prevoutputids.index(interface['id'])]['pollfreq']
                        else:
                            pollfreq = defaultoutputpollfreq

                        # Add entry to outputs tables
                        querylist.append('insert into outputs values (\'' + interface['id'] + '\',\'' +
                            interface['interface'] + '\',\'' + interface['type'] + '\',\'' + str(address) + '\',\'' +
                                         gpioname + '\',\'' + str(value) + '\',\'\',\'' + str(polltime) + '\',\'' +
                                         str(pollfreq) + '\')')
                    else:
                        GPIO.setup(address, GPIO.IN)
                        value = GPIO.input(address)
                        polltime = pilib.gettimestring()

                    # Get input settings and keep them if the GPIO previously existed
                    if interface['id'] in prevoutputids:
                        pollfreq = previnputs[prevoutputids.index(interface['id'])]['pollfreq']
                        polltime = previnputs[prevoutputids.index(interface['id'])]['polltime']
                    else:
                        pollfreq = defaultinputpollfreq


                    # Add entry to inputs tables
                    # Get output settings and keep them if the GPIO previously existed
                    if interface['id'] in prevoutputids:
                        pollfreq = prevoutputs[prevoutputids.index(interface['id'])]['pollfreq']
                    else:
                        pollfreq = defaultoutputpollfreq
                    querylist.append(
                        'insert into inputs values (\'' + interface['id'] + '\',\'' + interface['interface'] + '\',\'' +
                        interface['type'] + '\',\'' + str(address) + '\',\'' + gpioname + '\',\'' + str(value) + '\',\'\',\'' +
                        str(polltime) + '\',\'' + str(pollfreq) + '\')')

                else:
                    GPIO.setup(address, GPIO.IN)
            else:
                print('GPIO address ' + address + 'not allowed. BAD THINGS CAN HAPPEN.')

        elif interface['interface'] == 'SPI':
            # print('processing SPI')
            if interface['type'] == 'SPITC':
                import readspi

                spidata = readspi.readspitc()
                readspi.recordspidata(database, spidata)
            elif interface['type'] == 'CuPIDLights':
                import spilights

                spilights.updatelightsfromdb(pilib.controldatabase, 'indicators')

    # Set tables
    # print(querylist)
    pilib.sqlitemultquery(pilib.controldatabase, querylist)
예제 #7
0
def runboot():
    import subprocess
    from time import sleep

    import pilib
    import spilights
    from iiutilities import utility, dblib, datalib

    try:
        pilib.set_all_wal(False)
    except:
        print('error setting wal mode')

    interfaces = pilib.dbs.control.read_table('interfaces')

    # Clear out status bits, if for no other reason to see the LEDs come on
    for statusvalue in ['systemstatusstatus', 'hamachistatus', 'picontrolstatus', 'updateiostatus', 'serialhandlerstatus' ]:
        dblib.setsinglevalue(pilib.dirs.dbs.system, 'systemstatus', statusvalue, 0)

    systemstatus = dblib.readonedbrow(pilib.dirs.dbs.system, 'systemstatus')[0]


    # Queue a message indicating we are rebooting
    # TODO: Make this an actions option, or put it somewhere.
    # try:
    import socket
    hostname = socket.gethostname()

    message = 'CuPID is booting:\r\n\r\n'
    notifications_email = '*****@*****.**'
    subject = 'CuPID : ' + hostname + ' : booting'
    notification_database = pilib.cupidDatabase(pilib.dirs.dbs.notifications)
    system_database = pilib.cupidDatabase(pilib.dirs.dbs.system)

    currenttime = datalib.gettimestring()
    notification_database.insert('queued',
                                 {'type': 'email', 'message': message,
                                  'options': 'email:' + notifications_email + ',subject:' + subject,
                                  'queuedtime': currenttime})
    system_database.set_single_value('notifications', 'lastnotification', currenttime, condition="item='boot'")

    # except Exception as e:
    #     error_message = 'EXCEPTION in notification: {}'.format(e.message)
    #     print (error_message)
    #     utility.log(pilib.dirs.logs.system, error_message)
    # else:
    #     utility.log(pilib.dirs.logs.system, 'Boot notificaiton complete. ')


    # Start pigpiod

    subprocess.call(['killall','pigpiod'])
    sleep(1)
    utility.log(pilib.dirs.logs.system, 'boot: starting pigpio daemon', 3, pilib.loglevels.system)
    subprocess.call(['/usr/local/bin/pigpiod'])

    # Start webserver

    subprocess.call(['killall','nginx'])
    subprocess.call(['killall','uwsgi'])
    subprocess.call(['killall','apache2'])

    if systemstatus['webserver'] == 'apache':
        utility.log(pilib.dirs.logs.system, 'boot: starting apache', 3, pilib.loglevels.system)
        subprocess.call(['service', 'apache2', 'start'])
    elif systemstatus['webserver'] == 'nginx':
        utility.log(pilib.dirs.logs.system, 'boot: starting nginx', 3, pilib.loglevels.system)
        subprocess.call(['service', 'nginx', 'start'])

    # Run uwsgi daemon if nginx is running

    try:
        result = subprocess.check_output(['service', 'nginx', 'status']).decode('utf-8')
    except subprocess.CalledProcessError as e:
        result = ''
        # print('I AM FAILING')
        # print e.output

    if result:
        utility.log(pilib.dirs.logs.system, 'boot: starting uwsgi based on nginx call', 0)
        subprocess.call(['uwsgi', '--emperor', '/usr/lib/iicontrollibs/wsgi/', '--daemonize', '/var/log/cupid/uwsgi.log'])
    else:
        # print(' I KNOW NGINX IS NOT RUNNING')
        pass
    # Mount 1wire master

    subprocess.call(['killall','owfs'])
    subprocess.call(['killall','owserver'])
    subprocess.call(['killall','owhttpd'])

    runi2cowfs = True
    runusbowfs = False

    temp_unit = 'C'
    for interface in interfaces:
        if interface['enabled']:
            from iiutilities.datalib import parseoptions
            options_dict = parseoptions(interface['options'])
            if 'tempunit' in options_dict:
                if options_dict['tempunit'] in ['F','f','Fahrenheit','fahrenheit']:
                    temp_unit = 'F'

            if interface['interface'] == 'I2C' and interface['type'] == 'DS2483':
                runi2cowfs = True
            if interface['interface'] == 'USB' and interface['type'] == 'DS9490':
                runusbowfs = True

            if interface['interface'] == 'SPI1' and type == 'CuPIDlights':
                spilights.updatelightsfromdb(pilib.dirs.dbs.control, 'indicators', 1)
            if interface['interface'] == 'SPI0' and type == 'CuPIDlights':
                spilights.updatelightsfromdb(pilib.dirs.dbs.control, 'indicators', 0)

    if runi2cowfs or runusbowfs:
        if runi2cowfs:
            utility.log(pilib.dirs.logs.system, 'boot: Running i2c owserver', 3, pilib.loglevels.system)
            try:
                if temp_unit == 'F':
                    subprocess.call(['/opt/owfs/bin/owserver', '-F', '--i2c=/dev/i2c-1:ALL', '-p', '4304'])
                else:
                    subprocess.call(['/opt/owfs/bin/owserver', '--i2c=/dev/i2c-1:ALL', '-p', '4304'])
            except:
                utility.log(pilib.dirs.logs.system, 'boot: error running i2c owserver', 1, pilib.loglevels.system)
        if runusbowfs:
            utility.log(pilib.dirs.logs.system, 'boot: Running usb owserver', 3, pilib.loglevels.system)
            try:
                if temp_unit == 'F':
                    subprocess.call(['/opt/owfs/bin/owserver', '-F', '-u', '-p', '4304'])
                else:
                    subprocess.call(['/opt/owfs/bin/owserver', '-u', '-p', '4304'])
            except:
                utility.log(pilib.dirs.logs.system, 'error running usb owserver', 1, pilib.loglevels.system)

        utility.log(pilib.dirs.logs.system, 'boot: Running owfs/owserver mount', 3, pilib.loglevels.system)
        try:
            if temp_unit == 'F':
                subprocess.call(['/opt/owfs/bin/owfs', '-F', '-s', '4304', '/var/1wire/'])
            else:
                subprocess.call(['/opt/owfs/bin/owfs', '-s', '4304', '/var/1wire/'])
        except:
            utility.log(pilib.dirs.logs.system, 'boot: error running owfs', 1, pilib.loglevels.system)

        utility.log(pilib.dirs.logs.system, 'boot: Running owhttpd/owserver mount', 3, pilib.loglevels.system)
        try:
            if temp_unit == 'F':
                subprocess.call(['/opt/owfs/bin/owhttpd', '-F', '-s', '4304', '-p', '4305'])
            else:
                subprocess.call(['/opt/owfs/bin/owhttpd', '-s', '4304', '-p', '4305'])
        except:
            utility.log(pilib.dirs.logs.system, 'boot: error running owhttpd', 1, pilib.loglevels.system)

    else:
        utility.log(pilib.dirs.logs.system, 'boot: not running owfs', 3, pilib.loglevels.system)

    # Run netstart script if enabled
    if systemstatus['netconfigenabled']:
        from netconfig import runconfig
        utility.log(pilib.dirs.logs.system, 'boot: running boot netconfig', 2, pilib.loglevels.system)
        runconfig(onboot=True)