From 91345c0bddc197a0be521f43a681481025fbb20b Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 6 Nov 2015 19:54:15 +0200 Subject: [PATCH] Add support for pySerial 3.0 // Resolve #307 --- HISTORY.rst | 2 + docs/userguide/cmd_serialports.rst | 94 ++++++++++++----- platformio/__init__.py | 2 +- platformio/commands/serialports.py | 160 ++++++++++++++++++++--------- setup.py | 2 +- 5 files changed, 186 insertions(+), 74 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 4ef2999b..d6a7c3c1 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -12,6 +12,8 @@ PlatformIO 2.0 (`issue #309 `_) * Added support for Espressif ESP8266 ESP-12E board (NodeMCU) (`issue #310 `_) +* Added support for pySerial 3.0 + (`issue #307 `_) * Upload firmware using external programmer via `platformio run --target program `__ target (`issue #311 `_) diff --git a/docs/userguide/cmd_serialports.rst b/docs/userguide/cmd_serialports.rst index 53bae993..dbaf5860 100644 --- a/docs/userguide/cmd_serialports.rst +++ b/docs/userguide/cmd_serialports.rst @@ -140,30 +140,41 @@ Set initial ``RTS`` line state, default ``0`` Set initial ``DTR`` line state, default ``0`` .. option:: - --echo + --encoding -Enable local echo, default ``Off`` +Set the encoding for the serial port (e.g. ``hexlify``, ``Latin1``, ``UTF-8``), +default ``UTF-8``. + +**NEW**: Available in Miniterm/PySerial 3.0 .. option:: - --cr + -f, --filter -Do not send ``CR+LF``, send ``R`` only, default ``Off`` +Add text transformation. Available filters: + +* ``colorize`` Apply different colors for received and echo +* ``debug`` Print what is sent and received +* ``default`` Remove typical terminal control codes from input +* ``direct`` Do-nothing: forward all data unchanged +* ``nocontrol`` Remove all control codes, incl. CR+LF +* ``printable`` Show decimal code for all non-ASCII characters and replace + most control codes + +**NEW**: Available in Miniterm/PySerial 3.0 .. option:: - --lf + --eol -Do not send ``CR+LF``, send ``LF`` only, default ``Off`` +End of line mode (``CR``, ``LF`` or ``CRLF``), default ``CRLF`` + +**NEW**: Available in Miniterm/PySerial 3.0 .. option:: - -d, --debug + --raw -Debug received data (escape non-printable chars). ``--debug`` can be given -multiple times: +Do not apply any encodings/transformations -0. just print what is received -1. escape non-printable characters, do newlines as unusual -2. escape non-printable characters, newlines too -3. hex dump everything +**NEW**: Available in Miniterm/PySerial 3.0 .. option:: --exit-char @@ -182,6 +193,43 @@ default ``0x14`` Diagnostics: suppress non-error messages, default ``Off`` + +.. option:: + --echo + +Enable local echo, default ``Off`` + +**REMOVED**: Is not available in Miniterm/PySerial 3.0 + +.. option:: + --cr + +Do not send ``CR+LF``, send ``R`` only, default ``Off`` + +**REMOVED**: Is not available in Miniterm/PySerial 3.0 + +.. option:: + --lf + +Do not send ``CR+LF``, send ``LF`` only, default ``Off`` + +**REMOVED**: Is not available in Miniterm/PySerial 3.0 + +.. option:: + -d, --debug + +Debug received data (escape non-printable chars). ``--debug`` can be given +multiple times: + +0. just print what is received +1. escape non-printable characters, do newlines as unusual +2. escape non-printable characters, newlines too +3. hex dump everything + +**REMOVED**: Is not available in Miniterm/PySerial 3.0. +See :option:`platformio serialports monitor --encoding` and +:option:`platformio serialports monitor --filter` options. + Examples ~~~~~~~~ @@ -201,21 +249,17 @@ Examples --rts [0|1] Set initial RTS line state, default=0 --dtr [0|1] Set initial DTR line state, default=0 --echo Enable local echo, default=Off - --cr Do not send CR+LF, send CR only, default=Off - --lf Do not send CR+LF, send LF only, default=Off - -d, --debug Debug received data (escape non-printable chars) - --debug can be given multiple times: - 0: just print what is received - 1: escape non-printable characters, do newlines as - unusual - 2: escape non-printable characters, newlines too - 3: hex dump everything + --encoding TEXT Set the encoding for the serial port (e.g. hexlify, + Latin1, UTF-8), default: UTF-8 + -f, --filter TEXT Add text transformation + --eol [CR|LF|CRLF] End of line mode, default=CRLF + --raw Do not apply any encodings/transformations --exit-char INTEGER ASCII code of special character that is used to exit - the application, default=0x1d + the application, default=29 (DEC) --menu-char INTEGER ASCII code of special character that is used to - control miniterm (menu), default=0x14 + control miniterm (menu), default=20 (DEC) --quiet Diagnostics: suppress non-error messages, default=Off - --help Show this message and exit. + -h, --help Show this message and exit. 2. Communicate with serial device and print help inside terminal diff --git a/platformio/__init__.py b/platformio/__init__.py index 28c8e0d0..61af9363 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -1,7 +1,7 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -VERSION = (2, 4, "0.dev1") +VERSION = (2, 4, "0.dev2") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/commands/serialports.py b/platformio/commands/serialports.py index f4232a1b..a1a89881 100644 --- a/platformio/commands/serialports.py +++ b/platformio/commands/serialports.py @@ -5,6 +5,7 @@ import json import sys import click +from serial import VERSION as PYSERIAL_VERSION from serial.tools import miniterm from platformio import app @@ -33,52 +34,117 @@ def serialports_list(json_output): click.echo("") -@cli.command("monitor", short_help="Monitor Serial port") -@click.option("--port", "-p", help="Port, a number or a device name") -@click.option("--baud", "-b", type=int, default=9600, - help="Set baud rate, default=9600") -@click.option("--parity", default="N", - type=click.Choice(["N", "E", "O", "S", "M"]), - help="Set parity, default=N") -@click.option("--rtscts", is_flag=True, - help="Enable RTS/CTS flow control, default=Off") -@click.option("--xonxoff", is_flag=True, - help="Enable software flow control, default=Off") -@click.option("--rts", default="0", type=click.Choice(["0", "1"]), - help="Set initial RTS line state, default=0") -@click.option("--dtr", default="0", type=click.Choice(["0", "1"]), - help="Set initial DTR line state, default=0") -@click.option("--echo", is_flag=True, - help="Enable local echo, default=Off") -@click.option("--cr", is_flag=True, - help="Do not send CR+LF, send CR only, default=Off") -@click.option("--lf", is_flag=True, - help="Do not send CR+LF, send LF only, default=Off") -@click.option("--debug", "-d", count=True, - help="""Debug received data (escape non-printable chars) -# --debug can be given multiple times: -# 0: just print what is received -# 1: escape non-printable characters, do newlines as unusual -# 2: escape non-printable characters, newlines too -# 3: hex dump everything""") -@click.option("--exit-char", type=int, default=29, - help="ASCII code of special character that is used to exit the " - "application, default=19 (DEC)") -@click.option("--menu-char", type=int, default=20, - help="ASCII code of special character that is used to control " - "miniterm (menu), default=20 (DEC)") -@click.option("--quiet", is_flag=True, - help="Diagnostics: suppress non-error messages, default=Off") -def serialports_monitor(**kwargs): - sys.argv = app.get_session_var("command_ctx").args[1:] +if int(PYSERIAL_VERSION[0]) == 3: + @cli.command("monitor", short_help="Monitor Serial port") + @click.option("--port", "-p", help="Port, a number or a device name") + @click.option("--baud", "-b", type=int, default=9600, + help="Set baud rate, default=9600") + @click.option("--parity", default="N", + type=click.Choice(["N", "E", "O", "S", "M"]), + help="Set parity, default=N") + @click.option("--rtscts", is_flag=True, + help="Enable RTS/CTS flow control, default=Off") + @click.option("--xonxoff", is_flag=True, + help="Enable software flow control, default=Off") + @click.option("--rts", default="0", type=click.Choice(["0", "1"]), + help="Set initial RTS line state, default=0") + @click.option("--dtr", default="0", type=click.Choice(["0", "1"]), + help="Set initial DTR line state, default=0") + @click.option("--encoding", default="UTF-8", + help="Set the encoding for the serial port (e.g. hexlify, " + "Latin1, UTF-8), default: UTF-8") + @click.option("--filter", "-f", multiple=True, + help="Add text transformation") + @click.option("--eol", default="CRLF", + type=click.Choice(["CR", "LF", "CRLF"]), + help="End of line mode, default=CRLF") + @click.option("--raw", is_flag=True, + help="Do not apply any encodings/transformations") + @click.option("--exit-char", type=int, default=29, + help="ASCII code of special character that is used to exit " + "the application, default=29 (DEC)") + @click.option("--menu-char", type=int, default=20, + help="ASCII code of special character that is used to " + "control miniterm (menu), default=20 (DEC)") + @click.option("--quiet", is_flag=True, + help="Diagnostics: suppress non-error messages, default=Off") + def serialports_monitor(**kwargs): + if not kwargs['port']: + for item in get_serialports(): + if "VID:PID" in item['hwid']: + kwargs['port'] = item['port'] + break - if not kwargs['port']: - for item in get_serialports(): - if "VID:PID" in item['hwid']: - sys.argv += ["--port", item['port']] - break + sys.argv = ["monitor"] + for k, v in kwargs.iteritems(): + if k in ("port", "baud", "rts", "dtr"): + continue + k = "--" + k.replace("_", "-") + if isinstance(v, bool): + if v: + sys.argv.append(k) + elif isinstance(v, tuple): + for i in v: + sys.argv.extend([k, i]) + else: + sys.argv.extend([k, str(v)]) - try: - miniterm.main() - except Exception as e: # pylint: disable=W0702 - raise MinitermException(e) + try: + miniterm.main( # pylint: disable=E1123 + default_port=kwargs['port'], + default_baudrate=kwargs['baud'], + default_rts=kwargs['rts'], + default_dtr=kwargs['dtr'] + ) + except Exception as e: # pylint: disable=W0702 + raise MinitermException(e) +else: + @cli.command("monitor", short_help="Monitor Serial port") + @click.option("--port", "-p", help="Port, a number or a device name") + @click.option("--baud", "-b", type=int, default=9600, + help="Set baud rate, default=9600") + @click.option("--parity", default="N", + type=click.Choice(["N", "E", "O", "S", "M"]), + help="Set parity, default=N") + @click.option("--rtscts", is_flag=True, + help="Enable RTS/CTS flow control, default=Off") + @click.option("--xonxoff", is_flag=True, + help="Enable software flow control, default=Off") + @click.option("--rts", default="0", type=click.Choice(["0", "1"]), + help="Set initial RTS line state, default=0") + @click.option("--dtr", default="0", type=click.Choice(["0", "1"]), + help="Set initial DTR line state, default=0") + @click.option("--echo", is_flag=True, + help="Enable local echo, default=Off") + @click.option("--cr", is_flag=True, + help="Do not send CR+LF, send CR only, default=Off") + @click.option("--lf", is_flag=True, + help="Do not send CR+LF, send LF only, default=Off") + @click.option("--debug", "-d", count=True, + help="""Debug received data (escape non-printable chars) + # --debug can be given multiple times: + # 0: just print what is received + # 1: escape non-printable characters, do newlines as unusual + # 2: escape non-printable characters, newlines too + # 3: hex dump everything""") + @click.option("--exit-char", type=int, default=29, + help="ASCII code of special character that is used to exit " + "the application, default=29 (DEC)") + @click.option("--menu-char", type=int, default=20, + help="ASCII code of special character that is used to " + "control miniterm (menu), default=20 (DEC)") + @click.option("--quiet", is_flag=True, + help="Diagnostics: suppress non-error messages, default=Off") + def serialports_monitor(**kwargs): + sys.argv = app.get_session_var("command_ctx").args[1:] + + if not kwargs['port']: + for item in get_serialports(): + if "VID:PID" in item['hwid']: + sys.argv += ["--port", item['port']] + break + + try: + miniterm.main() + except Exception as e: # pylint: disable=W0702 + raise MinitermException(e) diff --git a/setup.py b/setup.py index 35d674df..1b9a8f48 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ install_requires = [ "bottle", "click>=3.2", "lockfile>=0.9.1", - "pyserial<3", + "pyserial", "requests>=2.4.0" ]