class CommandProducer(SingletonMixin): """Forwards commands.""" def __init__(self): super(CommandProducer, self).__init__() self._producer = MessageProducer(config.COMMAND_EXCHANGE) def start(self): """Send the start command.""" self._producer.publish('start') def stop(self): """Send the stop command.""" self._producer.publish('stop') def reset(self): """Send the reset command.""" self._producer.publish('reset') def calibrate_compass(self): """Send the calibrate_compass command.""" self._producer.publish('calibrate-compass') def set_max_throttle(self, throttle): """Send the set max throttle command.""" self._producer.publish('set-max-throttle={}'.format(throttle))
class WaypointProducer(SingletonMixin): """Forwards waypoint commands to another exchange.""" def __init__(self): super(WaypointProducer, self).__init__() self._producer = MessageProducer(config.WAYPOINT_EXCHANGE) def load_kml_file(self, kml_file_name): """Loads some waypoints from a KML file.""" self._producer.publish( json.dumps({ 'command': 'load', 'file': kml_file_name }))
class WaypointProducer(SingletonMixin): """Forwards waypoint commands to another exchange.""" def __init__(self): super(WaypointProducer, self).__init__() self._producer = MessageProducer(config.WAYPOINT_EXCHANGE) def load_kml_file(self, kml_file_name): """Loads some waypoints from a KML file.""" self._producer.publish( json.dumps({ 'command': 'load', 'file': kml_file_name }) )
class CommandForwardProducer(SingletonMixin): """Forwards commands to another exchange.""" # This is a complete hack. I couldn't figure out how to do multiple # consumers, but I only need it for one producer (command) and I only have # two consumers, so I'll just manually forward them. I know this is fragile # and tightly coupled, because handlers shouldn't need to or know about # forwarding messages. # TODO(skari): Implement multi consumer def __init__(self): super(CommandForwardProducer, self).__init__() self._producer = MessageProducer(config.COMMAND_FORWARDED_EXCHANGE) def forward(self, message): """Forwards the message.""" self._producer.publish(message)
class AsyncLogger(SingletonMixin): """Logger that sends messages over Unix domain sockets.""" def __init__(self): super(AsyncLogger, self).__init__() self._producer = MessageProducer(config.LOGS_EXCHANGE) self.warning = self.warn def debug(self, message): """Forwards messages to debug log.""" self._producer.publish( json.dumps({ 'level': 'debug', 'message': message })) def info(self, message): """Forwards messages to info log.""" self._producer.publish( json.dumps({ 'level': 'info', 'message': message })) def warn(self, message): """Forwards messages to warn log.""" self._producer.publish( json.dumps({ 'level': 'warn', 'message': message })) def error(self, message): """Forwards messages to error log.""" self._producer.publish( json.dumps({ 'level': 'error', 'message': message })) def critical(self, message): """Forwards messages to critical log.""" self._producer.publish( json.dumps({ 'level': 'critical', 'message': message }))
class AsyncLogger(SingletonMixin): """Logger that sends messages over Unix domain sockets.""" def __init__(self): super(AsyncLogger, self).__init__() self._producer = MessageProducer(config.LOGS_EXCHANGE) self.warning = self.warn def debug(self, message): """Forwards messages to debug log.""" self._producer.publish(json.dumps({ 'level': 'debug', 'message': message })) def info(self, message): """Forwards messages to info log.""" self._producer.publish(json.dumps({ 'level': 'info', 'message': message })) def warn(self, message): """Forwards messages to warn log.""" self._producer.publish(json.dumps({ 'level': 'warn', 'message': message })) def error(self, message): """Forwards messages to error log.""" self._producer.publish(json.dumps({ 'level': 'error', 'message': message })) def critical(self, message): """Forwards messages to critical log.""" self._producer.publish(json.dumps({ 'level': 'critical', 'message': message }))
def terminate(signal_number, stack_frame): # pylint: disable=unused-argument """Terminates the program. Used when a signal is received.""" print( 'Received signal {signal_number}, quitting'.format( signal_number=signal_number ) ) if POPEN is not None and POPEN.poll() is None: print('Killing image capture') try: POPEN.kill() except OSError: pass DRIVER.drive(0.0, 0.0) time.sleep(0.2) try: with open('/dev/pi-blaster', 'w') as blaster: time.sleep(0.1) blaster.write( '{pin}={throttle}\n'.format( pin=THROTTLE_GPIO_PIN, throttle=THROTTLE_NEUTRAL_US ) ) time.sleep(0.1) blaster.write( '{pin}={steering}\n'.format( pin=STEERING_GPIO_PIN, steering=STEERING_NEUTRAL_US ) ) time.sleep(0.1) except IOError: pass for socket in os.listdir(os.sep.join(('.', 'messaging', 'sockets'))): MessageProducer(socket).kill() time.sleep(0.1) for thread in THREADS: thread.kill() thread.join() # Some threads should still be active expected = set(('MainThread', '_TimeoutMonitor')) actives = set((thread.name for thread in threading.enumerate())) if not (actives <= expected): print('Trying to exit while {} threads are still active!'.format( threading.active_count() )) for thread in threading.enumerate(): print(thread.name) sys.exit(0)
class TelemetryProducer(SingletonMixin): """Forwards telemetry messages.""" def __init__(self): super(TelemetryProducer, self).__init__() self._producer = MessageProducer(config.TELEMETRY_EXCHANGE) def gps_reading( self, latitude_d, longitude_d, accuracy_m, heading_d, speed_m_s, timestamp_s, device_id ): """Sends a GPS reading.""" self._producer.publish(json.dumps({ 'latitude_d': latitude_d, 'longitude_d': longitude_d, 'accuracy_m': accuracy_m, 'heading_d': heading_d, 'speed_m_s': speed_m_s, 'timestamp_s': timestamp_s, 'device_id': device_id, })) def compass_reading(self, compass_d, confidence, device_id): """Sends a compass reading.""" self._producer.publish(json.dumps({ 'compass_d': compass_d, 'confidence': confidence, 'device_id': device_id, })) def accelerometer_reading( self, acceleration_g_x, acceleration_g_y, acceleration_g_z, device_id ): """Sends an accelerometer reading.""" self._producer.publish(json.dumps({ 'acceleration_g_x': acceleration_g_x, 'acceleration_g_y': acceleration_g_y, 'acceleration_g_z': acceleration_g_z, 'device_id': device_id, }))
class TelemetryProducer(SingletonMixin): """Forwards telemetry messages.""" def __init__(self): super(TelemetryProducer, self).__init__() self._producer = MessageProducer(config.TELEMETRY_EXCHANGE) def gps_reading(self, latitude_d, longitude_d, accuracy_m, heading_d, speed_m_s, timestamp_s, device_id): """Sends a GPS reading.""" self._producer.publish( json.dumps({ 'latitude_d': latitude_d, 'longitude_d': longitude_d, 'accuracy_m': accuracy_m, 'heading_d': heading_d, 'speed_m_s': speed_m_s, 'timestamp_s': timestamp_s, 'device_id': device_id, })) def compass_reading(self, compass_d, confidence, device_id): """Sends a compass reading.""" self._producer.publish( json.dumps({ 'compass_d': compass_d, 'confidence': confidence, 'device_id': device_id, })) def accelerometer_reading(self, acceleration_g_x, acceleration_g_y, acceleration_g_z, device_id): """Sends an accelerometer reading.""" self._producer.publish( json.dumps({ 'acceleration_g_x': acceleration_g_x, 'acceleration_g_y': acceleration_g_y, 'acceleration_g_z': acceleration_g_z, 'device_id': device_id, }))
def __init__(self): super(AsyncLogger, self).__init__() self._producer = MessageProducer(config.LOGS_EXCHANGE) self.warning = self.warn
def test_1_producer_1_consumer(self): """Test single producer single consumer.""" def save_message(x): self.message = x def consume(): """Function to consume messages.""" consume_messages(self.EXCHANGE, save_message) consumer = threading.Thread(target=consume) consumer.name = '{}:consume_messages'.format(self.__class__.__name__) consumer.start() # Give the receiver some time to set up, see comment below time.sleep(0.05) self.assertIs(self.message, None) sent_message = 'banana' producer = MessageProducer(self.EXCHANGE) producer.publish(sent_message) producer.publish('QUIT') for _ in range(10): # Because of a race condition, if the message is sent before the # receiver has set up, the messages are never queued or something. # Keep resending until the thread exits. consumer.join(0.05) if consumer.is_alive(): producer.publish(sent_message) producer.publish('QUIT') consumer.join(0.05) self.assertFalse(consumer.is_alive()) producer.kill() self.assertEqual(self.message, sent_message)
def __init__(self): super(WaypointProducer, self).__init__() self._producer = MessageProducer(config.WAYPOINT_EXCHANGE)
def __init__(self): super(TelemetryProducer, self).__init__() self._producer = MessageProducer(config.TELEMETRY_EXCHANGE)
def __init__(self): super(CommandForwardProducer, self).__init__() self._producer = MessageProducer(config.COMMAND_FORWARDED_EXCHANGE)