01234567890123456789012345678901234567890123456789012345678901234567890123456789
512851295130513151325133513451355136513751385139514051415142514351445145514651475148 51495150515151525153 515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180 55185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576 56405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680 669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731 | <----SKIPPED LINES----> # then we need to # 1) update the histograms.php file with the correct file links, and # 2) delete the images that are now obsolete. epoch_string = EpochDisplayTime(time.time(), '%Y%m%d_%H%M%S_') ImageHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string, heartbeat=heartbeat) histogram_id_sequence = [ 'origin', 'destination', 'day_of_month', 'day_of_week', 'hour', 'bearing', 'distance', 'speed', 'vert_rate', 'altitude', 'airline', 'aircraft', 'aircraft_length'] path = WEBSERVER_PATH + WEBSERVER_IMAGE_RELATIVE_FOLDER files = os.listdir(path) lines = [ '<head>', '<title>Flight Tracker: Histograms</title>', '</head>', '<body>', '<?php include "nav.html" ?>', '<div class="resp-iframe">' ] for histogram_id in histogram_id_sequence: pattern = re.compile('histogram[0-9_]*%s.png' % histogram_id) matching_files = sorted( [f for f in files if pattern.match(f)]) # save the most recent; delete the others lines.append('<img id="%s" src="images/%s"><p>' % ( histogram_id, matching_files[-1])) for f in matching_files[:-1]: RemoveFile( os.path.join(WEBSERVER_PATH, WEBSERVER_IMAGE_RELATIVE_FOLDER, f)) lines.extend(['</div>', '</body>']) html = '\n'.join(lines) WriteFile(HISTOGRAM_IMAGE_HTML, html) return histogram_messages def SaveFlightsByAltitudeDistanceCSV( flights, max_days=0, filename='flights_by_alt_dist.csv', precision=100): """Generates CSV of hour of day, altitude, and distance. Generates a csv with 26 columns: - col#1: altitude (in feet) <----SKIPPED LINES----> RPi.GPIO.output(GPIO_SOFT_RESET[1], False) # signal that reset received Log(msg) def InterruptShutdownFromSignal(signalNumber, unused_frame): """Sets flag so main loop will terminate when it completes the iteration. The function signature is defined by the python language - i.e.: these two variables are passed automatically for registered signals. This function is only triggered by an interrupt signal. """ msg = '%d received termination signal %d (%s)' % ( os.getpid(), signalNumber, signal.Signals(signalNumber).name) # pylint: disable=E1101 global SHUTDOWN_SIGNAL SHUTDOWN_SIGNAL = msg Log(msg) def PerformGracefulShutdown(queues, shutdown, reboot): """Complete the graceful shutdown process by cleaning up. Args: queues: iterable of queues shared with child processes to be closed shutdown: tuple of shared flags with child processes to initiate shutdown in children reboot: boolean indicating whether we should trigger a reboot """ reboot_msg = '' if reboot: reboot_msg = ' and rebooting' Log('Shutting down self (%d)%s' % (os.getpid(), reboot_msg)) # TODO: the q.close() may have been blocking some of the shutdowns, since # it is blocking until the queue is fully drained. Let's see if we have # fewer problems without this code. #for q in queues: # q.close() for v in shutdown: # send the shutdown signal to child processes v.value = 1 if RASPBERRY_PI: RPi.GPIO.cleanup() UpdateDashboard(True, failure_message=SHUTDOWN_SIGNAL) if reboot or REBOOT_SIGNAL: time.sleep(10) # wait 10 seconds for children to shut down as well os.system('sudo reboot') sys.exit() def FindRunningParents(): """Returns proc ids of processes with identically-named python file running. In case there are multiple children processes spawned with the same name, such as via multiprocessing, this will only return the parent id (since a killed child process will likely just be respawned). <----SKIPPED LINES----> # with process IDs 1106 & 1110. if SHUTDOWN_SIGNAL: Log('Race condition? Though this process %s is just in startup, ' 'SHUTDOWN_SIGNAL has already been set to True\n' 'already_running_ids (PIDs detected when process started up): %s\n' 'still_running_ids (PIDs detected at start of function call): %s\n' '\nProcess shutting down' % (str(os.getpid()), already_running_ids, still_running_ids)) sys.exit() n = 0 running_parents = FindRunningParents() while running_parents: if n == max_seconds: Log('Kill signal sent from this process %d to %s, but %s still ' 'running after waiting cume %d seconds; rebooting' % ( os.getpid(), str(already_running_ids), str(running_parents), n+1)) PerformGracefulShutdown((), (), True) if not n % 3: Log('Kill signal sent from this process %d to %s, but %s still ' 'running after waiting cume %d seconds' % ( os.getpid(), str(already_running_ids), str(running_parents), n)) n += 1 time.sleep(1) running_parents = FindRunningParents() def InitArduinoVariables(): """Initializes variables for arduino threads with shared-memory queues.""" to_remote_q = multiprocessing.Queue() to_servo_q = multiprocessing.Queue() to_main_q = multiprocessing.Queue() # shared flags to initiate shutdown shutdown_remote = multiprocessing.Value('i') shutdown_servo = multiprocessing.Value('i') shutdown = (shutdown_remote, shutdown_servo) return (to_remote_q, to_servo_q, to_main_q, shutdown) <----SKIPPED LINES----> # check time & if appropriate, display next message from queue next_message_time = ManageMessageQueue( message_queue, next_message_time, configuration, screen_history) reboot = CheckRebootNeeded( startup_time, message_queue, json_desc_dict, configuration) CheckTemperature() if not SIMULATION: time.sleep(max(0, next_loop_time - time.time())) next_loop_time = time.time() + LOOP_DELAY_SECONDS else: SIMULATION_COUNTER += 1 if simulation_slowdown: SimulationSlowdownNearFlight(flights, persistent_nearby_aircraft) if SIMULATION: SimulationEnd(message_queue, flights, screen_history) PerformGracefulShutdown( (to_remote_q, to_servo_q, to_main_q), shutdown, reboot) if __name__ == "__main__": #interrupt, as in ctrl-c signal.signal(signal.SIGINT, InterruptShutdownFromSignal) #terminate, when another instance found or via kill signal.signal(signal.SIGTERM, InterruptShutdownFromSignal) if '-i' in sys.argv: BootstrapInsightList() else: main_settings = ReadAndParseSettings(CONFIG_FILE) if 'code_profiling_enabled' in main_settings: import cProfile cProfile.run( 'main()', 'messageboard_stats-%s.profile' % EpochDisplayTime(time.time(), '%Y-%m-%d-%H%M')) else: main() |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190 552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551 55525553555455555556555755585559 55605561556255635564556555665567556855695570557155725573557455755576557755785579 56435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683 669366946695669666976698669967006701670267036704670567066707670867096710671167126713 67146715671667176718671967206721672267236724672567266727672867296730673167326733 | <----SKIPPED LINES----> # then we need to # 1) update the histograms.php file with the correct file links, and # 2) delete the images that are now obsolete. epoch_string = EpochDisplayTime(time.time(), '%Y%m%d_%H%M%S_') ImageHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string, heartbeat=heartbeat) histogram_id_sequence = [ 'origin', 'destination', 'day_of_month', 'day_of_week', 'hour', 'bearing', 'distance', 'speed', 'vert_rate', 'altitude', 'airline', 'aircraft', 'aircraft_length'] path = WEBSERVER_PATH + WEBSERVER_IMAGE_RELATIVE_FOLDER files = os.listdir(path) lines = [ '<head>', ' <title>Flight Tracker: Histograms</title>', ' <meta content="text/html; charset=UTF-8" http-equiv="content-type">', ' <meta name="viewport" content="width=device-width,initial-scale=1">', '</head>', '<body>', '<?php include "nav.html" ?>', '<div class="resp-iframe">' ] open_image = ( '<div class="content-cap-holder">\n' ' <div class="image-box"' 'style="max-width:900px;min-width:300px;width:100%;">\n' ' <figure>\n') close_image = ('</figure>\n' ' </div>\n' ' </div>\n') for histogram_id in histogram_id_sequence: pattern = re.compile('histogram[0-9_]*%s.png' % histogram_id) matching_files = sorted( [f for f in files if pattern.match(f)]) # save the most recent; delete the others lines.append('%s<img id="%s" src="images/%s">%s' % ( open_image, histogram_id, matching_files[-1], close_image)) for f in matching_files[:-1]: RemoveFile( os.path.join(WEBSERVER_PATH, WEBSERVER_IMAGE_RELATIVE_FOLDER, f)) lines.extend(['</div>', '</body>']) html = '\n'.join(lines) WriteFile(HISTOGRAM_IMAGE_HTML, html) return histogram_messages def SaveFlightsByAltitudeDistanceCSV( flights, max_days=0, filename='flights_by_alt_dist.csv', precision=100): """Generates CSV of hour of day, altitude, and distance. Generates a csv with 26 columns: - col#1: altitude (in feet) <----SKIPPED LINES----> RPi.GPIO.output(GPIO_SOFT_RESET[1], False) # signal that reset received Log(msg) def InterruptShutdownFromSignal(signalNumber, unused_frame): """Sets flag so main loop will terminate when it completes the iteration. The function signature is defined by the python language - i.e.: these two variables are passed automatically for registered signals. This function is only triggered by an interrupt signal. """ msg = '%d received termination signal %d (%s)' % ( os.getpid(), signalNumber, signal.Signals(signalNumber).name) # pylint: disable=E1101 global SHUTDOWN_SIGNAL SHUTDOWN_SIGNAL = msg Log(msg) def PerformGracefulShutdown(shutdown, reboot): """Complete the graceful shutdown process by cleaning up. Args: shutdown: tuple of shared flags with child processes to initiate shutdown in children reboot: boolean indicating whether we should trigger a reboot """ reboot_msg = '' if reboot: reboot_msg = ' and rebooting' Log('Shutting down self (%d)%s' % (os.getpid(), reboot_msg)) for v in shutdown: # send the shutdown signal to child processes v.value = 1 if RASPBERRY_PI: RPi.GPIO.cleanup() UpdateDashboard(True, failure_message=SHUTDOWN_SIGNAL) if reboot or REBOOT_SIGNAL: time.sleep(10) # wait 10 seconds for children to shut down as well os.system('sudo reboot') sys.exit() def FindRunningParents(): """Returns proc ids of processes with identically-named python file running. In case there are multiple children processes spawned with the same name, such as via multiprocessing, this will only return the parent id (since a killed child process will likely just be respawned). <----SKIPPED LINES----> # with process IDs 1106 & 1110. if SHUTDOWN_SIGNAL: Log('Race condition? Though this process %s is just in startup, ' 'SHUTDOWN_SIGNAL has already been set to True\n' 'already_running_ids (PIDs detected when process started up): %s\n' 'still_running_ids (PIDs detected at start of function call): %s\n' '\nProcess shutting down' % (str(os.getpid()), already_running_ids, still_running_ids)) sys.exit() n = 0 running_parents = FindRunningParents() while running_parents: if n == max_seconds: Log('Kill signal sent from this process %d to %s, but %s still ' 'running after waiting cume %d seconds; rebooting' % ( os.getpid(), str(already_running_ids), str(running_parents), n+1)) PerformGracefulShutdown((), True) if not n % 3: Log('Kill signal sent from this process %d to %s, but %s still ' 'running after waiting cume %d seconds' % ( os.getpid(), str(already_running_ids), str(running_parents), n)) n += 1 time.sleep(1) running_parents = FindRunningParents() def InitArduinoVariables(): """Initializes variables for arduino threads with shared-memory queues.""" to_remote_q = multiprocessing.Queue() to_servo_q = multiprocessing.Queue() to_main_q = multiprocessing.Queue() # shared flags to initiate shutdown shutdown_remote = multiprocessing.Value('i') shutdown_servo = multiprocessing.Value('i') shutdown = (shutdown_remote, shutdown_servo) return (to_remote_q, to_servo_q, to_main_q, shutdown) <----SKIPPED LINES----> # check time & if appropriate, display next message from queue next_message_time = ManageMessageQueue( message_queue, next_message_time, configuration, screen_history) reboot = CheckRebootNeeded( startup_time, message_queue, json_desc_dict, configuration) CheckTemperature() if not SIMULATION: time.sleep(max(0, next_loop_time - time.time())) next_loop_time = time.time() + LOOP_DELAY_SECONDS else: SIMULATION_COUNTER += 1 if simulation_slowdown: SimulationSlowdownNearFlight(flights, persistent_nearby_aircraft) if SIMULATION: SimulationEnd(message_queue, flights, screen_history) PerformGracefulShutdown(shutdown, reboot) if __name__ == "__main__": #interrupt, as in ctrl-c signal.signal(signal.SIGINT, InterruptShutdownFromSignal) #terminate, when another instance found or via kill signal.signal(signal.SIGTERM, InterruptShutdownFromSignal) if '-i' in sys.argv: BootstrapInsightList() else: main_settings = ReadAndParseSettings(CONFIG_FILE) if 'code_profiling_enabled' in main_settings: import cProfile cProfile.run( 'main()', 'messageboard_stats-%s.profile' % EpochDisplayTime(time.time(), '%Y-%m-%d-%H%M')) else: main() |