live ##ˆl–äY>”Êe¶¥¸ ¸î4ò˜´oÎ ƒ|kÍÀÐ#@##! python # # This module implements a special URL handler that wraps an other port, # print the traffic for debugging purposes. With this, it is possible # to debug the serial port traffic on every application that uses # serial_for_url. # # This file is part of pySerial. https://github.com/pyserial/pyserial # (C) 2015 Chris Liechti # # SPDX-License-Identifier: BSD-3-Clause # # URL format: spy://port[?option[=value][&option[=value]]] # options: # - dev=X a file or device to write to # - color use escape code to colorize output # - raw forward raw bytes instead of hexdump # # example: # redirect output to an other terminal window on Posix (Linux): # python -m serial.tools.miniterm spy:///dev/ttyUSB0?dev=/dev/pts/14\&color import sys import time import serial try: import urlparse except ImportError: import urllib.parse as urlparse def sixteen(data): """\ yield tuples of hex and ASCII display in multiples of 16. Includes a space after 8 bytes and (None, None) after 16 bytes and at the end. """ n = 0 for b in serial.iterbytes(data): yield ('{:02X} '.format(ord(b)), b.decode('ascii') if b' ' <= b < b'\x7f' else '.') n += 1 if n == 8: yield (' ', '') elif n >= 16: yield (None, None) n = 0 if n > 0: while n < 16: n += 1 if n == 8: yield (' ', '') yield (' ', ' ') yield (None, None) def hexdump(data): """yield lines with hexdump of data""" values = [] ascii = [] offset = 0 for h, a in sixteen(data): if h is None: yield (offset, ' '.join([''.join(values), ''.join(ascii)])) del values[:] del ascii[:] offset += 0x10 else: values.append(h) ascii.append(a) class FormatRaw(object): """Forward only RX and TX data to output.""" def __init__(self, output, color): self.output = output self.color = color self.rx_color = '\x1b[32m' self.tx_color = '\x1b[31m' def rx(self, data): """show received data""" if self.color: self.output.write(self.rx_color) self.output.write(data) self.output.flush() def tx(self, data): """show transmitted data""" if self.color: self.output.write(self.tx_color) self.output.write(data) self.output.flush() def control(self, name, value): """(do not) show control calls""" pass class FormatHexdump(object): """\ Create a hex dump of RX ad TX data, show when control lines are read or written. output example:: 000000.000 Q-RX flushInput 000002.469 RTS inactive 000002.773 RTS active 000003.001 TX 48 45 4C 4C 4F HELLO 000003.102 RX 48 45 4C 4C 4F HELLO """ def __init__(self, output, color): self.start_time = time.time() self.output = output self.color = color self.rx_color = '\x1b[32m' self.tx_color = '\x1b[31m' self.control_color = '\x1b[37m' def write_line(self, timestamp, label, value, value2=''): self.output.write('{:010.3f} {:4} {}{}\n'.format(timestamp, label, value, value2)) self.output.flush() def rx(self, data): """show received data as hex dump""" if self.color: self.output.write(self.rx_color) if data: for offset, row in hexdump(data): self.write_line(time.time() - self.start_time, 'RX', '{:04X} '.format(offset), row) else: self.write_line(time.time() - self.start_time, 'RX', '') def tx(self, data): """show transmitted data as hex dump""" if self.color: self.output.write(self.tx_color) for offset, row in hexdump(data):