diff --git a/HISTORY.rst b/HISTORY.rst index 5df3557d..1f087ab7 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -23,6 +23,7 @@ PlatformIO Core 4.0 * Added support for "pythonPackages" in `platform.json `__ manifest (PlatformIO Package Manager will install dependent Python packages from PyPi registry automatically when dev-platform is installed) * Handle project configuration (monitor, test, and upload options) for PIO Remote commands (`issue #2591 `_) * Added support for Arduino's library.properties ``depends`` field (`issue #2781 `_) +* Autodetect monitor port for boards with specified HWIDs (`issue #3349 `_) * Updated SCons tool to 3.1.2 * Updated Unity tool to 2.5.0 * Made package ManifestSchema compatible with marshmallow >= 3 (`issue #3296 `_) diff --git a/platformio/commands/device.py b/platformio/commands/device.py index 72c7ee8e..24e7d3ca 100644 --- a/platformio/commands/device.py +++ b/platformio/commands/device.py @@ -21,6 +21,7 @@ from serial.tools import miniterm from platformio import exception, fs, util from platformio.compat import dump_json_to_unicode +from platformio.managers.platform import PlatformFactory from platformio.project.config import ProjectConfig from platformio.project.exception import NotPlatformIOProjectError @@ -189,6 +190,20 @@ def device_monitor(**kwargs): # pylint: disable=too-many-branches ports = util.get_serial_ports(filter_hwid=True) if len(ports) == 1: kwargs["port"] = ports[0]["port"] + elif "platform" in project_options and "board" in project_options: + board_hwids = get_board_hwids( + kwargs["project_dir"], + project_options["platform"], + project_options["board"], + ) + for item in ports: + for hwid in board_hwids: + hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "") + if hwid_str in item["hwid"]: + kwargs["port"] = item["port"] + break + if kwargs["port"]: + break elif kwargs["port"] and (set(["*", "?", "[", "]"]) & set(kwargs["port"])): for item in util.get_serial_ports(): if fnmatch(item["port"], kwargs["port"]): @@ -254,3 +269,12 @@ def get_project_options(environment=None): else: environment = config.envs()[0] return config.items(env=environment, as_dict=True) + + +def get_board_hwids(project_dir, platform, board): + with fs.cd(project_dir): + return ( + PlatformFactory.newPlatform(platform) + .board_config(board) + .get("build.hwids", []) + )