def main(): init_logging() transport = SerialTransport() c = Pytelemetry(transport) options = dict() options['port'] = "COM20" options['baudrate'] = 115200 transport.connect(options) #c.subscribe(None, printer) bad_frame = bytearray(b'0700736f6d65746f70696300626f6f7961613ecc') c.api._decode_frame(bad_frame) c.publish('sometopic','booyaa','string') timeout = time.time() + 3 while True: c.update() if time.time() > timeout: break transport.disconnect() print("Done.")
def test_unexisting_type(): # Setup t = transportMock() c = Pytelemetry(t) c.publish('sometopic',12,'int323') assert t.queue.qsize() == 0
def test_unexisting_type(): # Setup t = transportMock() c = Pytelemetry(t) with pytest.raises(IndexError): c.publish('sometopic',12,'int323') assert t.queue.qsize() == 0
def test_unexisting_type(): # Setup t = transportMock() c = Pytelemetry(t) with pytest.raises(IndexError): c.publish('sometopic', 12, 'int323') assert t.queue.qsize() == 0
def test_serial_stats(): # Setup t = SerialTransport() t.driver = driverMock() c = Pytelemetry(t) stats = t.stats() assert stats['rx_bytes'] == 0 assert stats['rx_chunks'] == 0 assert stats['tx_bytes'] == 0 assert stats['tx_chunks'] == 0 c.publish('foo', 'bar', 'string') stats = t.stats() assert stats['rx_bytes'] == 0 assert stats['rx_chunks'] == 0 assert stats['tx_bytes'] == 13 assert stats['tx_chunks'] == 1 c.update() stats = t.stats() assert stats['rx_bytes'] == 13 assert stats[ 'rx_chunks'] == 13 # TODO : For now data read byte after byter. To replace by read in bulk assert stats['tx_bytes'] == 13 assert stats['tx_chunks'] == 1 c.publish('fooqux', -32767, 'int16') stats = t.stats() assert stats['rx_bytes'] == 13 assert stats['rx_chunks'] == 13 assert stats['tx_bytes'] == 13 + 15 assert stats['tx_chunks'] == 2 c.update() stats = t.stats() assert stats['rx_bytes'] == 13 + 15 assert stats['rx_chunks'] == 13 + 15 assert stats['tx_bytes'] == 13 + 15 assert stats['tx_chunks'] == 2 t.resetStats() stats = t.stats() assert stats['rx_bytes'] == 0 assert stats['rx_chunks'] == 0 assert stats['tx_bytes'] == 0 assert stats['tx_chunks'] == 0
def test_wrong_type(): # Setup t = transportMock() c = Pytelemetry(t) with pytest.raises(Exception) as excinfo: c.publish('sometopic', 12, 'string') # TODO : Assert exception assert t.queue.qsize() == 0
def test_wrong_type(): # Setup t = transportMock() c = Pytelemetry(t) with pytest.raises(Exception) as excinfo: c.publish('sometopic',12,'string') # TODO : Assert exception assert t.queue.qsize() == 0
def test_hardcoded(): t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic","data"]) c.subscribe('sometopic ',cb) # Apply hardcoded frame directly generated by the c library # SOF head sometopic..................................... eol 12457........ crc..... eof t.write([247, 6, 0, 115, 111, 109, 101, 116, 111, 112, 105, 99, 32, 0, 169, 48, 0, 0, 111, 249, 127]) c.update() assert t.queue.qsize() == 0 cb.assert_called_once_with('sometopic ',12457, None)
def test_serial_stats(): # Setup t = SerialTransport() t.driver = driverMock() c = Pytelemetry(t) stats = t.stats() assert stats["rx_bytes"] == 0 assert stats["rx_chunks"] == 0 assert stats["tx_bytes"] == 0 assert stats["tx_chunks"] == 0 c.publish("foo", "bar", "string") stats = t.stats() assert stats["rx_bytes"] == 0 assert stats["rx_chunks"] == 0 assert stats["tx_bytes"] == 13 assert stats["tx_chunks"] == 1 c.update() stats = t.stats() assert stats["rx_bytes"] == 13 assert stats["rx_chunks"] == 13 # TODO : For now data read byte after byter. To replace by read in bulk assert stats["tx_bytes"] == 13 assert stats["tx_chunks"] == 1 c.publish("fooqux", -32767, "int16") stats = t.stats() assert stats["rx_bytes"] == 13 assert stats["rx_chunks"] == 13 assert stats["tx_bytes"] == 13 + 15 assert stats["tx_chunks"] == 2 c.update() stats = t.stats() assert stats["rx_bytes"] == 13 + 15 assert stats["rx_chunks"] == 13 + 15 assert stats["tx_bytes"] == 13 + 15 assert stats["tx_chunks"] == 2 t.resetStats() stats = t.stats() assert stats["rx_bytes"] == 0 assert stats["rx_chunks"] == 0 assert stats["tx_bytes"] == 0 assert stats["tx_chunks"] == 0
def test_topic_contains_space_both_ends(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic", "data", "opts"]) c.subscribe(' topicwithspaces ', cb) c.publish(' topicwithspaces ', 1234567, 'int32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_once_with(' topicwithspaces ', 1234567, None)
def main(): init_logging() transport = SerialTransport() c = Pytelemetry(transport) options = dict() options['port'] = "COM20" options['baudrate'] = 115200 transport.connect(options) #c.subscribe(None, printer) bad_frame = bytearray(b'0700736f6d65746f70696300626f6f7961613ecc') c.api._decode_frame(bad_frame) c.publish('sometopic', 'booyaa', 'string') timeout = time.time() + 3 while True: c.update() if time.time() > timeout: break transport.disconnect() print("Done.")
def __init__(self, transport=None, stdout=None): # cmd Initialization and configuration cmd.Cmd.__init__(self, stdout=stdout) self.intro = 'pytelemetry terminal started.' \ + ' (type help for a list of commands.)' self.prompt = ':> ' self.file = None # pytelemetry setup if not transport: self.transport = transports.SerialTransport() else: self.transport = transport self.telemetry = Pytelemetry(self.transport) self.topics = Topics() self.plots = [] self.plotsLock = Lock() self.runner = Runner(self.transport, self.telemetry, self.plots, self.plotsLock, self.topics) self.telemetry.subscribe(None, self.topics.process) self.types_lookup = { '--s': 'string', '--u8': 'uint8', '--u16': 'uint16', '--u32': 'uint32', '--i8': 'int8', '--i16': 'int16', '--i32': 'int32', '--f32': 'float32' } logger.info("Module path : %s" % os.path.dirname(os.path.realpath(__file__))) try: logger.info("Module version : %s" % __version__) except: logger.warning("Module version : not found.")
def test_topic_contains_space_both_ends(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic","data","opts"]) c.subscribe(' topicwithspaces ',cb) c.publish(' topicwithspaces ',1234567,'int32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_once_with(' topicwithspaces ',1234567,None)
def test_hardcoded(): t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic", "data"]) c.subscribe('sometopic ', cb) # Apply hardcoded frame directly generated by the c library # SOF head sometopic..................................... eol 12457........ crc..... eof t.write([ 247, 6, 0, 115, 111, 109, 101, 116, 111, 112, 105, 99, 32, 0, 169, 48, 0, 0, 111, 249, 127 ]) c.update() assert t.queue.qsize() == 0 cb.assert_called_once_with('sometopic ', 12457, None)
def __init__(self, transport=None, stdout=None): # cmd Initialization and configuration cmd.Cmd.__init__(self,stdout=stdout) self.intro = 'pytelemetry terminal started.' \ + ' (type help for a list of commands.)' self.prompt = ':> ' self.file = None # pytelemetry setup if not transport: self.transport = transports.SerialTransport() else: self.transport = transport self.telemetry = Pytelemetry(self.transport) self.topics = Topics() self.plots = [] self.plotsLock = Lock() self.runner = Runner(self.transport, self.telemetry, self.plots, self.plotsLock, self.topics) self.telemetry.subscribe(None,self.topics.process) self.types_lookup = {'--s' : 'string', '--u8' : 'uint8', '--u16' : 'uint16', '--u32' : 'uint32', '--i8' : 'int8', '--i16' : 'int16', '--i32' : 'int32', '--f32' : 'float32'} logger.info("Module path : %s" % os.path.dirname(os.path.realpath(__file__))) try: logger.info("Module version : %s" % __version__) except: logger.warning("Module version : not found.")
def test_protocol_stats(): t = transportMock() p = Pytelemetry(t) measures = p.api.stats() assert measures["rx_decoded_frames"] == 0 assert measures["rx_corrupted_crc"] == 0 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # Add a frame inside the transport queue t.write(bytearray.fromhex("f70700666f6f0062617247027f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 0 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # replaced CRC '4702' by '4701' to corrupt crc t.write(bytearray.fromhex("f70700666f6f0062617247017f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 1 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # replaced byte n3 '00' by '10' to corrupt crc t.write(bytearray.fromhex("f70710666f6f0062617247027f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 #crc = crc16(bytearray.fromhex("0900666f6f00626172")) #print(crc) #crc = struct.pack("<H",crc) #print(crc.hex()) # Replaced header from 0700 to 0900 to corrupt it. Crc is valid to not discard t.write(bytearray.fromhex("f70900666f6f006261725fc57f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 1 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 #crc = crc16(bytearray.fromhex("0700666f6f01626172")) #print(crc) #crc = struct.pack("<H",crc) #print(crc.hex()) # Removed EOL. Crc is valid to not discard t.write(bytearray.fromhex("f70700666f6f0162617224417f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 1 assert measures["rx_corrupted_eol"] == 1 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # Impossible to detect corrupted payload of type string because length is unkown. One more reason to store framesize inside frame # Use a frame of type u32 instead #crc = crc16(bytearray.fromhex("03006b6c6d6f707100ffffff")) #crc = struct.pack("<H",crc) #print(crc.hex()) # Corruped payload by removing third & fourth hex number from end. Crc will pass # t.write(bytearray.fromhex("f703006b6c6d6f707100fffffff2dd7f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 1 assert measures["rx_corrupted_eol"] == 1 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 1 assert measures["tx_encoded_frames"] == 0 topmeasures = p.stats() assert measures["rx_decoded_frames"] == topmeasures['protocol']["rx_decoded_frames"] assert measures["rx_corrupted_crc"] == topmeasures['protocol']["rx_corrupted_crc"] assert measures["rx_corrupted_header"] == topmeasures['protocol']["rx_corrupted_header"] assert measures["rx_corrupted_eol"] == topmeasures['protocol']["rx_corrupted_eol"] assert measures["rx_corrupted_topic"] == topmeasures['protocol']["rx_corrupted_topic"] assert measures["rx_corrupted_payload"] == topmeasures['protocol']["rx_corrupted_payload"] assert measures["tx_encoded_frames"] == topmeasures['protocol']["tx_encoded_frames"] p.publish("boo", 123, "uint8") # get measurements measures = p.stats() assert measures['protocol']["rx_decoded_frames"] == 1 assert measures['protocol']["rx_corrupted_crc"] == 2 assert measures['protocol']["rx_corrupted_header"] == 1 assert measures['protocol']["rx_corrupted_eol"] == 1 assert measures['protocol']["rx_corrupted_topic"] == 0 assert measures['protocol']["rx_corrupted_payload"] == 1 assert measures['protocol']["tx_encoded_frames"] == 1 measures = p.api.delimiter.stats() assert measures["rx_processed_bytes"] > 0 assert measures["rx_discarded_bytes"] == 0 assert measures["rx_escaped_bytes"] == 0 assert measures["rx_complete_frames"] > 0 assert measures["rx_uncomplete_frames"] == 0 assert measures["tx_processed_bytes"] > 0 assert measures["tx_encoded_frames"] > 0 assert measures["tx_escaped_bytes"] == 0 p.resetStats() measures = p.stats() assert measures['protocol']["rx_decoded_frames"] == 0 assert measures['protocol']["rx_corrupted_crc"] == 0 assert measures['protocol']["rx_corrupted_header"] == 0 assert measures['protocol']["rx_corrupted_eol"] == 0 assert measures['protocol']["rx_corrupted_topic"] == 0 assert measures['protocol']["rx_corrupted_payload"] == 0 assert measures['protocol']["tx_encoded_frames"] == 0 assert measures['framing']["rx_processed_bytes"] == 0 assert measures['framing']["rx_discarded_bytes"] == 0 assert measures['framing']["rx_escaped_bytes"] == 0 assert measures['framing']["rx_complete_frames"] == 0 assert measures['framing']["rx_uncomplete_frames"] == 0 assert measures['framing']["tx_processed_bytes"] == 0 assert measures['framing']["tx_encoded_frames"] == 0 assert measures['framing']["tx_escaped_bytes"] == 0
def test_end_to_end_string(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic","data","opts"]) default_cb = mock.Mock(spec=["topic","data","opts"]) c.subscribe('sometopic',cb) c.subscribe(None,default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic','someMessage','string') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_once_with('sometopic','someMessage',None) # test default callback c.publish('othertopic','otherMessage','string') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 default_cb.assert_called_once_with('othertopic','otherMessage',None)
def test_end_to_end_uints(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic", "data", "opts"]) default_cb = mock.Mock(spec=["topic", "data", "opts"]) c.subscribe('sometopic', cb) c.subscribe(None, default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 255, 'uint8') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', 255, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 65535, 'uint16') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', 65535, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 4294967295, 'uint32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', 4294967295, None)
def test_end_to_end_uints(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic","data","opts"]) default_cb = mock.Mock(spec=["topic","data","opts"]) c.subscribe('sometopic',cb) c.subscribe(None,default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',255,'uint8') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',255,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',65535,'uint16') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',65535,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',4294967295,'uint32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',4294967295,None)
class Application(cmd.Cmd): def __init__(self, transport=None, stdout=None): # cmd Initialization and configuration cmd.Cmd.__init__(self, stdout=stdout) self.intro = 'pytelemetry terminal started.' \ + ' (type help for a list of commands.)' self.prompt = ':> ' self.file = None # pytelemetry setup if not transport: self.transport = transports.SerialTransport() else: self.transport = transport self.telemetry = Pytelemetry(self.transport) self.topics = Topics() self.plots = [] self.plotsLock = Lock() self.runner = Runner(self.transport, self.telemetry, self.plots, self.plotsLock, self.topics) self.telemetry.subscribe(None, self.topics.process) self.types_lookup = { '--s': 'string', '--u8': 'uint8', '--u16': 'uint16', '--u32': 'uint32', '--i8': 'int8', '--i16': 'int16', '--i32': 'int32', '--f32': 'float32' } logger.info("Module path : %s" % os.path.dirname(os.path.realpath(__file__))) try: logger.info("Module version : %s" % __version__) except: logger.warning("Module version : not found.") def emptyline(self): pass # Override default behavior to repeat last command if empty input @docopt_cmd def do_serial(self, arg): """ List serial ports or connect to one of them. Usage: serial ((-l | --list) | <port> [options]) Options: -b X, --bauds X Connection speed in bauds [default: 9600] """ if arg['--list'] or arg['-l']: self.stdout.write("Available COM ports:\n") for port, desc, hid in list_ports.comports(): self.stdout.write("%s \t %s\n" % (port, desc)) return try: self.runner.disconnect() logger.warn("User requested connect without desconnecting first.") except (IOError, AttributeError) as e: logger.warn( "Already disconnected. Continuing happily. E : {0}".format(e)) pass self.topics.clear() logger.info("Cleared all topics for new session.") self.transport.resetStats(averaging_window=10) self.runner.resetStats() self.telemetry.resetStats() logger.info("Cleared all stats for new session.") try: b = int(arg['--bauds']) self.runner.connect(arg['<port>'], b) except IOError as e: self.stdout.write( "Failed to connect to {0} at {1} (bauds).\n".format( arg['<port>'], b)) logger.warn( "Failed to connect to {0} at {1} (bauds). E : \n".format( arg['<port>'], b, e)) else: s = "Connected to {0} at {1} (bauds).\n".format(arg['<port>'], b) self.stdout.write(s) logger.info(s) @docopt_cmd def do_print(self, arg): """ Prints X last received samples from <topic>. Usage: print <topic> [options] Options: -a, --all Display all received samples under <topic> -l X, --limit X Display X last received samples under <topic> [default: 1] """ topic = arg['<topic>'] if not self.topics.exists(topic): s = "Topic '{0}' unknown. Type 'ls' to list all available topics.\n".format( topic) self.stdout.write(s) logger.warn(s) return try: if arg['--all']: amount = 0 # 0 is understood as 'return all samples' by self.topics.samples() else: amount = int(arg['--limit']) except: s = "Could not cast --limit = '{0}' to integer. Using 1.\n".format( arg['--limit']) self.stdout.write(s) logger.warn(s) amount = 1 s = self.topics.samples(topic, amount) if s is not None: for i in s: self.stdout.write("{0}\n".format(i)) else: logger.error( "Could not retrieve {0} sample(s) under topic '{1}'.\n".format( amount, topic)) @docopt_cmd def do_ls(self, arg): """ Prints available topics. Topics are basically labels under which data is available (for display, plot, etc). Data can come from remote source (a connected embedded device) or the command-line interface itself (reception speed, etc). Without flags, prints a list of remote topics. Usage: ls [options] Options: -c, --cli Prints all CLI topics. Use this to display topics for monitoring reception speed, errors amount, etc. """ if arg['--cli']: for topic in self.topics.ls(source='cli'): self.stdout.write("%s\n" % topic) return for topic in self.topics.ls(source='remote'): self.stdout.write("%s\n" % topic) @docopt_cmd def do_plot(self, arg): """ Plots <topic> in a graph window. Usage: plot <topic> """ topic = arg['<topic>'] if not self.topics.exists(topic): s = "Topic '{0}' unknown. Type 'ls' to list all available topics.\n".format( topic) self.stdout.write(s) logger.warn(s) return if self.topics.intransfer(topic): s = "Topic '{0}' already plotting.\n".format(topic) self.stdout.write(s) logger.warn(s) return has_indexes = self.topics.has_indexed_data(arg['<topic>']) if has_indexes: plotType = PlotType.indexed transferType = "indexed" else: plotType = PlotType.linear transferType = "linear" p = Superplot(topic, plotType) q, ctrl = p.start() # Protect self.plots from modifications from the runner thread self.plotsLock.acquire() self.plots.append({ 'topic': topic, 'plot': p, # Plot handler 'queue': q, # Data queue 'ctrl': ctrl # Plot control pipe }) self.plotsLock.release() self.topics.transfer(topic, q, transfer_type=transferType) s = "Plotting '{0}' in mode [{1}].\n".format(topic, transferType) logger.info(s) self.stdout.write(s) @docopt_cmd def do_pub(self, arg): """ Publishes a (value | string) on <topic>. Usage: pub (--u8 | --u16 | --u32 | --i8 | --i16 | --i32 | --f32 | --s) <topic> <value> """ if arg['--f32']: arg['<value>'] = float(arg['<value>']) elif not arg['--s']: try: arg['<value>'] = int(arg['<value>']) except: # User most likely entered a float with an integer flag inter = float(arg['<value>']) rounded = int(inter) if isclose(inter, rounded): arg['<value>'] = rounded else: s = "Aborted : Wrote decimal number ({0}) with integer flag.".format( arg['<value>']) self.stdout.write(s + "\n") logger.warning(s) return subset = { k: arg[k] for k in ("--u8", "--u16", "--u32", "--i8", "--i16", "--i32", "--f32", "--s") } valtype = None for i, k in subset.items(): if k: valtype = self.types_lookup[i] if not valtype: logger.error("Payload type [{0}] unkown.".format(arg)) return try: self.telemetry.publish(arg['<topic>'], arg['<value>'], valtype) except SerialTimeoutException as e: self.stdout.write("Pub failed. Connection most likely terminated.") logger.error( "Pub failed. Connection most likely terminated. exception : %s" % e) return except AttributeError as e: self.stdout.write( "Pub failed because you are not connected to any device. Connect first using `serial` command." ) logger.warning( "Trying to publish while not connected. exception : %s" % e) return s = "Published on topic '{0}' : {1} [{2}]".format( arg['<topic>'], arg['<value>'], valtype) self.stdout.write(s + "\n") logger.info(s) @docopt_cmd def do_count(self, arg): """ Prints a count of received samples for each topic. Usage: count """ for topic in self.topics.ls(): self.stdout.write("{0} : {1}\n".format(topic, self.topics.count(topic))) @docopt_cmd def do_disconnect(self, arg): """ Disconnects from any open connection. Usage: disconnect """ try: self.runner.disconnect() self.stdout.write("Disconnected.\n") logger.info("Disconnected.") measures = self.transport.stats() for key, item in measures.items(): logger.info("Raw IO : %s : %s" % (key, item)) measures = self.runner.stats() for key, item in measures.items(): logger.info("IO speeds : %s : %s" % (key, item)) measures = self.telemetry.stats() for key, item in measures['framing'].items(): logger.info("Framing : %s : %s" % (key, item)) for key, item in measures['protocol'].items(): logger.info("Protocol : %s : %s" % (key, item)) logger.info("Logged session statistics.") except: logger.warn("Already disconnected. Continuing happily.") @docopt_cmd def do_info(self, arg): """ Prints out cli.py full path, module version. Usage: info """ self.stdout.write("- CLI path : %s\n" % os.path.dirname(os.path.realpath(__file__))) try: self.stdout.write("- version : %s\n" % __version__) except: self.stdout.write("- version : not found.\n") @docopt_cmd def do_stats(self, arg): """ Displays different metrics about the active transport (ex : serial port). This allows you to know if for instance corrupted frames are received, what fraction of the maximum baudrate is being used, etc. Usage: stats """ measures = self.transport.stats() self.stdout.write("Raw IO:\n") for key, item in measures.items(): self.stdout.write("\t%s : %s\n" % (key, item)) measures = self.runner.stats() self.stdout.write("IO speeds:\n") for key, item in measures.items(): self.stdout.write("\t%s : %s\n" % (key, item)) measures = self.telemetry.stats() self.stdout.write("Framing:\n") for key, item in measures['framing'].items(): self.stdout.write("\t%s : %s\n" % (key, item)) self.stdout.write("Protocol:\n") for key, item in measures['protocol'].items(): self.stdout.write("\t%s : %s\n" % (key, item)) def do_quit(self, arg): """ Exits the terminal application. Usage: quit """ self.runner.terminate() self.do_disconnect("") self.stdout.write("Good Bye!\n") logger.info("Application quit.") exit()
def test_end_to_end_ints(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic", "data", "opts"]) default_cb = mock.Mock(spec=["topic", "data", "opts"]) c.subscribe('sometopic', cb) c.subscribe(None, default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 127, 'int8') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', 127, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', -127, 'int8') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', -127, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 32767, 'int16') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', 32767, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', -32767, 'int16') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', -32767, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 2147483647, 'int32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', 2147483647, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', -2147483647, 'int32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', -2147483647, None)
import runner from pytelemetry import Pytelemetry import pytelemetry.transports.serialtransport as transports import time transport = transports.SerialTransport() telemetry = Pytelemetry(transport) app = runner.Runner(transport, telemetry) def printer(topic, data, options): if options: print(topic, '[', options['index'], "] : ", data) else: print(topic, " : ", data) options = dict() port = "COM20" bauds = 115200 app.connect(port, bauds) print("Connected.") telemetry.subscribe(None, printer) telemetry.publish('bar', 1354, 'int32') time.sleep(3) app.terminate() print("Done.")
def test_end_to_end_floats(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic", "data", "opts"]) default_cb = mock.Mock(spec=["topic", "data", "opts"]) c.subscribe('sometopic', cb) c.subscribe(None, default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 0.0, 'float32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic', 0.0, None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 3.4028234e38, 'float32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 assert abs(cb.call_args[0][1] - 3.4028234e38) <= max( 1e-7 * max(abs(cb.call_args[0][1]), abs(3.4028234e38)), 0.0) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', -3.4028234e38, 'float32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 assert abs(cb.call_args[0][1] - (-3.4028234e38)) <= max( 1e-7 * max(abs(cb.call_args[0][1]), abs(-3.4028234e38)), 0.0)
import tkinter as tk from pytelemetry import Pytelemetry import pytelemetry.transports.serialtransport as transports pressedKeys = dict() direction = 0 throttle = 0 # Configure pytelemetry transport = transports.SerialTransport() telemetry = Pytelemetry(transport) def clear(): global pressedKey global direction global throttle pressedKeys['Up'] = False pressedKeys['Down'] = False pressedKeys['Left'] = False pressedKeys['Right'] = False direction = 0 throttle = 0 def onKeyPress(event): global pressedKey pressedKeys[event.keysym] = True def onKeyRelease(event): global pressedKey pressedKeys[event.keysym] = False
def test_protocol_stats(): t = transportMock() p = Pytelemetry(t) measures = p.api.stats() assert measures["rx_decoded_frames"] == 0 assert measures["rx_corrupted_crc"] == 0 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # Add a frame inside the transport queue t.write(bytearray.fromhex("f70700666f6f0062617247027f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 0 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # replaced CRC '4702' by '4701' to corrupt crc t.write(bytearray.fromhex("f70700666f6f0062617247017f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 1 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # replaced byte n3 '00' by '10' to corrupt crc t.write(bytearray.fromhex("f70710666f6f0062617247027f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 0 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 #crc = crc16(bytearray.fromhex("0900666f6f00626172")) #print(crc) #crc = struct.pack("<H",crc) #print(crc.hex()) # Replaced header from 0700 to 0900 to corrupt it. Crc is valid to not discard t.write(bytearray.fromhex("f70900666f6f006261725fc57f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 1 assert measures["rx_corrupted_eol"] == 0 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 #crc = crc16(bytearray.fromhex("0700666f6f01626172")) #print(crc) #crc = struct.pack("<H",crc) #print(crc.hex()) # Removed EOL. Crc is valid to not discard t.write(bytearray.fromhex("f70700666f6f0162617224417f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 1 assert measures["rx_corrupted_eol"] == 1 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 0 assert measures["tx_encoded_frames"] == 0 # Impossible to detect corrupted payload of type string because length is unkown. One more reason to store framesize inside frame # Use a frame of type u32 instead #crc = crc16(bytearray.fromhex("03006b6c6d6f707100ffffff")) #crc = struct.pack("<H",crc) #print(crc.hex()) # Corruped payload by removing third & fourth hex number from end. Crc will pass # t.write(bytearray.fromhex("f703006b6c6d6f707100fffffff2dd7f")) # update to read the new frame p.update() # get measurements measures = p.api.stats() assert measures["rx_decoded_frames"] == 1 assert measures["rx_corrupted_crc"] == 2 assert measures["rx_corrupted_header"] == 1 assert measures["rx_corrupted_eol"] == 1 assert measures["rx_corrupted_topic"] == 0 assert measures["rx_corrupted_payload"] == 1 assert measures["tx_encoded_frames"] == 0 topmeasures = p.stats() assert measures["rx_decoded_frames"] == topmeasures['protocol'][ "rx_decoded_frames"] assert measures["rx_corrupted_crc"] == topmeasures['protocol'][ "rx_corrupted_crc"] assert measures["rx_corrupted_header"] == topmeasures['protocol'][ "rx_corrupted_header"] assert measures["rx_corrupted_eol"] == topmeasures['protocol'][ "rx_corrupted_eol"] assert measures["rx_corrupted_topic"] == topmeasures['protocol'][ "rx_corrupted_topic"] assert measures["rx_corrupted_payload"] == topmeasures['protocol'][ "rx_corrupted_payload"] assert measures["tx_encoded_frames"] == topmeasures['protocol'][ "tx_encoded_frames"] p.publish("boo", 123, "uint8") # get measurements measures = p.stats() assert measures['protocol']["rx_decoded_frames"] == 1 assert measures['protocol']["rx_corrupted_crc"] == 2 assert measures['protocol']["rx_corrupted_header"] == 1 assert measures['protocol']["rx_corrupted_eol"] == 1 assert measures['protocol']["rx_corrupted_topic"] == 0 assert measures['protocol']["rx_corrupted_payload"] == 1 assert measures['protocol']["tx_encoded_frames"] == 1 measures = p.api.delimiter.stats() assert measures["rx_processed_bytes"] > 0 assert measures["rx_discarded_bytes"] == 0 assert measures["rx_escaped_bytes"] == 0 assert measures["rx_complete_frames"] > 0 assert measures["rx_uncomplete_frames"] == 0 assert measures["tx_processed_bytes"] > 0 assert measures["tx_encoded_frames"] > 0 assert measures["tx_escaped_bytes"] == 0 p.resetStats() measures = p.stats() assert measures['protocol']["rx_decoded_frames"] == 0 assert measures['protocol']["rx_corrupted_crc"] == 0 assert measures['protocol']["rx_corrupted_header"] == 0 assert measures['protocol']["rx_corrupted_eol"] == 0 assert measures['protocol']["rx_corrupted_topic"] == 0 assert measures['protocol']["rx_corrupted_payload"] == 0 assert measures['protocol']["tx_encoded_frames"] == 0 assert measures['framing']["rx_processed_bytes"] == 0 assert measures['framing']["rx_discarded_bytes"] == 0 assert measures['framing']["rx_escaped_bytes"] == 0 assert measures['framing']["rx_complete_frames"] == 0 assert measures['framing']["rx_uncomplete_frames"] == 0 assert measures['framing']["tx_processed_bytes"] == 0 assert measures['framing']["tx_encoded_frames"] == 0 assert measures['framing']["tx_escaped_bytes"] == 0
def test_end_to_end_floats(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic","data","opts"]) default_cb = mock.Mock(spec=["topic","data","opts"]) c.subscribe('sometopic',cb) c.subscribe(None,default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',0.0,'float32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',0.0,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',3.4028234e38,'float32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 assert abs(cb.call_args[0][1] - 3.4028234e38) <= max(1e-7 * max(abs(cb.call_args[0][1]), abs(3.4028234e38)), 0.0) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',-3.4028234e38,'float32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 assert abs(cb.call_args[0][1] - (-3.4028234e38)) <= max(1e-7 * max(abs(cb.call_args[0][1]), abs(-3.4028234e38)), 0.0)
# --------- Import modules ---------- # from pytelemetry import Pytelemetry from pytelemetry.transports.serialtransport import * import time import socket import json # ---- Global Variables ---- # # load envVariable.json with open('./envVariable.json') as f: jsonFile = json.load(f) config = json.loads(json.dumps(jsonFile)) transport = SerialTransport() c = Pytelemetry(transport) """ * * Function Name: init_port_forward * Input: test boolean * Output: None * Logic: Initialises socket server, that communicates with js client * Example Call: int_port_forward() * """ def init_port_forward(test=False): print("starting port from server") HOST = '127.0.0.1' # Standard loopback interface address (localhost) # Port to listen on (non-privileged ports are > 1023) PORT = config["telemetrySocketPort"]
def test_end_to_end_ints(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic","data","opts"]) default_cb = mock.Mock(spec=["topic","data","opts"]) c.subscribe('sometopic',cb) c.subscribe(None,default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',127,'int8') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',127,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',-127,'int8') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',-127,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',32767,'int16') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',32767,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',-32767,'int16') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',-32767,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',2147483647,'int32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',2147483647,None) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic',-2147483647,'int32') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_with('sometopic',-2147483647,None)
class Application (cmd.Cmd): def __init__(self, transport=None, stdout=None): # cmd Initialization and configuration cmd.Cmd.__init__(self,stdout=stdout) self.intro = 'pytelemetry terminal started.' \ + ' (type help for a list of commands.)' self.prompt = ':> ' self.file = None # pytelemetry setup if not transport: self.transport = transports.SerialTransport() else: self.transport = transport self.telemetry = Pytelemetry(self.transport) self.topics = Topics() self.plots = [] self.plotsLock = Lock() self.runner = Runner(self.transport, self.telemetry, self.plots, self.plotsLock, self.topics) self.telemetry.subscribe(None,self.topics.process) self.types_lookup = {'--s' : 'string', '--u8' : 'uint8', '--u16' : 'uint16', '--u32' : 'uint32', '--i8' : 'int8', '--i16' : 'int16', '--i32' : 'int32', '--f32' : 'float32'} logger.info("Module path : %s" % os.path.dirname(os.path.realpath(__file__))) try: logger.info("Module version : %s" % __version__) except: logger.warning("Module version : not found.") def emptyline(self): pass # Override default behavior to repeat last command if empty input @docopt_cmd def do_serial(self, arg): """ List serial ports or connect to one of them. Usage: serial ((-l | --list) | <port> [options]) Options: -b X, --bauds X Connection speed in bauds [default: 9600] """ if arg['--list'] or arg['-l']: self.stdout.write("Available COM ports:\n") for port,desc,hid in list_ports.comports(): self.stdout.write("%s \t %s\n" % (port,desc)) return try: self.runner.disconnect() logger.warn("User requested connect without desconnecting first.") except (IOError,AttributeError) as e: logger.warn("Already disconnected. Continuing happily. E : {0}" .format(e)) pass self.topics.clear() logger.info("Cleared all topics for new session.") self.transport.resetStats(averaging_window=10) self.runner.resetStats() self.telemetry.resetStats() logger.info("Cleared all stats for new session.") try: b = int(arg['--bauds']) self.runner.connect(arg['<port>'],b) except IOError as e: self.stdout.write("Failed to connect to {0} at {1} (bauds).\n" .format(arg['<port>'],b)) logger.warn("Failed to connect to {0} at {1} (bauds). E : \n" .format(arg['<port>'],b,e)) else: s = "Connected to {0} at {1} (bauds).\n".format(arg['<port>'],b) self.stdout.write(s) logger.info(s) @docopt_cmd def do_print(self, arg): """ Prints X last received samples from <topic>. Usage: print <topic> [options] Options: -a, --all Display all received samples under <topic> -l X, --limit X Display X last received samples under <topic> [default: 1] """ topic = arg['<topic>'] if not self.topics.exists(topic): s = "Topic '{0}' unknown. Type 'ls' to list all available topics.\n".format(topic) self.stdout.write(s) logger.warn(s) return try: if arg['--all']: amount = 0 # 0 is understood as 'return all samples' by self.topics.samples() else: amount = int(arg['--limit']) except: s = "Could not cast --limit = '{0}' to integer. Using 1.\n".format(arg['--limit']) self.stdout.write(s) logger.warn(s) amount = 1 s = self.topics.samples(topic,amount) if s is not None: for i in s: self.stdout.write("{0}\n".format(i)) else: logger.error("Could not retrieve {0} sample(s) under topic '{1}'.\n".format(amount,topic)) @docopt_cmd def do_ls(self, arg): """ Prints available topics. Topics are basically labels under which data is available (for display, plot, etc). Data can come from remote source (a connected embedded device) or the command-line interface itself (reception speed, etc). Without flags, prints a list of remote topics. Usage: ls [options] Options: -c, --cli Prints all CLI topics. Use this to display topics for monitoring reception speed, errors amount, etc. """ if arg['--cli']: for topic in self.topics.ls(source='cli'): self.stdout.write("%s\n" % topic) return for topic in self.topics.ls(source='remote'): self.stdout.write("%s\n" % topic) @docopt_cmd def do_plot(self, arg): """ Plots <topic> in a graph window. Usage: plot <topic> """ topic = arg['<topic>'] if not self.topics.exists(topic): s = "Topic '{0}' unknown. Type 'ls' to list all available topics.\n".format(topic) self.stdout.write(s) logger.warn(s) return if self.topics.intransfer(topic): s = "Topic '{0}' already plotting.\n".format(topic) self.stdout.write(s) logger.warn(s) return has_indexes = self.topics.has_indexed_data(arg['<topic>']) if has_indexes: plotType = PlotType.indexed transferType = "indexed" else: plotType = PlotType.linear transferType = "linear" p = Superplot(topic,plotType) q, ctrl = p.start() # Protect self.plots from modifications from the runner thread self.plotsLock.acquire() self.plots.append({ 'topic': topic, 'plot': p, # Plot handler 'queue': q, # Data queue 'ctrl': ctrl # Plot control pipe }) self.plotsLock.release() self.topics.transfer(topic,q, transfer_type=transferType) s = "Plotting '{0}' in mode [{1}].\n".format(topic,transferType) logger.info(s) self.stdout.write(s) @docopt_cmd def do_pub(self, arg): """ Publishes a (value | string) on <topic>. Usage: pub (--u8 | --u16 | --u32 | --i8 | --i16 | --i32 | --f32 | --s) <topic> <value> """ if arg['--f32']: arg['<value>'] = float(arg['<value>']) elif not arg['--s']: try: arg['<value>'] = int(arg['<value>']) except: # User most likely entered a float with an integer flag inter = float(arg['<value>']) rounded = int(inter) if isclose(inter,rounded): arg['<value>'] = rounded else: s = "Aborted : Wrote decimal number ({0}) with integer flag.".format(arg['<value>']) self.stdout.write(s + "\n") logger.warning(s) return subset = {k: arg[k] for k in ("--u8","--u16","--u32","--i8","--i16","--i32","--f32","--s")} valtype = None for i, k in subset.items(): if k: valtype = self.types_lookup[i] if not valtype: logger.error( "Payload type [{0}] unkown." .format(arg)) return try: self.telemetry.publish(arg['<topic>'],arg['<value>'],valtype) except SerialTimeoutException as e: self.stdout.write("Pub failed. Connection most likely terminated.") logger.error("Pub failed. Connection most likely terminated. exception : %s" % e) return except AttributeError as e: self.stdout.write("Pub failed because you are not connected to any device. Connect first using `serial` command.") logger.warning("Trying to publish while not connected. exception : %s" % e) return s = "Published on topic '{0}' : {1} [{2}]".format(arg['<topic>'], arg['<value>'],valtype) self.stdout.write(s + "\n") logger.info(s) @docopt_cmd def do_count(self, arg): """ Prints a count of received samples for each topic. Usage: count """ for topic in self.topics.ls(): self.stdout.write("{0} : {1}\n".format(topic, self.topics.count(topic))) @docopt_cmd def do_disconnect(self, arg): """ Disconnects from any open connection. Usage: disconnect """ try: self.runner.disconnect() self.stdout.write("Disconnected.\n") logger.info("Disconnected.") measures = self.transport.stats() for key,item in measures.items(): logger.info("Raw IO : %s : %s" % (key,item)) measures = self.runner.stats() for key,item in measures.items(): logger.info("IO speeds : %s : %s" % (key,item)) measures = self.telemetry.stats() for key,item in measures['framing'].items(): logger.info("Framing : %s : %s" % (key,item)) for key,item in measures['protocol'].items(): logger.info("Protocol : %s : %s" % (key,item)) logger.info("Logged session statistics.") except: logger.warn("Already disconnected. Continuing happily.") @docopt_cmd def do_info(self, arg): """ Prints out cli.py full path, module version. Usage: info """ self.stdout.write("- CLI path : %s\n" % os.path.dirname(os.path.realpath(__file__))) try: self.stdout.write("- version : %s\n" % __version__) except: self.stdout.write("- version : not found.\n") @docopt_cmd def do_stats(self, arg): """ Displays different metrics about the active transport (ex : serial port). This allows you to know if for instance corrupted frames are received, what fraction of the maximum baudrate is being used, etc. Usage: stats """ measures = self.transport.stats() self.stdout.write("Raw IO:\n") for key,item in measures.items(): self.stdout.write("\t%s : %s\n" % (key,item)) measures = self.runner.stats() self.stdout.write("IO speeds:\n") for key,item in measures.items(): self.stdout.write("\t%s : %s\n" % (key,item)) measures = self.telemetry.stats() self.stdout.write("Framing:\n") for key,item in measures['framing'].items(): self.stdout.write("\t%s : %s\n" % (key,item)) self.stdout.write("Protocol:\n") for key,item in measures['protocol'].items(): self.stdout.write("\t%s : %s\n" % (key,item)) def do_quit(self, arg): """ Exits the terminal application. Usage: quit """ self.runner.terminate() self.do_disconnect("") self.stdout.write("Good Bye!\n") logger.info("Application quit.") exit()
import runner from pytelemetry import Pytelemetry import pytelemetry.transports.serialtransport as transports import time transport = transports.SerialTransport() telemetry = Pytelemetry(transport) app = runner.Runner(transport,telemetry) def printer(topic, data, options): if options: print(topic,'[',options['index'],"] : ", data) else: print(topic," : ", data) options = dict() port = "COM20" bauds = 115200 app.connect(port,bauds) print("Connected.") telemetry.subscribe(None, printer) telemetry.publish('bar',1354,'int32') time.sleep(3) app.terminate() print("Done.")
def test_end_to_end_string(): # Setup t = transportMock() c = Pytelemetry(t) cb = mock.Mock(spec=["topic", "data", "opts"]) default_cb = mock.Mock(spec=["topic", "data", "opts"]) c.subscribe('sometopic', cb) c.subscribe(None, default_cb) # testing callback subscribed to topic assert t.queue.qsize() == 0 c.publish('sometopic', 'someMessage', 'string') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 cb.assert_called_once_with('sometopic', 'someMessage', None) # test default callback c.publish('othertopic', 'otherMessage', 'string') assert t.queue.qsize() > 0 c.update() assert t.queue.qsize() == 0 default_cb.assert_called_once_with('othertopic', 'otherMessage', None)