01234567890123456789012345678901234567890123456789012345678901234567890123456789
6744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780 6781678267836784678567866787 67886789679067916792679367946795679667976798679968006801680268036804680568066807 68786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924 71227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162 | <----SKIPPED LINES----> else: msg = pin[2] if RASPBERRY_PI: RPi.GPIO.output(pin[0], value) if value: pin_setting = 'HIGH' relay_light_value = 'OFF' else: pin_setting = 'LOW' relay_light_value = 'ON' msg += '; RPi GPIO pin %d set to %s; relay light #%d should now be %s' % ( pin[0], pin_setting, pin[3], relay_light_value) if pin_values[pin[0]] != value: if VERBOSE: Log(msg) # log pin_values[pin[0]] = value # update cache UpdateDashboard(value, subsystem=pin, failure_message=failure_message) def UpdateDashboard(value, subsystem=0, failure_message=''): """Writes to disk a tuple with status details about a particular system. The independent monitoring.py module allows us to see in one place the status of all the subsystems and of the overall system; it does that monitoring based on these tuples of data. Args: value: Boolean indicating whether a failure has occurred (True) or system is nominal (False). subsystem: A tuple describing the system; though that description may have multiple attributes, the 0th element is the numeric identifier of that system. monitoring.py depends on other attributes of that tuple being present as well. Since the overall system does not have a tuple defined for it, it gets a default identifier of 0. failure_message: an (optional) message describing why the system / subsystem is being disabled or failing. """ versions = (VERSION_MESSAGEBOARD, VERSION_ARDUINO) if subsystem: subsystem = subsystem[0] PickleObjectToFile(( time.time(), subsystem, value, versions, failure_message, INSTANCE_START_TIME), PICKLE_DASHBOARD, True) def RemoveFile(file): """Removes a file, returning a boolean indicating if it had existed.""" if os.path.exists(file): try: os.remove(file) except PermissionError: return False return True return False def ConfirmNewFlight(flight, flights): """Replaces last-seen flight with new flight if identifiers overlap. Flights are identified by the radio over time by a tuple of identifiers: flight_number and squawk. Due to unknown communication issues, one or the <----SKIPPED LINES----> for file in files_to_overwrite: os.remove(file) for f in saved_flights: # we would like to use verify=True, but that's too slow without further # optimizing the verification step for a loop of data PickleObjectToFile( f, PICKLE_FLIGHTS, True, timestamp=f['now'], verify=False) return False def HeartbeatRestart(): """Logs system down / system up pair of heartbeats as system starts.""" if SIMULATION: return 0 UpdateDashboard(True) # Indicates that this wasn't running moment before, ... UpdateDashboard(False) # ... and now it is running! return time.time() def Heartbeat(last_heartbeat_time=None): """Logs a system up heartbeat.""" if SIMULATION: return last_heartbeat_time now = time.time() if not last_heartbeat_time or now - last_heartbeat_time > HEARTBEAT_SECONDS: UpdateDashboard(False) # Send an all-clear message last_heartbeat_time = now return last_heartbeat_time def VersionControl(): """Copies current instances of messageboard.py and arduino.py into repository. To aid debugging, we want to keep past versions of the code easily accessible, and linked to the errors that have been logged. This function copies the python code into a version control directory after adding in a date / time stamp to the file name. """ global VERSION_MESSAGEBOARD global VERSION_ARDUINO VERSION_MESSAGEBOARD = MakeVersionCopy('messageboard') VERSION_ARDUINO = MakeVersionCopy('arduino') def MakeVersionCopy(python_prefix): """Copies current instance of python file into repository.""" <----SKIPPED LINES----> 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 # 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 ( <----SKIPPED LINES----> |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
67446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811 68826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928 71267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166 | <----SKIPPED LINES----> else: msg = pin[2] if RASPBERRY_PI: RPi.GPIO.output(pin[0], value) if value: pin_setting = 'HIGH' relay_light_value = 'OFF' else: pin_setting = 'LOW' relay_light_value = 'ON' msg += '; RPi GPIO pin %d set to %s; relay light #%d should now be %s' % ( pin[0], pin_setting, pin[3], relay_light_value) if pin_values[pin[0]] != value: if VERBOSE: Log(msg) # log pin_values[pin[0]] = value # update cache UpdateDashboard(value, subsystem=pin, failure_message=failure_message) def UpdateDashboard(value, subsystem=0, failure_message='', iteration=None): """Writes to disk a tuple with status details about a particular system. The independent monitoring.py module allows us to see in one place the status of all the subsystems and of the overall system; it does that monitoring based on these tuples of data. Args: value: Boolean indicating whether a failure has occurred (True) or system is nominal (False). subsystem: A tuple describing the system; though that description may have multiple attributes, the 0th element is the numeric identifier of that system. monitoring.py depends on other attributes of that tuple being present as well. Since the overall system does not have a tuple defined for it, it gets a default identifier of 0. failure_message: an (optional) message describing why the system / subsystem is being disabled or failing. iteration: integer indicating how many times the main loop has been completed. """ versions = (VERSION_MESSAGEBOARD, VERSION_ARDUINO) if subsystem: subsystem = subsystem[0] PickleObjectToFile(( time.time(), subsystem, value, versions, failure_message, INSTANCE_START_TIME, iteration, gpiozero.CPUTemperature().temperature), PICKLE_DASHBOARD, True) def RemoveFile(file): """Removes a file, returning a boolean indicating if it had existed.""" if os.path.exists(file): try: os.remove(file) except PermissionError: return False return True return False def ConfirmNewFlight(flight, flights): """Replaces last-seen flight with new flight if identifiers overlap. Flights are identified by the radio over time by a tuple of identifiers: flight_number and squawk. Due to unknown communication issues, one or the <----SKIPPED LINES----> for file in files_to_overwrite: os.remove(file) for f in saved_flights: # we would like to use verify=True, but that's too slow without further # optimizing the verification step for a loop of data PickleObjectToFile( f, PICKLE_FLIGHTS, True, timestamp=f['now'], verify=False) return False def HeartbeatRestart(): """Logs system down / system up pair of heartbeats as system starts.""" if SIMULATION: return 0 UpdateDashboard(True) # Indicates that this wasn't running moment before, ... UpdateDashboard(False) # ... and now it is running! return time.time() def Heartbeat(last_heartbeat_time=None, iteration=None): """Logs a system up heartbeat.""" if SIMULATION: return last_heartbeat_time now = time.time() if not last_heartbeat_time or now - last_heartbeat_time > HEARTBEAT_SECONDS: UpdateDashboard(False, iteration=iteration) # Send an all-clear message last_heartbeat_time = now return last_heartbeat_time def VersionControl(): """Copies current instances of messageboard.py and arduino.py into repository. To aid debugging, we want to keep past versions of the code easily accessible, and linked to the errors that have been logged. This function copies the python code into a version control directory after adding in a date / time stamp to the file name. """ global VERSION_MESSAGEBOARD global VERSION_ARDUINO VERSION_MESSAGEBOARD = MakeVersionCopy('messageboard') VERSION_ARDUINO = MakeVersionCopy('arduino') def MakeVersionCopy(python_prefix): """Copies current instance of python file into repository.""" <----SKIPPED LINES----> 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, iteration=iteration) 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 ( <----SKIPPED LINES----> |