Package: discotool
DiscoToolModule and tool to discover all boards connected to USB.InstallingThediscotoolcommand line program and thediscotoolpython module for python 3 can be installed with pip.python3 -m pip install discotoolCompatibilityIt currently runs on MacOS, Linux and Windows. It should not require any installation outside of pip dependencies (no libusb, etc.). If it doesn't work for you, an issue with relevant OS information is welcome.discotool CLI toolWhen runningdiscotoolwhile using a single board, it will be automatically selected for commands. These are the commands I use the most:discotool repl: to connect to the REPL.discotool install ...: to install modules via circup.discotool update: to update modules via circup.I often have more than one board connected, and connect to the REPL usingdiscotool -n picofor example, or using the drive (mount) name to give each board a personnal namediscotool -m picotwo.I also use a command to back up all connected boards.alias cpbackups='discotool backup --date ~/Backups/CPBackups'ConfigurationDefine environment variables to override the default command line tools used by discotool. They are called by appending the relevant parameters at the end of the command, or replacing a placeholder.DISCOTOOL_SERIALTOOL: command to connect to the REPL (tio, picocom, etc.), adds the port at the end or replaces{port}if present.on windows{portnum}is the6inCOM6, required by TeraTerm.default values, using the first one found:TeraTermPro,PuTTYon Windows.tio,screenon linux/mac.DISCOTOOL_CIRCUP: (circup) command to call circup (pip installit for the default).DISCOTOOL_NOCOLOR: disables colors in the output if it evaluates to True.Command line options--wait: runs the scan every second until it detects a board.--nocolor: do not output colors in the terminal (overrides all else).--color: output colors in the terminal (overrides all else).--info: add more informations on Circuitpython boards by scanning the drive's content (might trigger the autoreload).No Commandif no filter is given, run thelistcommand.if filters are given, run thereplcommand.FiltersFilters select boards from the list of devices found to run a command on them. They are combined with OR logic: anything that matches any filter is selected. All filters are NOT case sensitive. Filters are simple text matches, they don't support wildcards.--auto: select the first board found.--name: search in the USB name/description field. Eg: "clue", "QT", "S2".--serial: search the serial number of the board.--mount: search the volume names of the board. Eg: "CIRCUITPY".Commandslist: lists the selected boards, with name, manufacturer, serial number. Lists the serial ports and file volumes. If the--infooption was given, identifies circuitpython code files present, as well as CPY version. On windows the name of the drive is listed in addition to the drive letter.repl: connect to the REPL of the selected boards using the tool specified, screen by default, choosing the first serial port found if there is more than one.eject: eject all selected board drives, or all found if no filter given. (MacOS only for now)backup <destination dir> [<sub dir>]: copy the content of the selected boards drives into the destination dir or the optional sub dir (that will be created for you). Each board is put in a directory with its name and serial number.--create: create the destination dir if it does not exist.--date: use a time stamp as subdirectory name, or add to the supplied name.circup <options>: calls circup with its--pathoption to each selected board and passes all other options and commands to it.get <key>: print just the value for the key, for the selected devices. Can be used with backticks and such in a shell script. Includes special keys:pid,vid,sn: shortcuts for product_id, vendor_id and serial_num.volume: path to the (first) mounted drive of the device.port: (first) serial port of the device.repl: (first) REPL serial port of the device.cdc: (first) non-REPL serial port of the device.mainorcode.py: full path to the main file for circuitpython.json: print the output of usbinfo as json for all selected boards.--pretty-p: pretty print it for human reading.ModuleExposes theget_identified_devices(drive_info=False)function. Find boards on the host's USB bus and tries to match them with serial ports and mounted drives, virtual or not. Ifdrive_infois True, when a drive is found, it reads circuitpython information if available: CPY version number and main files in order of priority (code.py, etc.). This might trigger the board's autoreload.importdiscotooldevicesList=discotool.get_identified_devices(drive_info=True)Devices list (MacOS)[{'manufacturer':'Adafruit Industries LLC','name':'CLUE nRF52840 Express','ports':[{"dev":"'/dev/cu.usbmodem144443111'","iface":"CircuitPython CDC data"}],'product_id':32882,'serial_num':'F88EE0399C0E1FC6','vendor_id':9114,'version':'6.0.1','volumes':[{'mains':['code.py'],'mount_point':'/Volumes/CIRCUITPY','name':'CIRCUITPY'}],'usb_location':'0x14630000'}]Other functions of the moduleget_devices_list(drive_info=False): return a tuple of the devices list and the list of remaining unidentified serial ports(devicesList, remainingPorts).get_identified_devices(drive_info=False): only return the devices list.get_unidentified_ports(): only return the unidentified serial ports.devices_by_name(name): only return the devices where the name contains the given string (not case sensitive).devices_by_drive(drive_name): only return the devices where the drive name (by default CIRCUITPY) is the given string.devices_by_serial(serial_number): only return the devices where the serial number is the given string (not case sensitive).The DeviceInfoDict classThe device list is actually a list of DeviceInfoDict, a subclass of dictionary that adds a few properties as shortcuts for paths in the dictionary, with a default value ofNone.Dictionary entries:name: USB name of the board (str).manufacturer: USB manufacturer of the board (str).product_id: USB Product ID (int).vendor_id: USB Vendor ID (int).serial_num: USB Serial number of the board (str).version: Circuitpython version, if found.ports: list of serial ports found on the board, dictionaries.dev: port device, used to connect to the port. COM port on windows, dev path on linux (str).iface: interface name for the serial port (str).volumes: list of mounted drives from the board, dictionaries.name: drive name, usuallyCIRCUITPYfor Circuitpython or*BOOTfor a UF2 bootloader drive (str).mount_point: mount path of the drive, letter on windows (str).mains: list of "main" files for Circuitpython (code.py etc.), by order of priority.usb_location: an identifier for the USB port the board is connected to, should be consistent across reboots and modes (bootloader/application).Shortcuts:repl: REPL port, if any.data: data port, if any.driveandvolume: board drive path.volume_name: board drive name.vid: shortcut forvendor_id.pid: shortcut forproduct_id.Screenshots:Using tio:discotool -n cluediscotool -n clue circup updateSamples of what output you can expect from some boards.