示例#1
0
    def __init__(self, bif=None, dbfile=DBFILE):
        """ create a new BaseLogger and connect it to the sensor
        source (bif) and the database (dbfile).
        """
        self.engine = create_engine(dbfile, echo=False)
        init_model(self.engine)
        self.metadata = Base.metadata

        if bif is None:
            self.bif = BaseIF("sf@localhost:9002")
        else:
            self.bif = bif
示例#2
0
    def __init__(self, bif=None, dbfile=DBFILE):
        """ create a new BaseLogger and connect it to the sensor
        source (bif) and the database (dbfile).
        """
        self.engine = create_engine(dbfile, echo=False)
        #init_model(self.engine)
        models.initialise_sql(self.engine)
        #self.metadata = Base.metadata

        if bif is None: 
            self.bif = BaseIF("sf@localhost:9002")
        else:
            self.bif = bif

        self.log = logging.getLogger("baselogger")
        self.running = True
示例#3
0
    def __init__(self, bif=None, dbfile=DBFILE):
        """ create a new BaseLogger and connect it to the sensor
        source (bif) and the database (dbfile).
        """
        self.engine = create_engine(dbfile, echo=False)
        init_model(self.engine)
        self.metadata = Base.metadata

        if bif is None:
            self.bif = BaseIF("sf@localhost:9002")
        else:
            self.bif = bif
示例#4
0
class BaseLogger(object):
    """ BaseLogger class receives sensor messages and writes them to
    the database.
    """
    def __init__(self, bif=None, dbfile=DBFILE):
        """ create a new BaseLogger and connect it to the sensor
        source (bif) and the database (dbfile).
        """
        self.engine = create_engine(dbfile, echo=False)
        init_model(self.engine)
        self.metadata = Base.metadata

        if bif is None:
            self.bif = BaseIF("sf@localhost:9002")
        else:
            self.bif = bif

    def create_tables(self):
        """ create any missing tables using sqlalchemy
        """
        self.metadata.create_all(self.engine)
        # TODO: follow the instructions at url:
        # https://alembic.readthedocs.org/en/latest/tutorial.html#building-an-up-to-date-database-from-scratch
        # to write an alembic version string

        session = Session()
        if session.query(SensorType).get(0) is None:
            raise Exception("SensorType must be populated by alembic " +
                            "before starting BaseLogger")
        session.close()    
                             

    def send_ack(self,
                 seq=None,
                 dest=None):
        """ send acknowledgement message
        """
        ack_msg = AckMsg()
        ack_msg.set_seq(seq)
        ack_msg.set_node_id(dest)
        
        self.bif.sendMsg(ack_msg, dest)
        LOGGER.debug("Sending Ack %s to %s" %
                     (seq, dest))


    def store_state(self, msg):
        """ receive and process a message object from the base station
        """
    
        # get the last source 

        if msg.get_special() != Packets.SPECIAL:
            raise Exception("Corrupted packet - special is %02x not %02x" %
                            (msg.get_special(), Packets.SPECIAL))

        try:
            session = Session()
            current_time = datetime.utcnow()
            node_id = msg.getAddr()
            parent_id = msg.get_ctp_parent_id()
            seq = msg.get_seq()

            node = session.query(Node).get(node_id)
            loc_id = None
            if node is None:
                add_node(session, node_id)
            else:
                loc_id = node.locationId


            pack_state = PackState.from_message(msg)
            
            if duplicate_packet(session=session,
                                receipt_time=current_time,
                                node_id=node_id,
                                localtime=msg.get_timestamp()):
                LOGGER.info("duplicate packet %d->%d, %d %s" %
                            (node_id, parent_id, msg.get_timestamp(), str(msg)))

                #send acknowledgement to base station to fwd to node
                self.send_ack(seq=seq,
                              dest=node_id)
                return

            # write a node state row
            node_state = NodeState(time=current_time,
                                   nodeId=node_id,
                                   parent=parent_id,
                localtime=msg.get_timestamp(),
                seq_num=seq)
            session.add(node_state)

            for i, value in pack_state.d.iteritems():
                if (msg.get_amType() == Packets.AM_BNMSG and
                    i not in [Packets.SC_VOLTAGE]):
                    type_id = i + BN_OFFSET   # TODO: ideally should be a flag in datbase or something
                else:
                    type_id = i

                session.add(Reading(time=current_time,
                                    nodeId=node_id,
                                    typeId=type_id,
                                    locationId=loc_id,
                    value=value))

            session.commit()

            #send acknowledgement to base station to fwd to node
            self.send_ack(seq=seq,
                          dest=node_id)
                     
            LOGGER.debug("reading: %s, %s" % (node_state, pack_state))
        except Exception as exc:
            session.rollback()
            LOGGER.exception("during storing: " + str(exc))
        finally:
            session.close()

    def run(self):
        """ run - main loop

        At the moment this is just receiving from the sensor message
        queue and processing the message.

        """

        try:
            while True:
                # wait up to 30 seconds for a message
                try:
                    msg = self.bif.queue.get(True, 30)
                    self.store_state(msg)
                except Empty:
                    pass
                except Exception as exc:
                    LOGGER.exception("during receiving or storing msg: " +
                                     str(exc))

        except KeyboardInterrupt:
            self.bif.finishAll()
