示例#1
0
    def check_date(self):
        """
        Checks recursively if the message on the bottom of the stack is within a month
        """

        buffer_line = self.lora_buffer.read(
            read_tail=True)  # read the tail of the lora_buffer
        buffer_lst = buffer_line.split(
            ',')  # convert string to a list of strings
        time_now = time.gmtime()  # get current date

        # get year, month and minutes of the month now
        year_now, month_now, minutes_now = time_now[0], time_now[
            1], minutes_of_the_month()

        # get year, month and minutes of the month of the last message in the lora_buffer
        year_then, month_then, minutes_then = int(buffer_lst[0]) + 2000, int(
            buffer_lst[1]), int(buffer_lst[4])

        # logic to decide if message is older than a month
        if year_then < year_now or month_then < month_now:
            if (month_then + 1
                    == month_now) or (month_then == 12 and month_now == 1
                                      and year_then + 1 == year_now):
                if minutes_then < minutes_now + 24 * 60:
                    self.lora_buffer.remove_tail()  # remove message
                    self.check_date()  # call recursively
            else:
                self.lora_buffer.remove_tail()  # remove message
                self.check_date()  # call recursively
示例#2
0
def get_sensor_averages(logger, lora):
    """
    Gets averages for specific columns of defined sensor data, loads them into a line and appends it to the file which
    the LoRa thread sends data from.
    A sensor is defined if it is ticked in the configuration and has data to be sent (has a current.csv file).
    :type logger: LoggerFactory object (status_logger)
    :param is_def: Stores which sensors are defined in the form "sensor_name" : True/False
    :type is_def: dict
    """

    logger.debug("Calculating averages")

    # get a dictionary of sensors and their status
    sensors = get_sensors()
    fmt = get_format(sensors)
    version = str(config.get_config("version"))
    timestamp = s.csv_timestamp_template.format(
        *time.gmtime())  # get current time in desired format
    minutes = str(minutes_of_the_month())  # get minutes past last midnight

    try:
        sensor_averages = {}
        for sensor_name in [s.TEMP, s.PM1, s.PM2]:
            if sensors[sensor_name]:
                sensor_averages.update(calculate_average(sensor_name, logger))

        # Append averages to the line to be sent over LoRa according to which sensors are defined.
        line_to_log = '{}' + fmt + ',' + version + ',' + minutes
        for sensor_name in [s.TEMP, s.PM1, s.PM2]:
            if sensors[sensor_name]:
                line_to_log += ',' + str(
                    config.get_config(sensor_name + "_id")) + ',' + ','.join(
                        sensor_averages[sensor_name + "_avg"]) + ',' + str(
                            sensor_averages[sensor_name + "_count"])
        line_to_log += '\n'

        # Logs line_to_log to archive and places copies into relevant to_send folders
        log_averages(line_to_log.format(timestamp + ','))
        if config.get_config("LORA") == "ON":
            year_month = timestamp[2:4] + "," + timestamp[5:7] + ','
            lora.lora_buffer.write(line_to_log.format(year_month))

        # If raw data was processed, saved and dumped, processing files can be deleted
        path = s.processing_path
        for sensor_name in [s.TEMP, s.PM1, s.PM2]:
            if sensors[sensor_name]:
                filename = sensor_name + '.csv'
                try:
                    os.remove(path + filename)
                except Exception as e:
                    logger.exception("Failed to remove " + filename + " in " +
                                     path)

    except Exception as e:
        logger.exception("Failed to flash averages")
        blink_led((0x550000, 0.4, True))
示例#3
0
def get_sensor_averages(logger, lora):
    """
    Takes the averages of sensor readings and constructs a line to log to the SD card, terminal and lora buffer
    :param logger: status logger
    :type logger: LoggerFactory object
    :param lora: LoRaWAN object, False if lora is not enabled
    :type lora: LoRaWAN object
    """

    logger.debug("Calculating averages")

    # get a dictionary of sensors and their status
    sensors = get_sensors()
    fmt = get_format(sensors)
    version = str(config.get_config("fmt_version"))
    timestamp = s.csv_timestamp_template.format(
        *time.gmtime())  # get current time in desired format
    minutes = str(minutes_of_the_month())  # get minutes past last midnight

    try:
        sensor_averages = {}
        for sensor_name in [s.TEMP, s.PM1, s.PM2]:
            if sensors[sensor_name]:
                sensor_averages.update(calculate_average(sensor_name, logger))

        # Append averages to the line to be sent over LoRa according to which sensors are defined.
        line_to_log = '{}' + fmt + ',' + version + ',' + minutes
        for sensor_name in [s.TEMP, s.PM1, s.PM2]:
            if sensors[sensor_name]:
                line_to_log += ',' + str(
                    config.get_config(sensor_name + "_id")) + ',' + ','.join(
                        sensor_averages[sensor_name + "_avg"]) + ',' + str(
                            sensor_averages[sensor_name + "_count"])
        line_to_log += '\n'

        # Logs line_to_log to archive and places copies into relevant to_send folders
        log_averages(line_to_log.format(timestamp + ','))
        if lora is not False:
            year_month = timestamp[2:4] + "," + timestamp[5:7] + ','
            lora.lora_buffer.write(line_to_log.format(year_month))

        # If raw data was processed, saved and dumped, processing files can be deleted
        path = s.processing_path
        for sensor_name in [s.TEMP, s.PM1, s.PM2]:
            if sensors[sensor_name]:
                filename = sensor_name + '.csv'
                try:
                    os.remove(path + filename)
                except Exception as e:
                    pass

    except Exception as e:
        logger.exception("Failed to flash averages")
        blink_led((0x550000, 0.4, True))
