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))
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))
from LoRaWAN import LoRaWAN # Configurations are entered parallel to main execution upon button press for 2.5 secs user_button.set_config_blocking(False) # Set debug level - has to be set after logger was initialized and device was configured logger_factory.set_level('status_logger', get_logging_level()) # Initialize file system initialize_file_system() # Remove residual files from the previous run (removes all files in the current and processing dir) remove_residual_files() # Get a dictionary of sensors and their status sensors = get_sensors() # Join the LoRa network lora = False if (True in sensors.values() or gps_on) and config.get_config("LORA") == "ON": lora = LoRaWAN(status_logger) # Initialise temperature and humidity sensor thread with id: TEMP if sensors[s.TEMP]: TEMP_logger = SensorLogger(sensor_name=s.TEMP, terminal_out=True) if config.get_config(s.TEMP) == "SHT35": temp_sensor = TempSHT35(TEMP_logger, status_logger) status_logger.info("Temperature and humidity sensor initialized") # Initialise PM sensor threads
def run_test(self): pycom.rgbled(0x66039a) # Purple :] self.logger.info("Running hardware test") active_sensors = get_sensors() active_sensor_names = list(active_sensors.keys()) self.logger.info("Found {} sensors: {}".format( len(active_sensor_names), active_sensor_names)) for sensor_name in active_sensor_names: if active_sensors[sensor_name] == False: self.logger.info( "Skipping test of disabled sensor {}".format(sensor_name)) continue self.logger.info("Testing sensor {}".format(sensor_name)) sensor_type = config.get_config(sensor_name) self.logger.info("Sensor {} found to be of type {}".format( sensor_name, sensor_type)) self.logger.info("Attempting to initialize sensor") try: if sensor_type == "PMS5003": sensor = Plantower( pins=("P3", "P17"), id=1, ) elif sensor_type == "SPS030": sensor = Sensirion(retries=1, pins=("P11", "P18"), id=2) elif sensor_type == "SHT35": sensor = TempSHT35(None, None) else: raise ValueError("Unknown sensor type") except Exception as e: self.logger.exception( "Failed to initialize sensor: {}".format(e)) continue time.sleep(1) init_count = 0 try: init_limit = int(config.get_config(sensor_name + "_init")) except TypeError: # Sensor doesn't have a set init time. init_limit = 5 self.logger.info( "Warming up sensor for {} seconds".format(init_limit)) while init_count < init_limit: try: time.sleep(1) sensor.read() init_count += 1 except Exception as e: self.logger.exception( "Failed to read from sensor: {}".format(e)) pass time.sleep(3) # We can't read the sensor too fast after warmup self.logger.info("Attempting read of data from sensor") try: recv = sensor.read() if recv: recv_str = str(recv) self.logger.info("Read data: {}".format(recv_str)) else: self.logger.info("sensor.read returned no data") except Exception as e: self.logger.exception( "Failed to read from sensor {}".format(sensor_type)) pass self.logger.info("Finished testing sensor {}".format(sensor_name)) self.logger.info("Hardware test finished") pycom.rgbled(0x000000) # Turn off