01234567890123456789012345678901234567890123456789012345678901234567890123456789
55035504550555065507550855095510551155125513551455155516551755185519552055215522 5523552455255526552755285529553055315532553355345535553655375538 553955405541554255435544554555465547 554855495550555155525553 5554 555555565557555855595560 5561556255635564556555665567 556855695570557155725573557455755576557755785579558055815582558355845585558655875588 558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612 5613 56145615561656175618561956205621562256235624562556265627562856295630563156325633 |
<----SKIPPED LINES---->
global VERSION_ARDUINO
def MakeCopy(python_prefix):
file_extension = '.py'
live_name = python_prefix + '.py'
live_path = os.path.join(CODE_REPOSITORY, live_name)
epoch = os.path.getmtime(live_path)
last_modified_suffix = EpochDisplayTime(epoch, format_string='-%Y-%m-%d-%H%M')
version_name = python_prefix + last_modified_suffix + file_extension
version_path = os.path.join(VERSION_REPOSITORY, version_name)
shutil.copyfile(live_path, version_path)
return version_name
VERSION_MESSAGEBOARD = MakeCopy('messageboard')
VERSION_ARDUINO = MakeCopy('arduino')
def main():
"""Traffic cop between incoming radio flight messages, configuration, and messageboard.
This is the main logic, checking for new flights, augmenting the radio signal with
additional web-scraped data, and generating messages in a form presentable to the
messageboard.
"""
RemoveFile(LOGFILE_LOCK)
VersionControl()
# Since this clears log files, it should occur first before we start logging
if '-s' in sys.argv:
global SIMULATION_COUNTER
SimulationSetup()
last_heartbeat_time = HeartbeatRestart()
# This flag slows down simulation time around a flight, great for debugging the arduinos
simulation_slowdown = bool('-f' in sys.argv)
# Redirect any errors to a log file instead of the screen, and add a datestamp
if not SIMULATION:
sys.stderr = open(STDERR_FILE, 'a')
Log('', STDERR_FILE)
Log('Starting up process %d' % os.getpid())
already_running_ids = FindRunningParents()
if already_running_ids:
for pid in already_running_ids:
Log('Sending termination signal to %d' % pid)
os.kill(pid, signal.SIGTERM)
SetPinMode()
configuration = ReadAndParseSettings(CONFIG_FILE)
startup_time = time.time()
json_desc_dict = {}
flights = UnpickleObjectFromFile(PICKLE_FLIGHTS, True, max_days=MAX_INSIGHT_HORIZON_DAYS)
# Clear the loaded flight of any cached data, identified by keys with a specific
# suffix, since code fixes may change the values for some of those cached elements
for flight in flights:
for key in list(flight.keys()):
if key.endswith(CACHED_ELEMENT_PREFIX):
flight.pop(key)
# If we're displaying just a single insight message, we want it to be something
# unique, to the extent possible; this dict holds a count of the diff types of messages
# displayed so far
insight_message_distribution = {}
# bootstrap the flight insights distribution from a list of insights on each
# flight (i.e.: flight['insight_types'] for a given flight might look like
# [1, 2, 7, 9], or [], to indicate which insights were identified; this then
# transforms that into {0: 25, 1: 18, ...} summing across all flights.
missing_insights = []
for flight in flights:
if 'insight_types' not in flight:
missing_insights.append(
'%s on %s' % (DisplayFlightNumber(flight), DisplayTime(flight, '%x %X')))
distribution = flight.get('insight_types', [])
for key in distribution:
insight_message_distribution[key] = (
insight_message_distribution.get(key, 0) + 1)
if missing_insights:
Log('Flights missing insight distributions: %s' % ';'.join(missing_insights))
remote, servo, to_remote_q, to_servo_q, to_main_q, shutdown = InitArduinos(configuration)
# used in simulation to print the hour of simulation once per simulated hour
prev_simulated_hour = ''
persistent_nearby_aircraft = {} # key = flight number; value = last seen epoch
persistent_path = {}
histogram = {}
# Next up to print is index 0; this is a list of tuples:
# tuple element#1: flag indicating the type of message that this is
# tuple element#2: the message itself
message_queue = []
next_message_time = time.time()
# 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
WaitUntilKillComplete(already_running_ids)
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)
CheckForNewFilterCriteria(configuration, new_configuration, message_queue, flights)
configuration = new_configuration
ResetLogs(configuration) # clear the logs if requested
# 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 updated since it was last read.
tmp_timestamp = 0
if not SIMULATION:
dump_json_exists = os.path.exists(DUMP_JSON_FILE)
if dump_json_exists:
tmp_timestamp = os.path.getmtime(DUMP_JSON_FILE)
<----SKIPPED LINES---->
|
01234567890123456789012345678901234567890123456789012345678901234567890123456789
55035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651 |
<----SKIPPED LINES---->
global VERSION_ARDUINO
def MakeCopy(python_prefix):
file_extension = '.py'
live_name = python_prefix + '.py'
live_path = os.path.join(CODE_REPOSITORY, live_name)
epoch = os.path.getmtime(live_path)
last_modified_suffix = EpochDisplayTime(epoch, format_string='-%Y-%m-%d-%H%M')
version_name = python_prefix + last_modified_suffix + file_extension
version_path = os.path.join(VERSION_REPOSITORY, version_name)
shutil.copyfile(live_path, version_path)
return version_name
VERSION_MESSAGEBOARD = MakeCopy('messageboard')
VERSION_ARDUINO = MakeCopy('arduino')
def LogInitTimes(init_times):
msg = ''
for n, t in enumerate(init_times[:-1]):
msg += '%.2fs to get from reading %d to reading %s' % (t[n + 1] - t[n], n, n + 1)
Log(msg)
def main():
"""Traffic cop between incoming radio flight messages, configuration, and messageboard.
This is the main logic, checking for new flights, augmenting the radio signal with
additional web-scraped data, and generating messages in a form presentable to the
messageboard.
"""
RemoveFile(LOGFILE_LOCK)
VersionControl()
# Since this clears log files, it should occur first before we start logging
if '-s' in sys.argv:
global SIMULATION_COUNTER
SimulationSetup()
last_heartbeat_time = HeartbeatRestart()
init_timing = [time.time()] # time 0
# This flag slows down simulation time around a flight, great for debugging the arduinos
simulation_slowdown = bool('-f' in sys.argv)
# Redirect any errors to a log file instead of the screen, and add a datestamp
if not SIMULATION:
sys.stderr = open(STDERR_FILE, 'a')
Log('', STDERR_FILE)
init_timing.append(time.time()) # time 1
Log('Starting up process %d' % os.getpid())
already_running_ids = FindRunningParents()
if already_running_ids:
for pid in already_running_ids:
Log('Sending termination signal to %d' % pid)
os.kill(pid, signal.SIGTERM)
init_timing.append(time.time()) # time 2
SetPinMode()
configuration = ReadAndParseSettings(CONFIG_FILE)
startup_time = time.time()
json_desc_dict = {}
init_timing.append(time.time()) # time 3
flights = UnpickleObjectFromFile(PICKLE_FLIGHTS, True, max_days=MAX_INSIGHT_HORIZON_DAYS)
# Clear the loaded flight of any cached data, identified by keys with a specific
# suffix, since code fixes may change the values for some of those cached elements
for flight in flights:
for key in list(flight.keys()):
if key.endswith(CACHED_ELEMENT_PREFIX):
flight.pop(key)
init_timing.append(time.time()) # time 4
# If we're displaying just a single insight message, we want it to be something
# unique, to the extent possible; this dict holds a count of the diff types of messages
# displayed so far
insight_message_distribution = {}
# bootstrap the flight insights distribution from a list of insights on each
# flight (i.e.: flight['insight_types'] for a given flight might look like
# [1, 2, 7, 9], or [], to indicate which insights were identified; this then
# transforms that into {0: 25, 1: 18, ...} summing across all flights.
missing_insights = []
for flight in flights:
if 'insight_types' not in flight:
missing_insights.append(
'%s on %s' % (DisplayFlightNumber(flight), DisplayTime(flight, '%x %X')))
distribution = flight.get('insight_types', [])
for key in distribution:
insight_message_distribution[key] = (
insight_message_distribution.get(key, 0) + 1)
if missing_insights:
Log('Flights missing insight distributions: %s' % ';'.join(missing_insights))
init_timing.append(time.time()) # time 5
remote, servo, to_remote_q, to_servo_q, to_main_q, shutdown = InitArduinos(configuration)
# used in simulation to print the hour of simulation once per simulated hour
prev_simulated_hour = ''
persistent_nearby_aircraft = {} # key = flight number; value = last seen epoch
persistent_path = {}
histogram = {}
# Next up to print is index 0; this is a list of tuples:
# tuple element#1: flag indicating the type of message that this is
# tuple element#2: the message itself
message_queue = []
next_message_time = time.time()
# 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()) # time 6
WaitUntilKillComplete(already_running_ids)
init_timing.append(time.time()) # time 7
LogInitTimes(init_timing)
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)
CheckForNewFilterCriteria(configuration, new_configuration, message_queue, flights)
configuration = new_configuration
ResetLogs(configuration) # clear the logs if requested
# 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 updated since it was last read.
tmp_timestamp = 0
if not SIMULATION:
dump_json_exists = os.path.exists(DUMP_JSON_FILE)
if dump_json_exists:
tmp_timestamp = os.path.getmtime(DUMP_JSON_FILE)
<----SKIPPED LINES---->
|