示例#5
0
class BaseLogger(object):
    """ BaseLogger class receives sensor messages and writes them to
    the database.
    """
    def __init__(self, bif=None, dbfile=DBFILE):
        """ create a new BaseLogger and connect it to the sensor
        source (bif) and the database (dbfile).
        """
        self.engine = create_engine(dbfile, echo=False)
        init_model(self.engine)
        self.metadata = Base.metadata

        if bif is None:
            self.bif = BaseIF("sf@localhost:9002")
        else:
            self.bif = bif

    def create_tables(self):
        """ create any missing tables using sqlalchemy
        """
        self.metadata.create_all(self.engine)
        # TODO: follow the instructions at url:
        # https://alembic.readthedocs.org/en/latest/tutorial.html#building-an-up-to-date-database-from-scratch
        # to write an alembic version string

        session = Session()
        if session.query(SensorType).get(0) is None:
            raise Exception("SensorType must be populated by alembic " +
                            "before starting BaseLogger")
        session.close()

    def send_ack(self, seq=None, dest=None):
        """ send acknowledgement message
        """
        ack_msg = AckMsg()
        ack_msg.set_seq(seq)
        ack_msg.set_node_id(dest)

        self.bif.sendMsg(ack_msg, dest)
        LOGGER.debug("Sending Ack %s to %s" % (seq, dest))

    def store_state(self, msg):
        """ receive and process a message object from the base station
        """

        # get the last source

        if msg.get_special() != Packets.SPECIAL:
            raise Exception("Corrupted packet - special is %02x not %02x" %
                            (msg.get_special(), Packets.SPECIAL))

        try:
            session = Session()
            current_time = datetime.utcnow()
            node_id = msg.getAddr()
            parent_id = msg.get_ctp_parent_id()
            seq = msg.get_seq()

            node = session.query(Node).get(node_id)
            loc_id = None
            if node is None:
                add_node(session, node_id)
            else:
                loc_id = node.locationId

            pack_state = PackState.from_message(msg)

            if duplicate_packet(session=session,
                                receipt_time=current_time,
                                node_id=node_id,
                                localtime=msg.get_timestamp()):
                LOGGER.info(
                    "duplicate packet %d->%d, %d %s" %
                    (node_id, parent_id, msg.get_timestamp(), str(msg)))

                #send acknowledgement to base station to fwd to node
                self.send_ack(seq=seq, dest=node_id)
                return

            # write a node state row
            node_state = NodeState(time=current_time,
                                   nodeId=node_id,
                                   parent=parent_id,
                                   localtime=msg.get_timestamp(),
                                   seq_num=seq)
            session.add(node_state)

            for i, value in pack_state.d.iteritems():
                if (msg.get_amType() == Packets.AM_BNMSG
                        and i not in [Packets.SC_VOLTAGE]):
                    type_id = i + BN_OFFSET  # TODO: ideally should be a flag in datbase or something
                else:
                    type_id = i

                session.add(
                    Reading(time=current_time,
                            nodeId=node_id,
                            typeId=type_id,
                            locationId=loc_id,
                            value=value))

            session.commit()

            #send acknowledgement to base station to fwd to node
            self.send_ack(seq=seq, dest=node_id)

            LOGGER.debug("reading: %s, %s" % (node_state, pack_state))
        except Exception as exc:
            session.rollback()
            LOGGER.exception("during storing: " + str(exc))
        finally:
            session.close()

    def run(self):
        """ run - main loop

        At the moment this is just receiving from the sensor message
        queue and processing the message.

        """

        try:
            while True:
                # wait up to 30 seconds for a message
                try:
                    msg = self.bif.queue.get(True, 30)
                    self.store_state(msg)
                except Empty:
                    pass
                except Exception as exc:
                    LOGGER.exception("during receiving or storing msg: " +
                                     str(exc))

        except KeyboardInterrupt:
            self.bif.finishAll()
示例#6
0
                      default="info",
                      metavar="LEVEL")

    (options, args) = parser.parse_args()
    if len(args) != 0:
        parser.error("incorrect number of arguments")

    LEVEL_MAP = {
        "debug": logging.DEBUG,
        "info": logging.INFO,
        "warning": logging.WARNING,
        "error": logging.ERROR,
        "critical": logging.CRITICAL
    }

    if options.log_level not in LEVEL_MAP:
        parser.error("invalid LEVEL: " + options.log_level)

    bif = BaseIF("sf@localhost:9002")

    seq = 0
    time.sleep(2)
    while True:
        seq = 1
        print "sending ack"
        send_ack(bif=bif, seq=seq, dest=19)
        #seq = 1
        #if seq > 255:
        #    seq = 0
        time.sleep(2)
