01234567890123456789012345678901234567890123456789012345678901234567890123456789
949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 4426442744284429443044314432443344344435443644374438443944404441444244434444444544464447 44484449445044514452445344544455445644574458445944604461446244634464446544664467 475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776 4777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804 | <----SKIPPED LINES----> SPLIT_SIMULATION_FLIGHT_PICKLE = False # Status data about messageboard - is it running, etc. Specifically, has tuples # of data (timestamp, system_id, status), where system_id is either the pin id of GPIO, # or a 0 to indicate overall system, and status is boolean PICKLE_DASHBOARD = 'pickle/dashboard.pk' CACHED_ELEMENT_PREFIX = 'cached_' # This web-exposed file is used for non-error messages that might highlight data or # code logic to check into. It is only cleared out manually. LOGFILE = 'log.txt' # Identical to the LOGFILE, except it includes just the most recent n lines. Newest # lines are at the end. ROLLING_LOGFILE = 'rolling_log.txt' #file for error messages ROLLING_LOG_SIZE = 1000 # default number of lines which may be overridden by settings file # Users can trigger .png histograms analogous to the text ones from the web interface; # this is the folder (within WEBSERVER_PATH) where those files are placed WEBSERVER_IMAGE_FOLDER = 'images/' # Multiple histograms can be generated, i.e. for airline, aircraft, day of week, etc. # The output files are named by the prefix & suffix, i.e.: prefix + type + . + suffix, # as in histogram_aircraft.png. These names match up to the names expected by the html # page that displays the images. Also, note that the suffix is interpreted by matplotlib # to identify the image format to create. HISTOGRAM_IMAGE_PREFIX = 'histogram_' HISTOGRAM_IMAGE_SUFFIX = 'png' HISTOGRAM_IMAGE_HTML = 'histograms.html' # This file indicates a pending request for histograms - either png, text-based, or # both; once it is processed, this file is deleted. The contents are concatenated key-value # pairs, histogram=all;histogram_history=24h; etc. HISTOGRAM_CONFIG_FILE = 'secure/histogram.txt' HISTOGRAM_BOOLEANS = ('histogram_data_summary') # This contains concatenated key-value configuration attributes in a similar format # to the HISTOGRAM_CONFIG_FILE that are exposed to the user via the web interface or, # for a subset of them, through the Arduino interface. They are polled at every iteration # so that the most current value is always leveraged by the running software. CONFIG_FILE = 'secure/settings.txt' CONFIG_BOOLEANS = ('setting_screen_enabled', 'next_flight', 'reset_logs', 'log_jsons') <----SKIPPED LINES----> #if running on raspberry, then need to prepend path to file names if RASPBERRY_PI: PICKLE_FLIGHTS = MESSAGEBOARD_PATH + PICKLE_FLIGHTS PICKLE_DASHBOARD = MESSAGEBOARD_PATH + PICKLE_DASHBOARD LOGFILE = MESSAGEBOARD_PATH + LOGFILE PICKLE_DUMP_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_DUMP_JSON_FILE PICKLE_FA_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_FA_JSON_FILE CODE_REPOSITORY = MESSAGEBOARD_PATH HISTOGRAM_CONFIG_FILE = WEBSERVER_PATH + HISTOGRAM_CONFIG_FILE CONFIG_FILE = WEBSERVER_PATH + CONFIG_FILE ROLLING_MESSAGE_FILE = WEBSERVER_PATH + ROLLING_MESSAGE_FILE ALL_MESSAGE_FILE = WEBSERVER_PATH + ALL_MESSAGE_FILE ROLLING_LOGFILE = WEBSERVER_PATH + ROLLING_LOGFILE STDERR_FILE = WEBSERVER_PATH + STDERR_FILE BACKUP_FILE = WEBSERVER_PATH + BACKUP_FILE SERVICE_VERIFICATION_FILE = WEBSERVER_PATH + SERVICE_VERIFICATION_FILE UPTIMES_FILE = WEBSERVER_PATH + UPTIMES_FILE WEBSERVER_IMAGE_FOLDER = WEBSERVER_PATH + WEBSERVER_IMAGE_FOLDER HISTOGRAM_IMAGE_HTML = WEBSERVER_PATH + HISTOGRAM_IMAGE_HTML HOURLY_IMAGE_FILE = WEBSERVER_IMAGE_FOLDER + HOURLY_IMAGE_FILE VERSION_REPOSITORY = WEBSERVER_PATH + VERSION_REPOSITORY TIMEZONE = 'US/Pacific' # timezone of display TZ = pytz.timezone(TIMEZONE) KNOWN_AIRPORTS = ('SJC', 'SFO', 'OAK') # iata codes that we don't need to expand SPLITFLAP_CHARS_PER_LINE = 22 SPLITFLAP_LINE_COUNT = 6 DIRECTIONS_4 = ['N', 'E', 'S', 'W'] DIRECTIONS_8 = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'] DIRECTIONS_16 = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] HOURS = ['12a', ' 1a', ' 2a', ' 3a', ' 4a', ' 5a', ' 6a', ' 7a', ' 8a', ' 9a', '10a', '11a', '12p', ' 1p', ' 2p', ' 3p', ' 4p', ' 5p', ' 6p', ' 7p', ' 8p', ' 9p', '10p', '11p'] <----SKIPPED LINES----> this_histogram = which_histograms if this_histogram == 'all': this_histogram = histogram['generate'] (key, sort, title, hours) = HistogramSettingsKeySortTitle( this_histogram, hours, flights) # if multiple histograms are getting generated, this might take a few seconds; # logging a heartbeat with each histogram ensures that monitoring.py does not # mistake this pause for a hang. if heartbeat: Heartbeat() CreateSingleHistogramChart( flights, key, sort, title, truncate=histogram.get('truncate', TRUNCATE), hours=hours, exhaustive=histogram.get('exhaustive', False)) filename = filename_prefix + histogram['generate'] + '.' + filename_suffix filepath = WEBSERVER_IMAGE_FOLDER + filename matplotlib.pyplot.savefig(filepath) matplotlib.pyplot.close() histograms_generated.append((histogram['generate'], filename)) return histograms_generated def MessageboardHistograms( flights, which_histograms, how_much_history, max_screens, data_summary): """Generates multiple split flap screen histograms. Args: flights: the iterable of the raw data from which the histogram will be generated; each element of the iterable is a dictionary, that contains at least the key 'now', and depending on other parameters, also potentially 'min_feet' amongst others. <----SKIPPED LINES----> generated_histograms = ImageHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string) html_lines = ReadFile(HISTOGRAM_IMAGE_HTML).split('\n') replaced_images = [] for identifier, new_filename in generated_histograms: # for each histogram, find the html_line with the matching id # Example line: <img id="destination" src="images/histogram_destination.png"><p> identifier = '"%s"' % identifier # add quotations to make sure its complete n, line = None, None # addresses pylint complaint found = False for n, line in enumerate(html_lines): if identifier in line: found = True break found = False if found: start_char = line.find(WEBSERVER_IMAGE_FOLDER) + len(WEBSERVER_IMAGE_FOLDER) end_character = ( line.find(HISTOGRAM_IMAGE_SUFFIX, start_char) + len(HISTOGRAM_IMAGE_SUFFIX)) old_filename = line[start_char:end_character] line = line.replace(old_filename, new_filename) html_lines[n] = line replaced_images.append(line[start_char:end_character]) new_html = '\n'.join(html_lines) WriteFile(HISTOGRAM_IMAGE_HTML, new_html) # Remove those obsoleted files for f in old_filename: RemoveFile(f) return histogram_messages def SaveFlightsByAltitudeDistanceCSV( flights, max_days=0, filename='flights_by_alt_dist.csv', precision=100): """Extracts hourly histogram into text file for a variety of altitudes and distances. Generates a csv with 26 columns: - col#1: altitude (in feet) - col#2: distance (in feet) - cols#3-26: hour of the day The first row is a header row; subsequent rows list the number of flights that have occurred in the last max_days with an altitude and min distance less than that identified in the first two columns. Each row increments elevation or altitude by precision feet, <----SKIPPED LINES----> |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 239240241242243244245246247248249250251252253254255256257258 259260261262263264265266267268269270271272273274275276277278279280 442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472 47584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810 | <----SKIPPED LINES----> SPLIT_SIMULATION_FLIGHT_PICKLE = False # Status data about messageboard - is it running, etc. Specifically, has tuples # of data (timestamp, system_id, status), where system_id is either the pin id of GPIO, # or a 0 to indicate overall system, and status is boolean PICKLE_DASHBOARD = 'pickle/dashboard.pk' CACHED_ELEMENT_PREFIX = 'cached_' # This web-exposed file is used for non-error messages that might highlight data or # code logic to check into. It is only cleared out manually. LOGFILE = 'log.txt' # Identical to the LOGFILE, except it includes just the most recent n lines. Newest # lines are at the end. ROLLING_LOGFILE = 'rolling_log.txt' #file for error messages ROLLING_LOG_SIZE = 1000 # default number of lines which may be overridden by settings file # Users can trigger .png histograms analogous to the text ones from the web interface; # this is the folder (within WEBSERVER_PATH) where those files are placed WEBSERVER_IMAGE_RELATIVE_FOLDER = 'images/' # Multiple histograms can be generated, i.e. for airline, aircraft, day of week, etc. # The output files are named by the prefix & suffix, i.e.: prefix + type + . + suffix, # as in histogram_aircraft.png. These names match up to the names expected by the html # page that displays the images. Also, note that the suffix is interpreted by matplotlib # to identify the image format to create. HISTOGRAM_IMAGE_PREFIX = 'histogram_' HISTOGRAM_IMAGE_SUFFIX = 'png' HISTOGRAM_IMAGE_HTML = 'histograms.html' # This file indicates a pending request for histograms - either png, text-based, or # both; once it is processed, this file is deleted. The contents are concatenated key-value # pairs, histogram=all;histogram_history=24h; etc. HISTOGRAM_CONFIG_FILE = 'secure/histogram.txt' HISTOGRAM_BOOLEANS = ('histogram_data_summary') # This contains concatenated key-value configuration attributes in a similar format # to the HISTOGRAM_CONFIG_FILE that are exposed to the user via the web interface or, # for a subset of them, through the Arduino interface. They are polled at every iteration # so that the most current value is always leveraged by the running software. CONFIG_FILE = 'secure/settings.txt' CONFIG_BOOLEANS = ('setting_screen_enabled', 'next_flight', 'reset_logs', 'log_jsons') <----SKIPPED LINES----> #if running on raspberry, then need to prepend path to file names if RASPBERRY_PI: PICKLE_FLIGHTS = MESSAGEBOARD_PATH + PICKLE_FLIGHTS PICKLE_DASHBOARD = MESSAGEBOARD_PATH + PICKLE_DASHBOARD LOGFILE = MESSAGEBOARD_PATH + LOGFILE PICKLE_DUMP_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_DUMP_JSON_FILE PICKLE_FA_JSON_FILE = MESSAGEBOARD_PATH + PICKLE_FA_JSON_FILE CODE_REPOSITORY = MESSAGEBOARD_PATH HISTOGRAM_CONFIG_FILE = WEBSERVER_PATH + HISTOGRAM_CONFIG_FILE CONFIG_FILE = WEBSERVER_PATH + CONFIG_FILE ROLLING_MESSAGE_FILE = WEBSERVER_PATH + ROLLING_MESSAGE_FILE ALL_MESSAGE_FILE = WEBSERVER_PATH + ALL_MESSAGE_FILE ROLLING_LOGFILE = WEBSERVER_PATH + ROLLING_LOGFILE STDERR_FILE = WEBSERVER_PATH + STDERR_FILE BACKUP_FILE = WEBSERVER_PATH + BACKUP_FILE SERVICE_VERIFICATION_FILE = WEBSERVER_PATH + SERVICE_VERIFICATION_FILE UPTIMES_FILE = WEBSERVER_PATH + UPTIMES_FILE HISTOGRAM_IMAGE_HTML = WEBSERVER_PATH + HISTOGRAM_IMAGE_HTML HOURLY_IMAGE_FILE = WEBSERVER_PATH + WEBSERVER_IMAGE_RELATIVE_FOLDER + HOURLY_IMAGE_FILE VERSION_REPOSITORY = WEBSERVER_PATH + VERSION_REPOSITORY TIMEZONE = 'US/Pacific' # timezone of display TZ = pytz.timezone(TIMEZONE) KNOWN_AIRPORTS = ('SJC', 'SFO', 'OAK') # iata codes that we don't need to expand SPLITFLAP_CHARS_PER_LINE = 22 SPLITFLAP_LINE_COUNT = 6 DIRECTIONS_4 = ['N', 'E', 'S', 'W'] DIRECTIONS_8 = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'] DIRECTIONS_16 = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'] HOURS = ['12a', ' 1a', ' 2a', ' 3a', ' 4a', ' 5a', ' 6a', ' 7a', ' 8a', ' 9a', '10a', '11a', '12p', ' 1p', ' 2p', ' 3p', ' 4p', ' 5p', ' 6p', ' 7p', ' 8p', ' 9p', '10p', '11p'] <----SKIPPED LINES----> this_histogram = which_histograms if this_histogram == 'all': this_histogram = histogram['generate'] (key, sort, title, hours) = HistogramSettingsKeySortTitle( this_histogram, hours, flights) # if multiple histograms are getting generated, this might take a few seconds; # logging a heartbeat with each histogram ensures that monitoring.py does not # mistake this pause for a hang. if heartbeat: Heartbeat() CreateSingleHistogramChart( flights, key, sort, title, truncate=histogram.get('truncate', TRUNCATE), hours=hours, exhaustive=histogram.get('exhaustive', False)) filename = ( WEBSERVER_IMAGE_RELATIVE_FOLDER + # i.e.: images/ filename_prefix + # i.e.: histogram_ histogram['generate'] + # i.e.: destination '.' + filename_suffix) # i.e.: .png filepath = WEBSERVER_PATH + filename # i.e.: /var/www/html/ + filename matplotlib.pyplot.savefig(filepath) matplotlib.pyplot.close() histograms_generated.append((histogram['generate'], filename)) return histograms_generated def MessageboardHistograms( flights, which_histograms, how_much_history, max_screens, data_summary): """Generates multiple split flap screen histograms. Args: flights: the iterable of the raw data from which the histogram will be generated; each element of the iterable is a dictionary, that contains at least the key 'now', and depending on other parameters, also potentially 'min_feet' amongst others. <----SKIPPED LINES----> generated_histograms = ImageHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string) html_lines = ReadFile(HISTOGRAM_IMAGE_HTML).split('\n') replaced_images = [] for identifier, new_filename in generated_histograms: # for each histogram, find the html_line with the matching id # Example line: <img id="destination" src="images/histogram_destination.png"><p> identifier = '"%s"' % identifier # add quotations to make sure its complete n, line = None, None # addresses pylint complaint found = False for n, line in enumerate(html_lines): if identifier in line: found = True break found = False if found: start_char = line.find(WEBSERVER_IMAGE_RELATIVE_FOLDER) end_character = ( line.find(HISTOGRAM_IMAGE_SUFFIX, start_char) + len(HISTOGRAM_IMAGE_SUFFIX)) old_filename = line[start_char:end_character] print(old_filename, new_filename) line = line.replace(old_filename, new_filename) html_lines[n] = line replaced_images.append(line[start_char:end_character]) new_html = '\n'.join(html_lines) WriteFile(HISTOGRAM_IMAGE_HTML, new_html) # Remove those obsoleted files for f in replaced_images: RemoveFile(f) return histogram_messages def SaveFlightsByAltitudeDistanceCSV( flights, max_days=0, filename='flights_by_alt_dist.csv', precision=100): """Extracts hourly histogram into text file for a variety of altitudes and distances. Generates a csv with 26 columns: - col#1: altitude (in feet) - col#2: distance (in feet) - cols#3-26: hour of the day The first row is a header row; subsequent rows list the number of flights that have occurred in the last max_days with an altitude and min distance less than that identified in the first two columns. Each row increments elevation or altitude by precision feet, <----SKIPPED LINES----> |