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()
|