示例#7
0
class BaseLogger(object):
    """ BaseLogger class receives sensor messages and writes them to
    the database.
    """
    def __init__(self, bif=None, dbfile=DBFILE):
        """ create a new BaseLogger and connect it to the sensor
        source (bif) and the database (dbfile).
        """
        self.engine = create_engine(dbfile, echo=False)
        #init_model(self.engine)
        models.initialise_sql(self.engine)
        #self.metadata = Base.metadata

        if bif is None: 
            self.bif = BaseIF("sf@localhost:9002")
        else:
            self.bif = bif

        self.log = logging.getLogger("baselogger")
        self.running = True

    def create_tables(self):
        """ create any missing tables using sqlalchemy
        """
        #self.metadata.create_all(self.engine)
        # TODO: follow the instructions at url:
        # https://alembic.readthedocs.org/en/latest/tutorial.html#building-an-up-to-date-database-from-scratch
        # to write an alembic version string

        session = meta.Session()
        models.populateData.init_data(session)
        if session.query(SensorType).get(0) is None:
            raise Exception("SensorType must be populated by alembic " +
                            "before starting BaseLogger")
        session.close()    
                             

    def send_ack(self,
                 seq=None,
                 dest=None):
        """ send acknowledgement message
        """
        ack_msg = AckMsg()
        ack_msg.set_seq(seq)
        ack_msg.set_node_id(dest)
        
        self.bif.sendMsg(ack_msg, dest)
        self.log.debug("Sending Ack %s to %s" %
                       (seq, dest))


    def booted_node(self, msg):
        """Receieve and process a boot message object from the base station
        """

        if msg.get_special() != Packets.SPECIAL:
            raise Exception("Corrupted packet - special is %02x not %02x" %
                            (msg.get_special(), Packets.SPECIAL))
        try:
            session = Session()
            current_time = datetime.utcnow()
            node_id = msg.getAddr()
            clustered = msg.get_clustered()
            version = msg.get_version()
            version = "".join([chr(i) for i in version])
  
            node = session.query(Node).get(node_id)
            if node is None:
                add_node(session, node_id)

            b = NodeBoot(time=current_time,
                         nodeId=node_id,
                         clustered=clustered,
                         version=version)
            
            session.add(b)
            session.flush()
            self.log.debug("boot: %s %s, %s, %s" % (current_time, node_id, clustered, version))
            session.commit()
        except Exception as exc:
            session.rollback()
            self.log.exception("error during storing (boot): " + str(exc))
        finally:
            session.close()

        return True


    def store_state(self, msg):
        """ receive and process a message object from the base station
        """
    
        if msg.get_special() != Packets.SPECIAL:
            raise Exception("Corrupted packet - special is %02x not %02x" %
                            (msg.get_special(), Packets.SPECIAL))

        try:
            session = Session()
            current_time = datetime.utcnow()
            node_id = msg.getAddr()
            parent_id = msg.get_ctp_parent_id()
            seq = msg.get_seq()
            rssi_val = msg.get_rssi()

            node = session.query(Node).get(node_id)
            loc_id = None
            if node is None:
                add_node(session, node_id)
            else:
                loc_id = node.locationId


            pack_state = PackState.from_message(msg)
            
            if duplicate_packet(session=session,
                                receipt_time=current_time,
                                node_id=node_id,
                                localtime=msg.get_timestamp()):
                LOGGER.info("duplicate packet %d->%d, %d %s" %
                            (node_id, parent_id, msg.get_timestamp(), str(msg)))

                return False

            # write a node state row
            node_state = NodeState(time=current_time,
                                   nodeId=node_id,
                                   parent=parent_id,
                localtime=msg.get_timestamp(),
                seq_num=seq,
                rssi = rssi_val)
            session.add(node_state)

            for i, value in pack_state.d.iteritems():
                type_id = i
                if math.isinf(value) or math.isnan(value):
                    value = None

                r = Reading(time=current_time,
                            nodeId=node_id,
                            typeId=type_id,
                            locationId=loc_id,
                            value=value)
                try:
                    session.add(r)
                    session.flush()

                except sqlalchemy.exc.IntegrityError, e:
                    self.log.error("Unable to store reading, checking if node type exists")
                    self.log.error(e)
                    session.rollback()
                    s = session.query(SensorType).filter_by(id=i).first()
                    if s is None:
                        s = SensorType(id=type_id,name="UNKNOWN")
                        session.add(s)
                        self.log.info("Adding new sensortype")
                        session.flush()
                        session.add(r)
                        session.flush()                            
                    else:
                        self.log.error("Sensor type exists")


            self.log.debug("reading: %s, %s" % (node_state, pack_state))
            session.commit()

            #send acknowledgement to base station to fwd to node
            self.send_ack(seq=seq,
                          dest=node_id)
                     

        except Exception as exc:
            session.rollback()
            self.log.exception("error during storing (reading): " + str(exc))