01234567890123456789012345678901234567890123456789012345678901234567890123456789
445446447448449450451452453454455456457458459460461462463464 465466467468469470471472473474475476477478479480481482483484 11901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230 57705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798 5799 58005801580258035804580558065807 5808580958105811 581258135814581558165817 58185819582058215822582358245825582658275828582958305831583258335834583558365837 71047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147 720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241 72427243724472457246724772487249725072517252725372547255725672577258725972607261 72667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306 | <----SKIPPED LINES----> AIRCRAFT_LENGTH['Cessna Conquest 2 (twin-turboprop)'] = 11.89 AIRCRAFT_LENGTH['Cessna Skyhawk (piston-single)'] = 8.28 AIRCRAFT_LENGTH['Cessna Skylane (piston-single)'] = 8.84 AIRCRAFT_LENGTH['CESSNA T182 Turbo Skylane (piston-single)'] = 8.84 AIRCRAFT_LENGTH['Cessna T206 Turbo Stationair (piston-single)'] = 8.61 AIRCRAFT_LENGTH['Cessna 421 (twin-piston)'] = 11.09 AIRCRAFT_LENGTH['Cirrus SR-20 (piston-single)'] = 7.92 AIRCRAFT_LENGTH['Cirrus SR-22 (piston-single)'] = 7.92 AIRCRAFT_LENGTH['Cirrus SR22 Turbo (piston-single)'] = 7.92 AIRCRAFT_LENGTH['Cirrus Vision SF50 (single-jet)'] = 9.42 AIRCRAFT_LENGTH['Daher-Socata TBM-900 (single-turboprop)'] = 10.72 AIRCRAFT_LENGTH['Dassault Falcon 50 (tri-jet)'] = 18.52 AIRCRAFT_LENGTH['Dassault Falcon 2000 (twin-jet)'] = 20.23 AIRCRAFT_LENGTH['Dassault Falcon 900 (tri-jet)'] = 20.21 AIRCRAFT_LENGTH['Embraer 170/175 (twin-jet)'] = (29.90 + 31.68) / 2 AIRCRAFT_LENGTH['EMBRAER 175 (long wing) (twin-jet)'] = 31.68 AIRCRAFT_LENGTH['Embraer ERJ-135 (twin-jet)'] = 26.33 AIRCRAFT_LENGTH['Embraer ERJ-145 (twin-jet)'] = 29.87 AIRCRAFT_LENGTH['Embraer ERJ 175 (twin-jet)'] = 31.68 AIRCRAFT_LENGTH['Embraer ERJ 190 (twin-jet)'] = 36.25 AIRCRAFT_LENGTH['Embraer Legacy 450 (twin-jet)'] = 19.69 AIRCRAFT_LENGTH['Embraer Legacy 550 (twin-jet)'] = 20.74 AIRCRAFT_LENGTH['Embraer Legacy 600/650 (twin-jet)'] = 26.33 AIRCRAFT_LENGTH['Embraer Phenom 300 (twin-jet)'] = 15.9 AIRCRAFT_LENGTH['Eurocopter EC-635 (twin-turboshaft)'] = 10.21 AIRCRAFT_LENGTH['Fairchild Dornier 328JET (twin-jet)'] = 21.11 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream 3 (twin-jet)'] = 25.32 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G450 (twin-jet)'] = 27.23 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G550 (twin-jet)'] = 29.39 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G650 (twin-jet)'] = 30.41 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream IV (twin-jet)'] = 26.92 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream V (twin-jet)'] = 29.4 AIRCRAFT_LENGTH['Hawker Beechcraft 4000 (twin-jet)'] = 21.08 AIRCRAFT_LENGTH['Honda HondaJet (twin-jet)'] = 12.99 AIRCRAFT_LENGTH['IAI Gulfstream G100 (twin-jet)'] = 16.94 AIRCRAFT_LENGTH['IAI Gulfstream G150 (twin-jet)'] = 16.94 AIRCRAFT_LENGTH['IAI Gulfstream G200 (twin-jet)'] = 18.97 AIRCRAFT_LENGTH['IAI Gulfstream G280 (twin-jet)'] = 20.3 AIRCRAFT_LENGTH['Learjet 31 (twin-jet)'] = 14.83 AIRCRAFT_LENGTH['Learjet 35 (twin-jet)'] = 14.83 <----SKIPPED LINES----> Args: filename: string of the filename to open, potentially also including the full path. log_exception: boolean indicating whether to log an exception if file not found. Returns: Return text string of file contents. """ try: with open(filename, 'r') as content_file: file_contents = content_file.read() except IOError: if log_exception: Log('Unable to read '+filename) return '' return file_contents # because reading is ~25x more expensive than getmtime, we will only read & # parse if the getmtime is more recent than last call for this file. So this # dict stores the a tuple, the last time read & the resulting parsed return # value CACHED_FILES = {} def ReadAndParseSettings(filename): """Reads filename and parses the resulting key-value pairs into a dict.""" global CACHED_FILES (last_read_time, settings) = CACHED_FILES.get(filename, (0, {})) if os.path.exists(filename): last_modified = os.path.getmtime(filename) if last_modified > last_read_time: setting_str = ReadFile(filename) settings = ParseSettings(setting_str) CACHED_FILES[filename] = (last_modified, settings) return settings # File does not - or at least no longer - exists; so remove the cache if filename in CACHED_FILES: CACHED_FILES.pop(filename) return {} <----SKIPPED LINES----> whether the current active json changed from the prior one. Returns: Boolean - True if different (and processing needed), False if identical """ if SIMULATION_COUNTER == 0: return True (this_json, unused_now) = DUMP_JSONS[SIMULATION_COUNTER] (last_json, unused_now) = DUMP_JSONS[SIMULATION_COUNTER - 1] return this_json != last_json def CheckRebootNeeded( startup_time, message_queue, json_desc_dict, configuration): """Reboot based on duration instance has been running. Reboot needed in one of the following situations: - All quiet: if running for over 24 hours and all is quiet (message queue empty, no planes in radio, and backup not currently in process). - Mostly quiet: if running for over 36 hours and message queue is empty and it's 3a. - Reboot requested via html form. Also checks if reset requested via html form. """ reboot = False global SHUTDOWN_SIGNAL running_hours = (time.time() - startup_time) / SECONDS_IN_HOUR if ( running_hours >= HOURS_IN_DAY and not message_queue and not json_desc_dict.get('radio_range_flights') and # script /home/pi/splitflap/backup.sh creates temp file in this # directory; after it is copied to the NAS, it is deleted not os.listdir('/media/backup')): msg = 'All quiet reboot needed after running for %.2f hours' % running_hours SHUTDOWN_SIGNAL = msg Log(msg) reboot = True if ( running_hours > HOURS_IN_DAY * 1.5 and not message_queue and int(EpochDisplayTime(time.time(), '%-H')) >= 3): msg = ('Early morning reboot needed after running for %.2f hours' % running_hours) SHUTDOWN_SIGNAL = msg Log(msg) reboot = True if 'soft_reboot' in configuration: msg = 'Soft reboot requested via web form' SHUTDOWN_SIGNAL = msg Log(msg) reboot = True RemoveSetting(configuration, 'soft_reboot') if 'end_process' in configuration: msg = 'Process end requested via web form' SHUTDOWN_SIGNAL = msg Log(msg) RemoveSetting(configuration, 'end_process') return reboot <----SKIPPED LINES----> # We repeat the loop every x seconds; this ensures that if the processing # time is long, we don't wait another x seconds after processing completes next_loop_time = time.time() + LOOP_DELAY_SECONDS # These files are read only if the version on disk has been modified more # recently than the last time it was read last_dump_json_timestamp = 0 init_timing.append((time.time(), 7)) WaitUntilKillComplete(already_running_ids) init_timing.append((time.time(), 8)) personal_message = None # Unknown what personal message is displayed temp_last_logged = 0 # Keeps track of when temperature was last logged LogTimes(init_timing) reboot = False iteration = 0 # counter that tracks how many times thru while loop start_time = time.time() if initial_memory_dump: DumpMemorySnapsnot( configuration, iteration, start_time, initial_frame_count) Log('Finishing initialization of %d; starting radio polling loop' % os.getpid()) while ((not SIMULATION or SIMULATION_COUNTER < len(DUMP_JSONS)) and not SHUTDOWN_SIGNAL): last_heartbeat_time = Heartbeat(last_heartbeat_time) new_configuration = ReadAndParseSettings(CONFIG_FILE) UpdateRollingLogSize(new_configuration) CheckForNewFilterCriteria( configuration, new_configuration, message_queue, flights) configuration = new_configuration ResetLogs(configuration) # clear the logs if requested UpdateRollingLogSize(configuration) # if this is a SIMULATION, then process every diff dump. But if it # isn't a simulation, then only read & do related processing for the # next dump if the last-modified timestamp indicates the file has been <----SKIPPED LINES----> insight_messages = CreateFlightInsights( flights, configuration.get('insights'), insight_message_distribution) if configuration.get('next_flight', 'off') == 'on': next_flight_text = FlightInsightNextFlight(flights, configuration) if next_flight_text: insight_messages.insert(0, next_flight_text) insight_messages = [(FLAG_MSG_INSIGHT, m) for m in insight_messages] for insight_message in insight_messages: message_queue.insert(0, insight_message) else: # flight didn't meet display criteria flight['insight_types'] = [] PickleObjectToFile( flight, PICKLE_FLIGHTS, True, timestamp=flight['now']) # now that we've saved the flight, we have no more need to keep the # memory-hogging persistent_path key of that flight in live memory if 'persistent_path' in flights[-1]: del flights[-1]['persistent_path'] else: remote, servo = RefreshArduinos( remote, servo, to_remote_q, to_servo_q, to_main_q, shutdown, flights, json_desc_dict, configuration, screen_history) message_queue, next_message_time = ProcessArduinoCommmands( to_main_q, flights, configuration, message_queue, next_message_time) personal_message = PersonalMessage( configuration, message_queue, personal_message) if SIMULATION: if now: simulated_hour = EpochDisplayTime(now, '%Y-%m-%d %H:00%z') if simulated_hour != prev_simulated_hour: print(simulated_hour) prev_simulated_hour = simulated_hour histogram = ReadAndParseSettings(HISTOGRAM_CONFIG_FILE) RemoveFile(HISTOGRAM_CONFIG_FILE) # We also need to make sure there are flights on which to generate a # histogram! Why might there not be any flights? Primarily during a # simulation, if there's a lingering histogram file at the time of # history restart. if histogram and not flights: Log('Histogram requested (%s) but no flights in memory' % histogram) if histogram and flights: message_queue.extend(TriggerHistograms(flights, histogram)) if message_queue: # Any personal message displayed has been cleared <----SKIPPED LINES----> message_queue, next_message_time, configuration, screen_history) reboot = CheckRebootNeeded( startup_time, message_queue, json_desc_dict, configuration) temp_last_logged = CheckTemperature(configuration, temp_last_logged) 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) # now that we've completed the loop, lets potentially dump the # memory snapshot iteration += 1 # this completes the iteration-th time thru the loop if initial_memory_dump: DumpMemorySnapsnot( configuration, iteration, start_time, initial_frame_count) 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( <----SKIPPED LINES----> |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485 11911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231 5771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846 71137114711571167117711871197120712171227123712471257126712771287129713071317132 71337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155 72147215721672177218721972207221722272237224722572267227722872297230723172327233 7234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285 72907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330 | <----SKIPPED LINES----> AIRCRAFT_LENGTH['Cessna Conquest 2 (twin-turboprop)'] = 11.89 AIRCRAFT_LENGTH['Cessna Skyhawk (piston-single)'] = 8.28 AIRCRAFT_LENGTH['Cessna Skylane (piston-single)'] = 8.84 AIRCRAFT_LENGTH['CESSNA T182 Turbo Skylane (piston-single)'] = 8.84 AIRCRAFT_LENGTH['Cessna T206 Turbo Stationair (piston-single)'] = 8.61 AIRCRAFT_LENGTH['Cessna 421 (twin-piston)'] = 11.09 AIRCRAFT_LENGTH['Cirrus SR-20 (piston-single)'] = 7.92 AIRCRAFT_LENGTH['Cirrus SR-22 (piston-single)'] = 7.92 AIRCRAFT_LENGTH['Cirrus SR22 Turbo (piston-single)'] = 7.92 AIRCRAFT_LENGTH['Cirrus Vision SF50 (single-jet)'] = 9.42 AIRCRAFT_LENGTH['Daher-Socata TBM-900 (single-turboprop)'] = 10.72 AIRCRAFT_LENGTH['Dassault Falcon 50 (tri-jet)'] = 18.52 AIRCRAFT_LENGTH['Dassault Falcon 2000 (twin-jet)'] = 20.23 AIRCRAFT_LENGTH['Dassault Falcon 900 (tri-jet)'] = 20.21 AIRCRAFT_LENGTH['Embraer 170/175 (twin-jet)'] = (29.90 + 31.68) / 2 AIRCRAFT_LENGTH['EMBRAER 175 (long wing) (twin-jet)'] = 31.68 AIRCRAFT_LENGTH['Embraer ERJ-135 (twin-jet)'] = 26.33 AIRCRAFT_LENGTH['Embraer ERJ-145 (twin-jet)'] = 29.87 AIRCRAFT_LENGTH['Embraer ERJ 175 (twin-jet)'] = 31.68 AIRCRAFT_LENGTH['Embraer ERJ 190 (twin-jet)'] = 36.25 AIRCRAFT_LENGTH['Embraer ERJ-190 (twin-jet)'] = 36.25 AIRCRAFT_LENGTH['Embraer Legacy 450 (twin-jet)'] = 19.69 AIRCRAFT_LENGTH['Embraer Legacy 550 (twin-jet)'] = 20.74 AIRCRAFT_LENGTH['Embraer Legacy 600/650 (twin-jet)'] = 26.33 AIRCRAFT_LENGTH['Embraer Phenom 300 (twin-jet)'] = 15.9 AIRCRAFT_LENGTH['Eurocopter EC-635 (twin-turboshaft)'] = 10.21 AIRCRAFT_LENGTH['Fairchild Dornier 328JET (twin-jet)'] = 21.11 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream 3 (twin-jet)'] = 25.32 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G450 (twin-jet)'] = 27.23 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G550 (twin-jet)'] = 29.39 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream G650 (twin-jet)'] = 30.41 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream IV (twin-jet)'] = 26.92 AIRCRAFT_LENGTH['Gulfstream Aerospace Gulfstream V (twin-jet)'] = 29.4 AIRCRAFT_LENGTH['Hawker Beechcraft 4000 (twin-jet)'] = 21.08 AIRCRAFT_LENGTH['Honda HondaJet (twin-jet)'] = 12.99 AIRCRAFT_LENGTH['IAI Gulfstream G100 (twin-jet)'] = 16.94 AIRCRAFT_LENGTH['IAI Gulfstream G150 (twin-jet)'] = 16.94 AIRCRAFT_LENGTH['IAI Gulfstream G200 (twin-jet)'] = 18.97 AIRCRAFT_LENGTH['IAI Gulfstream G280 (twin-jet)'] = 20.3 AIRCRAFT_LENGTH['Learjet 31 (twin-jet)'] = 14.83 AIRCRAFT_LENGTH['Learjet 35 (twin-jet)'] = 14.83 <----SKIPPED LINES----> Args: filename: string of the filename to open, potentially also including the full path. log_exception: boolean indicating whether to log an exception if file not found. Returns: Return text string of file contents. """ try: with open(filename, 'r') as content_file: file_contents = content_file.read() except IOError: if log_exception: Log('Unable to read '+filename) return '' return file_contents # because reading is ~25x more expensive than getmtime, we will only read & # parse if the getmtime is more recent than last call for this file. So this # dict stores a 2-tuple, the last time read & the resulting parsed return # value CACHED_FILES = {} def ReadAndParseSettings(filename): """Reads filename and parses the resulting key-value pairs into a dict.""" global CACHED_FILES (last_read_time, settings) = CACHED_FILES.get(filename, (0, {})) if os.path.exists(filename): last_modified = os.path.getmtime(filename) if last_modified > last_read_time: setting_str = ReadFile(filename) settings = ParseSettings(setting_str) CACHED_FILES[filename] = (last_modified, settings) return settings # File does not - or at least no longer - exists; so remove the cache if filename in CACHED_FILES: CACHED_FILES.pop(filename) return {} <----SKIPPED LINES----> whether the current active json changed from the prior one. Returns: Boolean - True if different (and processing needed), False if identical """ if SIMULATION_COUNTER == 0: return True (this_json, unused_now) = DUMP_JSONS[SIMULATION_COUNTER] (last_json, unused_now) = DUMP_JSONS[SIMULATION_COUNTER - 1] return this_json != last_json def CheckRebootNeeded( startup_time, message_queue, json_desc_dict, configuration): """Reboot based on duration instance has been running. Reboot needed in one of the following situations: - All quiet: if running for over 24 hours and all is quiet (message queue empty, no planes in radio, and backup not currently in process). - Mostly quiet: if running for over 36 hours and message queue is empty and it's 4a. - Reboot requested via html form. Also checks if reset requested via html form. """ reboot = False global SHUTDOWN_SIGNAL running_hours = (time.time() - startup_time) / SECONDS_IN_HOUR restart_days = configuration.get('restart_days', 1) min_hours = restart_days * HOURS_IN_DAY if ( running_hours >= min_hours and not message_queue and not json_desc_dict.get('radio_range_flights') and # script /home/pi/splitflap/backup.sh creates temp file in this # directory; after it is copied to the NAS, it is deleted not os.listdir('/media/backup')): msg = ('All quiet reboot triggered based on %d days (%d hours); ' 'actual runtime: %.2f hours' % (restart_days, min_hours, running_hours)) SHUTDOWN_SIGNAL = msg Log(msg) reboot = True # Wait another half day restart_days += 0.5 min_hours = restart_days * HOURS_IN_DAY if ( running_hours > min_hours and not message_queue and int(EpochDisplayTime(time.time(), '%-H')) >= 4): msg = ('Early morning reboot triggered based on %.1f (%d hours); ' 'actual runtime: %.2f hours' % (restart_days, min_hours, running_hours)) SHUTDOWN_SIGNAL = msg Log(msg) reboot = True if 'soft_reboot' in configuration: msg = 'Soft reboot requested via web form' SHUTDOWN_SIGNAL = msg Log(msg) reboot = True RemoveSetting(configuration, 'soft_reboot') if 'end_process' in configuration: msg = 'Process end requested via web form' SHUTDOWN_SIGNAL = msg Log(msg) RemoveSetting(configuration, 'end_process') return reboot <----SKIPPED LINES----> # We repeat the loop every x seconds; this ensures that if the processing # time is long, we don't wait another x seconds after processing completes next_loop_time = time.time() + LOOP_DELAY_SECONDS # These files are read only if the version on disk has been modified more # recently than the last time it was read last_dump_json_timestamp = 0 init_timing.append((time.time(), 7)) WaitUntilKillComplete(already_running_ids) init_timing.append((time.time(), 8)) personal_message = None # Unknown what personal message is displayed temp_last_logged = 0 # Keeps track of when temperature was last logged LogTimes(init_timing) reboot = False iteration = 0 # counter that tracks how many times thru while loop if initial_memory_dump: DumpMemorySnapsnot( configuration, iteration, startup_time, initial_frame_count) Log('Finishing initialization of %d; starting radio polling loop' % os.getpid()) while ((not SIMULATION or SIMULATION_COUNTER < len(DUMP_JSONS)) and not SHUTDOWN_SIGNAL): last_heartbeat_time = Heartbeat(last_heartbeat_time) new_configuration = ReadAndParseSettings(CONFIG_FILE) UpdateRollingLogSize(new_configuration) CheckForNewFilterCriteria( configuration, new_configuration, message_queue, flights) configuration = new_configuration ResetLogs(configuration) # clear the logs if requested UpdateRollingLogSize(configuration) # if this is a SIMULATION, then process every diff dump. But if it # isn't a simulation, then only read & do related processing for the # next dump if the last-modified timestamp indicates the file has been <----SKIPPED LINES----> insight_messages = CreateFlightInsights( flights, configuration.get('insights'), insight_message_distribution) if configuration.get('next_flight', 'off') == 'on': next_flight_text = FlightInsightNextFlight(flights, configuration) if next_flight_text: insight_messages.insert(0, next_flight_text) insight_messages = [(FLAG_MSG_INSIGHT, m) for m in insight_messages] for insight_message in insight_messages: message_queue.insert(0, insight_message) else: # flight didn't meet display criteria flight['insight_types'] = [] PickleObjectToFile( flight, PICKLE_FLIGHTS, True, timestamp=flight['now']) else: remote, servo = RefreshArduinos( remote, servo, to_remote_q, to_servo_q, to_main_q, shutdown, flights, json_desc_dict, configuration, screen_history) message_queue, next_message_time = ProcessArduinoCommmands( to_main_q, flights, configuration, message_queue, next_message_time) personal_message = PersonalMessage( configuration, message_queue, personal_message) # MEMORY MANAGEMENT # now that we've saved the flight, we have no more need to keep the # memory-hogging persistent_path key of that flight in live memory if 'persistent_path' in flights[-1]: del flights[-1]['persistent_path'] # it turns out we only need the last screen in the screen history, not # the entire history, so we can purge all the rest from active memory # to eliminate a slow-growing memory hog screen_history = [screen_history[-1]] # we also do not need more than MAX_INSIGHT_HORIZON_DAYS of history # of the flights, so we can purge flights older than that as the flights # list slowly grows over time. we can search the entire list every time # but that's unnecessary; instead we can just pop off the 0-th element # each time through the list if it's more than 1 + max days in the past. # Why + 1? Because the histogram generation expects that many *full* days # of history, so to make sure we don't have a partial day if we were to # generate the monthly histograms mid-day, we will keep an extra day. if time.time() - flights[0]['now'] > SECONDS_IN_DAY * ( MAX_INSIGHT_HORIZON_DAYS + 1): flights.pop(0) if SIMULATION: if now: simulated_hour = EpochDisplayTime(now, '%Y-%m-%d %H:00%z') if simulated_hour != prev_simulated_hour: print(simulated_hour) prev_simulated_hour = simulated_hour histogram = ReadAndParseSettings(HISTOGRAM_CONFIG_FILE) RemoveFile(HISTOGRAM_CONFIG_FILE) # We also need to make sure there are flights on which to generate a # histogram! Why might there not be any flights? Primarily during a # simulation, if there's a lingering histogram file at the time of # history restart. if histogram and not flights: Log('Histogram requested (%s) but no flights in memory' % histogram) if histogram and flights: message_queue.extend(TriggerHistograms(flights, histogram)) if message_queue: # Any personal message displayed has been cleared <----SKIPPED LINES----> message_queue, next_message_time, configuration, screen_history) reboot = CheckRebootNeeded( startup_time, message_queue, json_desc_dict, configuration) temp_last_logged = CheckTemperature(configuration, temp_last_logged) 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) # now that we've completed the loop, lets potentially dump the # memory snapshot iteration += 1 # this completes the iteration-th time thru the loop if initial_memory_dump: DumpMemorySnapsnot( configuration, iteration, startup_time, initial_frame_count) 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( <----SKIPPED LINES----> |