示例#4
0
def get_position(logger, lora):

    if gps_lock.locked():
        logger.debug("Waiting for other gps thread to finish")
    with gps_lock:
        logger.info("Getting position via GPS")

        serial, chrono, indicator_led = gps_init(logger)
        com_counter = int(chrono.read())  # counter for checking whether gps is connected
        message = False

        while True:
            # data_in = '$GPGGA,085259.000,5056.1384,N,00123.1522,W,1,8,1.17,25.1,M,47.6,M,,*7D\r\n'
            data_in = (str(serial.readline()))[1:]

            if (int(chrono.read()) - com_counter) >= 10:
                gps_deinit(serial, logger, message, indicator_led)
                logger.error("GPS enabled, but not connected")
                return False

            if data_in[1:4] != "$GP":
                time.sleep(1)
            else:
                for char in data_in:
                    sentence = gps.update(char)
                    if sentence == "GPGGA":
                        com_counter = int(chrono.read())

                        # set aim for the quality of the signal based on the time elapsed
                        elapsed = chrono.read() / int(config.get_config("GPS_timeout"))

                        hdop_aim = [1, 1.2, 1.5, 1.8, 2, 2.5, 3, 4, 5, 6, 7]
                        time_limit = [0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9]

                        for index in range(len(time_limit)):
                            if elapsed < time_limit[index]:
                                break

                        # Process data only if quality of signal is great
                        if 0 < gps.hdop <= hdop_aim[index] and gps.satellites_in_use >= 3:

                            latitude = gps.latitude[0] + gps.latitude[1]/60
                            if gps.latitude[2] == 'S':
                                latitude = -latitude

                            longitude = gps.longitude[0] + gps.longitude[1]/60
                            if gps.longitude[2] == 'W':
                                longitude = -longitude

                            message = """Successfully acquired location from GPS
                            Satellites used: {}
                            HDOP: {}
                            Latitude: {}
                            Longitude: {}
                            Altitude: {}""".format(gps.satellites_in_use, gps.hdop, latitude, longitude, gps.altitude)

                            # Process GPS location
                            timestamp = s.csv_timestamp_template.format(*time.gmtime())  # get current time in desired format
                            lst_to_log = [timestamp, latitude, longitude, gps.altitude]
                            str_lst_to_log = list(map(str, lst_to_log))  # cast to string
                            line_to_log = ','.join(str_lst_to_log) + '\n'

                            # Print to terminal and log to archive
                            sys.stdout.write(s.GPS + " - " + line_to_log)
                            with open(s.archive_path + s.GPS + '.csv', 'a') as f_archive:
                                f_archive.write(line_to_log)

                            if config.get_config("LORA") == "ON":
                                # get year and month from timestamp
                                year_month = timestamp[2:4] + "," + timestamp[5:7] + ','

                                # get minutes since start of the month
                                minutes = str(minutes_of_the_month())

                                # Construct LoRa message
                                line_to_log = year_month + 'G,' + str(config.get_config("version")) + ',' + minutes + ',' \
                                              + str(config.get_config("GPS_id")) + ',' + ','.join(str_lst_to_log[1:]) + '\n'

                                # Logs line_to_log to be sent over lora
                                lora.lora_buffer.write(line_to_log)

                            gps_deinit(serial, logger, message, indicator_led)
                            return True

            # If timeout elapsed exit function or thread
            if chrono.read() >= int(config.get_config("GPS_timeout")):
                gps_deinit(serial, logger, message, indicator_led)
                logger.error("""GPS timeout
                Check if GPS module is connected
                Place device under clear sky
                Increase GPS timeout in configurations""")
                return False