01234567890123456789012345678901234567890123456789012345678901234567890123456789
10191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059 539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454 60136014601560166017601860196020602160226023602460256026602760286029603060316032 60336034603560366037603860396040604160426043604460456046604760486049605060516052 |
<----SKIPPED LINES---->
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 given filename and then 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) # TODO - uncomment?
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 {}
def BuildSettings(d):
"""Converts a dict to a string of form key1=value1;...;keyn=valuen; keys alpha sorted."""
kv_pairs = []
for key in sorted(list(d.keys())):
kv_pairs.append('%s=%s' % (key, d[key]))
s = ';'.join(kv_pairs)
if s: # add terminating semicolon
s += ';'
return s
<----SKIPPED LINES---->
configuration: dictionary of settings
message_queue: current message queue
next_message_time: epoch of the next message to display to screen
Returns:
A 2-tuple of the (possibly-updated) message_queue and next_message_time.
"""
while not q.empty():
command, args = q.get()
if command == 'pin':
UpdateStatusLight(*args)
elif command == 'replay':
# a command might request info about flight to be (re)displayed, irrespective of
# whether the screen is on; if so, let's put that message at the front of the message
# queue, and delete any subsequent messages in queue because presumably the button
# was pushed either a) when the screen was off (so no messages in queue), or b)
# because the screen was on, but the last flight details got lost after other screens
# that we're no longer interested in
Log('Replay requested') #TODO - remove
messageboard_flight_index = IdentifyFlightDisplayed(
flights, configuration, display_all_hours=True)
if messageboard_flight_index is not None:
message_queue = [m for m in message_queue if m[0] != FLAG_MSG_INSIGHT]
flight_message = CreateMessageAboutFlight(flights[messageboard_flight_index])
message_queue = [(FLAG_MSG_FLIGHT, flight_message)]
next_message_time = time.time()
elif command == 'histogram':
if not flights:
Log('Histogram requested by remote %s but no flights in memory' % str(args))
else:
histogram_type, histogram_history = args
message_queue.extend(MessageboardHistograms(
flights,
histogram_type,
histogram_history,
'_1',
False))
elif command == 'update_configuration':
Log('Writing CONFIG_FILE: %s' % str(args)) #TODO - remove
WriteFile(CONFIG_FILE, *args)
else:
Log('Improper command from arduinos: %s / %s' % (command, args))
return message_queue, next_message_time
def PublishMessage(
s,
subscription_id='12fd73cd-75ef-4cae-bbbf-29b2678692c1',
key='c5f62d44-e30d-4c43-a43e-d4f65f4eb399',
secret='b00aeb24-72f3-467c-aad2-82ba5e5266ca',
timeout=3):
"""Publishes a text string to a Vestaboard.
The message is pushed to the vestaboard splitflap display by way of its web services;
see https://docs.vestaboard.com/introduction for more details.
Args:
<----SKIPPED LINES---->
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(), 6))
WaitUntilKillComplete(already_running_ids)
init_timing.append((time.time(), 7))
LogTimes(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)
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 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)
if (SIMULATION and DumpJsonChanges()) or (
not SIMULATION and dump_json_exists and tmp_timestamp > last_dump_json_timestamp):
last_dump_json_timestamp = tmp_timestamp
(persistent_nearby_aircraft,
flight, now,
<----SKIPPED LINES---->
|
01234567890123456789012345678901234567890123456789012345678901234567890123456789
10191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059 53925393539453955396539753985399540054015402540354045405540654075408540954105411 541254135414541554165417541854195420542154225423542454255426542754285429543054315432 54335434543554365437543854395440544154425443544454455446544754485449545054515452 60116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066 |
<----SKIPPED LINES---->
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 given filename and then 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 {}
def BuildSettings(d):
"""Converts a dict to a string of form key1=value1;...;keyn=valuen; keys alpha sorted."""
kv_pairs = []
for key in sorted(list(d.keys())):
kv_pairs.append('%s=%s' % (key, d[key]))
s = ';'.join(kv_pairs)
if s: # add terminating semicolon
s += ';'
return s
<----SKIPPED LINES---->
configuration: dictionary of settings
message_queue: current message queue
next_message_time: epoch of the next message to display to screen
Returns:
A 2-tuple of the (possibly-updated) message_queue and next_message_time.
"""
while not q.empty():
command, args = q.get()
if command == 'pin':
UpdateStatusLight(*args)
elif command == 'replay':
# a command might request info about flight to be (re)displayed, irrespective of
# whether the screen is on; if so, let's put that message at the front of the message
# queue, and delete any subsequent messages in queue because presumably the button
# was pushed either a) when the screen was off (so no messages in queue), or b)
# because the screen was on, but the last flight details got lost after other screens
# that we're no longer interested in
messageboard_flight_index = IdentifyFlightDisplayed(
flights, configuration, display_all_hours=True)
if messageboard_flight_index is not None:
message_queue = [m for m in message_queue if m[0] != FLAG_MSG_INSIGHT]
flight_message = CreateMessageAboutFlight(flights[messageboard_flight_index])
message_queue = [(FLAG_MSG_FLIGHT, flight_message)]
next_message_time = time.time()
elif command == 'histogram':
if not flights:
Log('Histogram requested by remote %s but no flights in memory' % str(args))
else:
histogram_type, histogram_history = args
message_queue.extend(MessageboardHistograms(
flights,
histogram_type,
histogram_history,
'_1',
False))
elif command == 'update_configuration':
WriteFile(CONFIG_FILE, *args)
else:
Log('Improper command from arduinos: %s / %s' % (command, args))
return message_queue, next_message_time
def PublishMessage(
s,
subscription_id='12fd73cd-75ef-4cae-bbbf-29b2678692c1',
key='c5f62d44-e30d-4c43-a43e-d4f65f4eb399',
secret='b00aeb24-72f3-467c-aad2-82ba5e5266ca',
timeout=3):
"""Publishes a text string to a Vestaboard.
The message is pushed to the vestaboard splitflap display by way of its web services;
see https://docs.vestaboard.com/introduction for more details.
Args:
<----SKIPPED LINES---->
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(), 6))
WaitUntilKillComplete(already_running_ids)
init_timing.append((time.time(), 7))
LogTimes(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)
UpdateRollingLogSize(new_configuration)
CheckForNewFilterCriteria(configuration, new_configuration, message_queue, flights)
if 'setting_screen_enabled' not in configuration and 'setting_screen_enabled' in new_configuration:
Log('setting_screen_enabled changed from NOT PRESENT to ON')
if 'setting_screen_enabled' in configuration and 'setting_screen_enabled' not in new_configuration:
Log('setting_screen_enabled changed from ON to NOT PRESENT')
last_configuration = configuration
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 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)
if (SIMULATION and DumpJsonChanges()) or (
not SIMULATION and dump_json_exists and tmp_timestamp > last_dump_json_timestamp):
last_dump_json_timestamp = tmp_timestamp
(persistent_nearby_aircraft,
flight, now,
<----SKIPPED LINES---->
|