01234567890123456789012345678901234567890123456789012345678901234567890123456789
3334353637383940414243444546474849505152 53 545556575859606162636465666768697071727374 267268269270271272273274275276277278279280281282283284285286 287288289290291292293294295296297298299 300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 331332333334335336337338339340341342343344345346347348349350351352353 661662663664665666667668669670671672673674675676677678679680681682 683684685686687688689690691692693694695696697698699700701702 1215121612171218121912201221122212231224122512261227122812291230123112321233123412351236 | <----SKIPPED LINES----> if RASPBERRY_PI: ARDUINO_LOG = MESSAGEBOARD_PATH + ARDUINO_LOG SERIALS_LOG = MESSAGEBOARD_PATH + SERIALS_LOG SERVO_SIMULATED_OUT = MESSAGEBOARD_PATH + SERVO_SIMULATED_OUT SERVO_SIMULATED_IN = MESSAGEBOARD_PATH + SERVO_SIMULATED_IN REMOTE_SIMULATED_OUT = MESSAGEBOARD_PATH + REMOTE_SIMULATED_OUT REMOTE_SIMULATED_IN = MESSAGEBOARD_PATH + REMOTE_SIMULATED_IN ARDUINO_ROLLING_LOG = WEBSERVER_PATH + ARDUINO_ROLLING_LOG CONNECTION_FLAG_BLUETOOTH = 1 CONNECTION_FLAG_USB = 2 CONNECTION_FLAG_SIMULATED = 3 RASPBERRY_PI = psutil.sys.platform.title() == 'Linux' SN_SERVO = '5583834303435111C1A0' SERVO_CONNECTION = (CONNECTION_FLAG_BLUETOOTH, (2, '98:D3:11:FC:42:16', 1)) SN_REMOTE = '75835343130351802272' REMOTE_CONNECTION = (CONNECTION_FLAG_BLUETOOTH, (1, '98:D3:91:FD:B1:8F', 1)) # directly connected to Serial2 REMOTE_CONNECTION = (CONNECTION_FLAG_BLUETOOTH, (1, '98:D3:91:FD:B3:C9', 1)) # connected thru MOSFET to Serial1 MIN_ALTITUDE = 5 # below this elevation degrees, turn off the tracking if SIMULATE_ARDUINO: SERVO_CONNECTION = (CONNECTION_FLAG_SIMULATED, (SERVO_SIMULATED_IN, SERVO_SIMULATED_OUT)) REMOTE_CONNECTION = ( CONNECTION_FLAG_SIMULATED, (REMOTE_SIMULATED_IN, REMOTE_SIMULATED_OUT)) KEY_NOT_PRESENT_STRING = 'N/A' DISP_LAST_FLIGHT_NUMB_ORIG_DEST = 0 DISP_LAST_FLIGHT_AZIMUTH_ELEVATION = 1 DISP_FLIGHT_COUNT_LAST_SEEN = 2 DISP_RADIO_RANGE = 3 DISPLAY_MODE_NAMES = [ 'LAST_FLIGHT_NUMB_ORIG_DEST', 'LAST_FLIGHT_AZIMUTH_ELEVATION', 'FLIGHT_COUNT_LAST_SEEN', 'RADIO_RANGE'] WRITE_DELAY_TIME = 0.2 # write to arduino every n seconds READ_DELAY_TIME = 0.1 # read from arduino every n seconds <----SKIPPED LINES----> Args: format_string: String of the form expected by struct.pack Returns: Tuple of values matching that as identified in format_string. """ if self.connection_type == CONNECTION_FLAG_SIMULATED: if ( self.__simulated_reads__ and time.time() - self.start_time > self.__simulated_reads__[0][0]): # time for next next_line = self.__simulated_reads__.pop(0) return next_line[1] return () if not format_string: format_string = self.read_format try: data = Read(self.link, format_string) except OSError as e: if self.error_pin: self.to_parent_q.put(('pin', (self.error_pin, True))) self.Reopen(log_message='Failed to read: %s' % e) return self.Read(format_string=format_string) self.last_read = time.time() if data: self.last_receipt = time.time() if LOG_SERIALS: ts = time.time() - self.start_time str_data = str(['%7.2f' % d if isinstance(d, float) else str(d) for d in data]) with open(SERIALS_LOG, 'a') as f: f.write('%10.3f RECD@%s: %s\n' % (ts, self.name, str_data)) if self.read_timeout and self.last_read - self.last_receipt > self.read_timeout: if self.error_pin: self.to_parent_q.put(('pin', (self.error_pin, True))) self.Reopen(log_message='Heartbeat not received in %.2f seconds (expected: %.2f)' % (self.last_read - self.last_receipt, self.read_timeout)) return self.Read(format_string=format_string) return data def Write(self, values, format_string=None): """Writes to an open serial. Writes to an open serial values as identified in the format_string provided here, or if not provided in this call, as saved on the Serial instance. If an OSError exception is detected, this method will attempt to reopen the connection. Args: values: tuple of values to send matching that as identified in format_string. format_string: String of the form expected by struct.pack """ ts = time.time() - self.start_time str_values = str(['%7.2f' % v if isinstance(v, float) else str(v) for v in values]) if self.connection_type == CONNECTION_FLAG_SIMULATED: with open(self.connection_tuple[1], 'a') as f: f.write('%10.3f: %s\n' % (ts, str_values)) return if not format_string: format_string = self.write_format try: Write(self.link, values, format_string) except OSError as e: if self.error_pin: self.to_parent_q.put(('pin', (self.error_pin, True))) self.Reopen(log_message='Failed to write: %s' % e) self.Write(values) if LOG_SERIALS: with open(SERIALS_LOG, 'a') as f: f.write('%10.3f SENT@%s: %s\n' % (ts, self.name, str_values)) def HasReset(self): """Indicates exactly oncewhether the serial connection has reset since last called.""" if self.connection_type == CONNECTION_FLAG_SIMULATED: raise NotImplementedError('Not implemented for simulations') flag = self.reset_flag self.reset_flag = False return flag def RunCommand(cmd, sleep_seconds=1, log=True): """Runs shell command, checking if it completed (perhaps with errors) within timeout.""" conn = subprocess.Popen(cmd, shell=True) time.sleep(sleep_seconds) conn.poll() <----SKIPPED LINES----> next_read = time.time() + READ_DELAY_TIME now = GetNow(json_desc_dict, additional_attr) current_angles = AzimuthAltitude(flight, now) if current_angles and time.time() > next_write: if current_angles[1] >= configuration['minimum_altitude_servo_tracking']: flight_present = True laser_rgb = LaserRGBFlight(flight) link.Write((*current_angles, *laser_rgb)) last_angles = current_angles # flight no longer tracked; send one more command to turn off lasers elif flight_present: link.Write((*last_angles, *LASER_RGB_OFF)) flight_present = False next_write = time.time() + WRITE_DELAY_TIME link.Close() Log('Shutdown signal received by process %d' % os.getpid(), link) to_parent_q.put(('pin', (messageboard.GPIO_ERROR_ARDUINO_SERVO_CONNECTION, True))) LASER_RGB_OFF = (0, 0, 0) def LaserRGBFlight(flight): """Based on flight attributes, set the laser.""" if not flight: return LASER_RGB_OFF return 1, 0, 0 def DifferentFlights(f1, f2): """True if flights same except for persistent path; False if they differ. We cannot simply check if two flights are identical by checking equality of the dicts, because a few attributes are updated after the flight is first found: - the persistent_path is kept current - cached_* attributes may be updated - the insights are generated after flight first enqueued On the other hand, we cannot check if they are identical by looking just at the flight number, because flight numbers may be unknown. Thus, this checks all <----SKIPPED LINES----> TestDisplayMode(DISP_LAST_FLIGHT_NUMB_ORIG_DEST) TestDisplayMode(DISP_LAST_FLIGHT_AZIMUTH_ELEVATION) TestDisplayMode(DISP_FLIGHT_COUNT_LAST_SEEN) TestDisplayMode(DISP_RADIO_RANGE) if time.time() >= next_write: next_write = SendRemoteMessage( flight, json_desc_dict, configuration, additional_attr, display_mode, write_keys, write_format_tuple, link) if time.time() >= next_read: values_t = link.Read() # simple ack message sent by servos values_d = dict(zip(read_keys, values_t)) if values_d.get('confirmed'): display_mode, low_batt = ExecuteArduinoCommand( values_d, configuration, display_mode, low_batt, to_parent_q, link) next_read = time.time() + READ_DELAY_TIME link.Close() Log('Shutdown signal received by process %d' % os.getpid(), link) to_parent_q.put(('pin', (messageboard.GPIO_ERROR_ARDUINO_REMOTE_CONNECTION, True))) |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
3334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710 1223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247 | <----SKIPPED LINES----> if RASPBERRY_PI: ARDUINO_LOG = MESSAGEBOARD_PATH + ARDUINO_LOG SERIALS_LOG = MESSAGEBOARD_PATH + SERIALS_LOG SERVO_SIMULATED_OUT = MESSAGEBOARD_PATH + SERVO_SIMULATED_OUT SERVO_SIMULATED_IN = MESSAGEBOARD_PATH + SERVO_SIMULATED_IN REMOTE_SIMULATED_OUT = MESSAGEBOARD_PATH + REMOTE_SIMULATED_OUT REMOTE_SIMULATED_IN = MESSAGEBOARD_PATH + REMOTE_SIMULATED_IN ARDUINO_ROLLING_LOG = WEBSERVER_PATH + ARDUINO_ROLLING_LOG CONNECTION_FLAG_BLUETOOTH = 1 CONNECTION_FLAG_USB = 2 CONNECTION_FLAG_SIMULATED = 3 RASPBERRY_PI = psutil.sys.platform.title() == 'Linux' SN_SERVO = '5583834303435111C1A0' SERVO_CONNECTION = (CONNECTION_FLAG_BLUETOOTH, (2, '98:D3:11:FC:42:16', 1)) SN_REMOTE = '75835343130351802272' # directly connected to Serial2 # REMOTE_CONNECTION = (CONNECTION_FLAG_BLUETOOTH, (1, '98:D3:91:FD:B1:8F', 1)) # connected thru MOSFET to Serial1 REMOTE_CONNECTION = (CONNECTION_FLAG_BLUETOOTH, (1, '98:D3:91:FD:B3:C9', 1)) MIN_ALTITUDE = 5 # below this elevation degrees, turn off the tracking if SIMULATE_ARDUINO: SERVO_CONNECTION = (CONNECTION_FLAG_SIMULATED, (SERVO_SIMULATED_IN, SERVO_SIMULATED_OUT)) REMOTE_CONNECTION = ( CONNECTION_FLAG_SIMULATED, (REMOTE_SIMULATED_IN, REMOTE_SIMULATED_OUT)) KEY_NOT_PRESENT_STRING = 'N/A' DISP_LAST_FLIGHT_NUMB_ORIG_DEST = 0 DISP_LAST_FLIGHT_AZIMUTH_ELEVATION = 1 DISP_FLIGHT_COUNT_LAST_SEEN = 2 DISP_RADIO_RANGE = 3 DISPLAY_MODE_NAMES = [ 'LAST_FLIGHT_NUMB_ORIG_DEST', 'LAST_FLIGHT_AZIMUTH_ELEVATION', 'FLIGHT_COUNT_LAST_SEEN', 'RADIO_RANGE'] WRITE_DELAY_TIME = 0.2 # write to arduino every n seconds READ_DELAY_TIME = 0.1 # read from arduino every n seconds <----SKIPPED LINES----> Args: format_string: String of the form expected by struct.pack Returns: Tuple of values matching that as identified in format_string. """ if self.connection_type == CONNECTION_FLAG_SIMULATED: if ( self.__simulated_reads__ and time.time() - self.start_time > self.__simulated_reads__[0][0]): # time for next next_line = self.__simulated_reads__.pop(0) return next_line[1] return () if not format_string: format_string = self.read_format try: data = Read(self.link, format_string) except OSError as e: failure_message = 'Failed to read: %s' % e if self.error_pin: self.to_parent_q.put(('pin', (self.error_pin, True, failure_message))) self.Reopen(log_message=failure_message) return self.Read(format_string=format_string) self.last_read = time.time() if data: self.last_receipt = time.time() if LOG_SERIALS: ts = time.time() - self.start_time str_data = str(['%7.2f' % d if isinstance(d, float) else str(d) for d in data]) with open(SERIALS_LOG, 'a') as f: f.write('%10.3f RECD@%s: %s\n' % (ts, self.name, str_data)) if self.read_timeout and self.last_read - self.last_receipt > self.read_timeout: failure_message = 'Heartbeat not received in %.2f seconds (expected: %.2f)' % ( self.last_read - self.last_receipt, self.read_timeout) if self.error_pin: self.to_parent_q.put(('pin', (self.error_pin, True, failure_message))) self.Reopen(log_message=failure_message) return self.Read(format_string=format_string) return data def Write(self, values, format_string=None): """Writes to an open serial. Writes to an open serial values as identified in the format_string provided here, or if not provided in this call, as saved on the Serial instance. If an OSError exception is detected, this method will attempt to reopen the connection. Args: values: tuple of values to send matching that as identified in format_string. format_string: String of the form expected by struct.pack """ ts = time.time() - self.start_time str_values = str(['%7.2f' % v if isinstance(v, float) else str(v) for v in values]) if self.connection_type == CONNECTION_FLAG_SIMULATED: with open(self.connection_tuple[1], 'a') as f: f.write('%10.3f: %s\n' % (ts, str_values)) return if not format_string: format_string = self.write_format try: Write(self.link, values, format_string) except OSError as e: failure_message = 'Failed to write: %s' % e if self.error_pin: self.to_parent_q.put(('pin', (self.error_pin, True, failure_message))) self.Reopen(log_message=failure_message) self.Write(values) if LOG_SERIALS: with open(SERIALS_LOG, 'a') as f: f.write('%10.3f SENT@%s: %s\n' % (ts, self.name, str_values)) def HasReset(self): """Indicates exactly oncewhether the serial connection has reset since last called.""" if self.connection_type == CONNECTION_FLAG_SIMULATED: raise NotImplementedError('Not implemented for simulations') flag = self.reset_flag self.reset_flag = False return flag def RunCommand(cmd, sleep_seconds=1, log=True): """Runs shell command, checking if it completed (perhaps with errors) within timeout.""" conn = subprocess.Popen(cmd, shell=True) time.sleep(sleep_seconds) conn.poll() <----SKIPPED LINES----> next_read = time.time() + READ_DELAY_TIME now = GetNow(json_desc_dict, additional_attr) current_angles = AzimuthAltitude(flight, now) if current_angles and time.time() > next_write: if current_angles[1] >= configuration['minimum_altitude_servo_tracking']: flight_present = True laser_rgb = LaserRGBFlight(flight) link.Write((*current_angles, *laser_rgb)) last_angles = current_angles # flight no longer tracked; send one more command to turn off lasers elif flight_present: link.Write((*last_angles, *LASER_RGB_OFF)) flight_present = False next_write = time.time() + WRITE_DELAY_TIME link.Close() failure_message = 'Shutdown signal received by process %d' % os.getpid() Log(failure_message, link) to_parent_q.put(( 'pin', (messageboard.GPIO_ERROR_ARDUINO_SERVO_CONNECTION, True, failure_message))) LASER_RGB_OFF = (0, 0, 0) def LaserRGBFlight(flight): """Based on flight attributes, set the laser.""" if not flight: return LASER_RGB_OFF return 1, 0, 0 def DifferentFlights(f1, f2): """True if flights same except for persistent path; False if they differ. We cannot simply check if two flights are identical by checking equality of the dicts, because a few attributes are updated after the flight is first found: - the persistent_path is kept current - cached_* attributes may be updated - the insights are generated after flight first enqueued On the other hand, we cannot check if they are identical by looking just at the flight number, because flight numbers may be unknown. Thus, this checks all <----SKIPPED LINES----> TestDisplayMode(DISP_LAST_FLIGHT_NUMB_ORIG_DEST) TestDisplayMode(DISP_LAST_FLIGHT_AZIMUTH_ELEVATION) TestDisplayMode(DISP_FLIGHT_COUNT_LAST_SEEN) TestDisplayMode(DISP_RADIO_RANGE) if time.time() >= next_write: next_write = SendRemoteMessage( flight, json_desc_dict, configuration, additional_attr, display_mode, write_keys, write_format_tuple, link) if time.time() >= next_read: values_t = link.Read() # simple ack message sent by servos values_d = dict(zip(read_keys, values_t)) if values_d.get('confirmed'): display_mode, low_batt = ExecuteArduinoCommand( values_d, configuration, display_mode, low_batt, to_parent_q, link) next_read = time.time() + READ_DELAY_TIME link.Close() failure_message = 'Shutdown signal received by process %d' % os.getpid() Log(failure_message, link) to_parent_q.put(( 'pin', (messageboard.GPIO_ERROR_ARDUINO_REMOTE_CONNECTION, True, failure_message))) |