def startup_stats(self): """Initial statistics collection and transmssion at startup""" try: # if statistics file doesn't exist, create it if not os.path.isfile(STATS_CSV): self.logger.debug("[Daemon] Statistics file doesn't " "exist, creating {}".format(STATS_CSV)) recreate_stat_file(ID_FILE, STATS_CSV, STATS_INTERVAL, MYCODO_VERSION) daemon_startup_time = timeit.default_timer() - self.startup_timer self.logger.info("[Daemon] Mycodo v{} started in {:.3f}" " seconds".format(MYCODO_VERSION, daemon_startup_time)) add_update_csv(self.logger, STATS_CSV, 'daemon_startup_seconds', daemon_startup_time) except Exception as msg: self.logger.exception( "[Daemon] Statistics initilization Error: {}".format(msg))
def startup_stats(self): """Initial statistics collection and transmssion at startup""" try: # if statistics file doesn't exist, create it if not os.path.isfile(STATS_CSV): self.logger.debug( "Statistics file doesn't exist, creating {file}".format( file=STATS_CSV)) recreate_stat_file() daemon_startup_time = timeit.default_timer()-self.startup_timer self.logger.info("Mycodo v{ver} started in {time:.3f}" " seconds".format(ver=MYCODO_VERSION, time=daemon_startup_time)) add_update_csv(STATS_CSV, 'daemon_startup_seconds', daemon_startup_time) except Exception as msg: self.logger.exception( "Statistics initialization Error: {err}".format(err=msg))
def startup_stats(self): """Initial statistics collection and transmssion at startup""" try: # if statistics file doesn't exist, create it if not os.path.isfile(STATS_CSV): self.logger.debug("[Daemon] Statistics file doesn't " "exist, creating {}".format(STATS_CSV)) recreate_stat_file(ID_FILE, STATS_CSV, STATS_INTERVAL, MYCODO_VERSION) daemon_startup_time = timeit.default_timer()-self.startup_timer self.logger.info("[Daemon] Mycodo v{} started in {:.3f}" " seconds".format(MYCODO_VERSION, daemon_startup_time)) add_update_csv(self.logger, STATS_CSV, 'daemon_startup_seconds', daemon_startup_time) except Exception as msg: self.logger.exception( "[Daemon] Statistics initilization Error: {}".format(msg))
def send_stats(self): """Collect and send statistics""" try: stat_dict = return_stat_file_dict(STATS_CSV) if float(stat_dict['next_send']) < time.time(): self.timer_stats = self.timer_stats + STATS_INTERVAL add_update_csv(self.logger, STATS_CSV, 'next_send', self.timer_stats) else: self.timer_stats = float(stat_dict['next_send']) except Exception as msg: self.logger.exception("Error: Cound not read stats file. " "Regenerating. Error msg: {}".format(msg)) os.remove(STATS_CSV) recreate_stat_file(ID_FILE, STATS_CSV, STATS_INTERVAL, MYCODO_VERSION) try: send_stats(self.logger, STATS_HOST, STATS_PORT, STATS_USER, STATS_PASSWORD, STATS_DATABASE, MYCODO_DB_PATH, USER_DB_PATH, STATS_CSV, MYCODO_VERSION, session_scope, LCD, Log, Method, PID, Relay, Sensor, Timer, Users) except Exception as msg: self.logger.exception("Error: Cound not send statistics: " "{}".format(msg))
def send_stats(self): """Collect and send statistics""" try: stat_dict = return_stat_file_dict(STATS_CSV) if float(stat_dict['next_send']) < time.time(): self.timer_stats = self.timer_stats+STATS_INTERVAL add_update_csv(STATS_CSV, 'next_send', self.timer_stats) else: self.timer_stats = float(stat_dict['next_send']) except Exception as msg: self.logger.exception( "Error: Could not read stats file. Regenerating. Error msg: " "{msg}".format(msg=msg)) try: os.remove(STATS_CSV) except OSError: pass recreate_stat_file() try: send_stats() except Exception as except_msg: self.logger.exception( "Error: Could not send statistics: {err}".format( err=except_msg))
def send_stats(self): """Collect and send statistics""" try: stat_dict = return_stat_file_dict(STATS_CSV) if float(stat_dict['next_send']) < time.time(): self.timer_stats = self.timer_stats+STATS_INTERVAL add_update_csv(self.logger, STATS_CSV, 'next_send', self.timer_stats) else: self.timer_stats = float(stat_dict['next_send']) except Exception as msg: self.logger.exception("Error: Cound not read stats file. " "Regenerating. Error msg: {}".format(msg)) os.remove(STATS_CSV) recreate_stat_file(ID_FILE, STATS_CSV, STATS_INTERVAL, MYCODO_VERSION) try: send_stats(self.logger, STATS_HOST, STATS_PORT, STATS_USER, STATS_PASSWORD, STATS_DATABASE, MYCODO_DB_PATH, USER_DB_PATH, STATS_CSV, MYCODO_VERSION, session_scope, LCD, Log, Method, PID, Relay, Sensor, Timer, Users) except Exception as msg: self.logger.exception("Error: Cound not send statistics: " "{}".format(msg))
def run(self): self.start_all_controllers() self.startup_stats() try: # loop until daemon is instructed to shut down while self.daemon_run: now = time.time() # If timelapse active, take photo at predefined periods if (os.path.isfile(FILE_TIMELAPSE_PARAM) and os.path.isfile(LOCK_FILE_TIMELAPSE)): # Read user-defined timelapse parameters with open(FILE_TIMELAPSE_PARAM, mode='r') as infile: reader = csv.reader(infile) dict_timelapse_param = OrderedDict( (row[0], row[1]) for row in reader) if now > float(dict_timelapse_param['end_time']): try: os.remove(FILE_TIMELAPSE_PARAM) os.remove(LOCK_FILE_TIMELAPSE) except: pass elif now > float(dict_timelapse_param['next_capture']): # Ensure next capture is greater than now (in case of power failure/reboot) next_capture = float( dict_timelapse_param['next_capture']) capture_number = int( dict_timelapse_param['capture_number']) while next_capture < now: # Update last capture and image number to latest before capture next_capture += float( dict_timelapse_param['interval']) capture_number += 1 add_update_csv(logger, FILE_TIMELAPSE_PARAM, 'next_capture', next_capture) add_update_csv(logger, FILE_TIMELAPSE_PARAM, 'capture_number', capture_number) # Capture image with session_scope(MYCODO_DB_PATH) as new_session: camera = new_session.query(Method) camera_record( INSTALL_DIRECTORY, 'timelapse', camera, start_time=dict_timelapse_param['start_time'], capture_number=capture_number) elif (os.path.isfile(FILE_TIMELAPSE_PARAM) or os.path.isfile(LOCK_FILE_TIMELAPSE)): try: os.remove(FILE_TIMELAPSE_PARAM) os.remove(LOCK_FILE_TIMELAPSE) except: pass # Log ram usage every 24 hours if now > self.timer_ram_use: self.timer_ram_use = now + 86400 ram = resource.getrusage( resource.RUSAGE_SELF).ru_maxrss / float(1000) self.logger.info("[Daemon] {} MB ram in use".format(ram)) # collect and send anonymous statistics if (not self.opt_out_statistics and now > self.timer_stats): self.send_stats() time.sleep(0.25) except Exception as except_msg: self.logger.exception("Unexpected error: {}: {}".format( sys.exc_info()[0], except_msg)) raise # If the daemon errors or finishes, shut it down finally: self.logger.debug("[Daemon] Stopping all running controllers") self.stop_all_controllers() self.logger.info("[Daemon] Mycodo terminated in {:.3f} seconds".format( timeit.default_timer() - self.thread_shutdown_timer)) self.terminated = True # Wait for the client to receive the response before it disconnects time.sleep(0.25)
def run(self): self.start_all_controllers() self.startup_stats() try: # loop until daemon is instructed to shut down while self.daemon_run: now = time.time() # If timelapse active, take photo at predefined periods if (os.path.isfile(FILE_TIMELAPSE_PARAM) and os.path.isfile(LOCK_FILE_TIMELAPSE)): # Read user-defined timelapse parameters with open(FILE_TIMELAPSE_PARAM, mode='r') as infile: reader = csv.reader(infile) dict_timelapse_param = OrderedDict((row[0], row[1]) for row in reader) if now > float(dict_timelapse_param['end_time']): try: os.remove(FILE_TIMELAPSE_PARAM) os.remove(LOCK_FILE_TIMELAPSE) except: pass elif now > float(dict_timelapse_param['next_capture']): # Ensure next capture is greater than now (in case of power failure/reboot) next_capture = float(dict_timelapse_param['next_capture']) capture_number = int(dict_timelapse_param['capture_number']) while next_capture < now: # Update last capture and image number to latest before capture next_capture += float(dict_timelapse_param['interval']) capture_number += 1 add_update_csv(logger, FILE_TIMELAPSE_PARAM, 'next_capture', next_capture) add_update_csv(logger, FILE_TIMELAPSE_PARAM, 'capture_number', capture_number) # Capture image with session_scope(MYCODO_DB_PATH) as new_session: camera = new_session.query(CameraStill).first() camera_record( INSTALL_DIRECTORY, 'timelapse', camera, start_time=dict_timelapse_param['start_time'], capture_number=capture_number) elif (os.path.isfile(FILE_TIMELAPSE_PARAM) or os.path.isfile(LOCK_FILE_TIMELAPSE)): try: os.remove(FILE_TIMELAPSE_PARAM) os.remove(LOCK_FILE_TIMELAPSE) except: pass # Log ram usage every 24 hours if now > self.timer_ram_use: self.timer_ram_use = now+86400 ram = resource.getrusage( resource.RUSAGE_SELF).ru_maxrss / float(1000) self.logger.info("[Daemon] {} MB ram in use".format(ram)) # collect and send anonymous statistics if (not self.opt_out_statistics and now > self.timer_stats): self.send_stats() time.sleep(0.25) GPIO.cleanup() except Exception as except_msg: self.logger.exception("Unexpected error: {}: {}".format( sys.exc_info()[0], except_msg)) raise # If the daemon errors or finishes, shut it down finally: self.logger.debug("[Daemon] Stopping all running controllers") self.stop_all_controllers() self.logger.info("[Daemon] Mycodo terminated in {:.3f} seconds".format( timeit.default_timer()-self.thread_shutdown_timer)) self.terminated = True # Wait for the client to receive the response before it disconnects time.sleep(0.25)