mirror of
				https://github.com/mfulz/qmk_firmware.git
				synced 2025-10-31 05:12:33 +01:00 
			
		
		
		
	remove qmk console, which is now part of the global cli (#14206)
This commit is contained in:
		
							parent
							
								
									1ac3b3e9b6
								
							
						
					
					
						commit
						f155865804
					
				| @ -118,54 +118,6 @@ This command lets you configure the behavior of QMK. For the full `qmk config` d | |||||||
| qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] | qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## `qmk console` |  | ||||||
| 
 |  | ||||||
| This command lets you connect to keyboard consoles to get debugging messages. It only works if your keyboard firmware has been compiled with `CONSOLE_ENABLE=yes`. |  | ||||||
| 
 |  | ||||||
| **Usage**: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| qmk console [-d <pid>:<vid>[:<index>]] [-l] [-n] [-t] [-w <seconds>] |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| **Examples**: |  | ||||||
| 
 |  | ||||||
| Connect to all available keyboards and show their console messages: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| qmk console |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| List all devices: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| qmk console -l |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Show only messages from clueboard/66/rev3 keyboards: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| qmk console -d C1ED:2370 |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Show only messages from the second clueboard/66/rev3: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| qmk console -d C1ED:2370:2 |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Show timestamps and VID:PID instead of names: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| qmk console -n -t |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| Disable bootloader messages: |  | ||||||
| 
 |  | ||||||
| ``` |  | ||||||
| qmk console --no-bootloaders |  | ||||||
| ``` |  | ||||||
| 
 |  | ||||||
| ## `qmk doctor` | ## `qmk doctor` | ||||||
| 
 | 
 | ||||||
| This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to. | This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to. | ||||||
|  | |||||||
| @ -35,7 +35,6 @@ subcommands = [ | |||||||
|     'qmk.cli.chibios.confmigrate', |     'qmk.cli.chibios.confmigrate', | ||||||
|     'qmk.cli.clean', |     'qmk.cli.clean', | ||||||
|     'qmk.cli.compile', |     'qmk.cli.compile', | ||||||
|     'qmk.cli.console', |  | ||||||
|     'qmk.cli.docs', |     'qmk.cli.docs', | ||||||
|     'qmk.cli.doctor', |     'qmk.cli.doctor', | ||||||
|     'qmk.cli.fileformat', |     'qmk.cli.fileformat', | ||||||
|  | |||||||
| @ -1,303 +0,0 @@ | |||||||
| """Acquire debugging information from usb hid devices |  | ||||||
| 
 |  | ||||||
| cli implementation of https://www.pjrc.com/teensy/hid_listen.html |  | ||||||
| """ |  | ||||||
| from pathlib import Path |  | ||||||
| from threading import Thread |  | ||||||
| from time import sleep, strftime |  | ||||||
| 
 |  | ||||||
| import hid |  | ||||||
| import usb.core |  | ||||||
| 
 |  | ||||||
| from milc import cli |  | ||||||
| 
 |  | ||||||
| LOG_COLOR = { |  | ||||||
|     'next': 0, |  | ||||||
|     'colors': [ |  | ||||||
|         '{fg_blue}', |  | ||||||
|         '{fg_cyan}', |  | ||||||
|         '{fg_green}', |  | ||||||
|         '{fg_magenta}', |  | ||||||
|         '{fg_red}', |  | ||||||
|         '{fg_yellow}', |  | ||||||
|     ], |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| KNOWN_BOOTLOADERS = { |  | ||||||
|     # VID  ,  PID |  | ||||||
|     ('03EB', '2FEF'): 'atmel-dfu: ATmega16U2', |  | ||||||
|     ('03EB', '2FF0'): 'atmel-dfu: ATmega32U2', |  | ||||||
|     ('03EB', '2FF3'): 'atmel-dfu: ATmega16U4', |  | ||||||
|     ('03EB', '2FF4'): 'atmel-dfu: ATmega32U4', |  | ||||||
|     ('03EB', '2FF9'): 'atmel-dfu: AT90USB64', |  | ||||||
|     ('03EB', '2FFA'): 'atmel-dfu: AT90USB162', |  | ||||||
|     ('03EB', '2FFB'): 'atmel-dfu: AT90USB128', |  | ||||||
|     ('03EB', '6124'): 'Microchip SAM-BA', |  | ||||||
|     ('0483', 'DF11'): 'stm32-dfu: STM32 BOOTLOADER', |  | ||||||
|     ('16C0', '05DC'): 'USBasp: USBaspLoader', |  | ||||||
|     ('16C0', '05DF'): 'bootloadHID: HIDBoot', |  | ||||||
|     ('16C0', '0478'): 'halfkay: Teensy Halfkay', |  | ||||||
|     ('1B4F', '9203'): 'caterina: Pro Micro 3.3V', |  | ||||||
|     ('1B4F', '9205'): 'caterina: Pro Micro 5V', |  | ||||||
|     ('1B4F', '9207'): 'caterina: LilyPadUSB', |  | ||||||
|     ('1C11', 'B007'): 'kiibohd: Kiibohd DFU Bootloader', |  | ||||||
|     ('1EAF', '0003'): 'stm32duino: Maple 003', |  | ||||||
|     ('1FFB', '0101'): 'caterina: Polou A-Star 32U4 Bootloader', |  | ||||||
|     ('2341', '0036'): 'caterina: Arduino Leonardo', |  | ||||||
|     ('2341', '0037'): 'caterina: Arduino Micro', |  | ||||||
|     ('239A', '000C'): 'caterina: Adafruit Feather 32U4', |  | ||||||
|     ('239A', '000D'): 'caterina: Adafruit ItsyBitsy 32U4 3v', |  | ||||||
|     ('239A', '000E'): 'caterina: Adafruit ItsyBitsy 32U4 5v', |  | ||||||
|     ('2A03', '0036'): 'caterina: Arduino Leonardo', |  | ||||||
|     ('2A03', '0037'): 'caterina: Arduino Micro', |  | ||||||
|     ('314B', '0106'): 'apm32-dfu: APM32 DFU ISP Mode', |  | ||||||
|     ('03EB', '2067'): 'qmk-hid: HID Bootloader', |  | ||||||
|     ('03EB', '2045'): 'lufa-ms: LUFA Mass Storage Bootloader' |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class MonitorDevice(object): |  | ||||||
|     def __init__(self, hid_device, numeric): |  | ||||||
|         self.hid_device = hid_device |  | ||||||
|         self.numeric = numeric |  | ||||||
|         self.device = hid.Device(path=hid_device['path']) |  | ||||||
|         self.current_line = '' |  | ||||||
| 
 |  | ||||||
|         cli.log.info('Console Connected: %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all})', hid_device) |  | ||||||
| 
 |  | ||||||
|     def read(self, size, encoding='ascii', timeout=1): |  | ||||||
|         """Read size bytes from the device. |  | ||||||
|         """ |  | ||||||
|         return self.device.read(size, timeout).decode(encoding) |  | ||||||
| 
 |  | ||||||
|     def read_line(self): |  | ||||||
|         """Read from the device's console until we get a \n. |  | ||||||
|         """ |  | ||||||
|         while '\n' not in self.current_line: |  | ||||||
|             self.current_line += self.read(32).replace('\x00', '') |  | ||||||
| 
 |  | ||||||
|         lines = self.current_line.split('\n', 1) |  | ||||||
|         self.current_line = lines[1] |  | ||||||
| 
 |  | ||||||
|         return lines[0] |  | ||||||
| 
 |  | ||||||
|     def run_forever(self): |  | ||||||
|         while True: |  | ||||||
|             try: |  | ||||||
|                 message = {**self.hid_device, 'text': self.read_line()} |  | ||||||
|                 identifier = (int2hex(message['vendor_id']), int2hex(message['product_id'])) if self.numeric else (message['manufacturer_string'], message['product_string']) |  | ||||||
|                 message['identifier'] = ':'.join(identifier) |  | ||||||
|                 message['ts'] = '{style_dim}{fg_green}%s{style_reset_all} ' % (strftime(cli.config.general.datetime_fmt),) if cli.args.timestamp else '' |  | ||||||
| 
 |  | ||||||
|                 cli.echo('%(ts)s%(color)s%(identifier)s:%(index)d{style_reset_all}: %(text)s' % message) |  | ||||||
| 
 |  | ||||||
|             except hid.HIDException: |  | ||||||
|                 break |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class FindDevices(object): |  | ||||||
|     def __init__(self, vid, pid, index, numeric): |  | ||||||
|         self.vid = vid |  | ||||||
|         self.pid = pid |  | ||||||
|         self.index = index |  | ||||||
|         self.numeric = numeric |  | ||||||
| 
 |  | ||||||
|     def run_forever(self): |  | ||||||
|         """Process messages from our queue in a loop. |  | ||||||
|         """ |  | ||||||
|         live_devices = {} |  | ||||||
|         live_bootloaders = {} |  | ||||||
| 
 |  | ||||||
|         while True: |  | ||||||
|             try: |  | ||||||
|                 for device in list(live_devices): |  | ||||||
|                     if not live_devices[device]['thread'].is_alive(): |  | ||||||
|                         cli.log.info('Console Disconnected: %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s%(vendor_id)04X:%(product_id)04X:%(index)d{style_reset_all})', live_devices[device]) |  | ||||||
|                         del live_devices[device] |  | ||||||
| 
 |  | ||||||
|                 for device in self.find_devices(): |  | ||||||
|                     if device['path'] not in live_devices: |  | ||||||
|                         device['color'] = LOG_COLOR['colors'][LOG_COLOR['next']] |  | ||||||
|                         LOG_COLOR['next'] = (LOG_COLOR['next'] + 1) % len(LOG_COLOR['colors']) |  | ||||||
|                         live_devices[device['path']] = device |  | ||||||
| 
 |  | ||||||
|                         try: |  | ||||||
|                             monitor = MonitorDevice(device, self.numeric) |  | ||||||
|                             device['thread'] = Thread(target=monitor.run_forever, daemon=True) |  | ||||||
| 
 |  | ||||||
|                             device['thread'].start() |  | ||||||
|                         except Exception as e: |  | ||||||
|                             device['e'] = e |  | ||||||
|                             device['e_name'] = e.__class__.__name__ |  | ||||||
|                             cli.log.error("Could not connect to %(color)s%(manufacturer_string)s %(product_string)s{style_reset_all} (%(color)s:%(vendor_id)04X:%(product_id)04X:%(index)d): %(e_name)s: %(e)s", device) |  | ||||||
|                             if cli.config.general.verbose: |  | ||||||
|                                 cli.log.exception(e) |  | ||||||
|                             del live_devices[device['path']] |  | ||||||
| 
 |  | ||||||
|                 if cli.args.bootloaders: |  | ||||||
|                     for device in self.find_bootloaders(): |  | ||||||
|                         if device.address in live_bootloaders: |  | ||||||
|                             live_bootloaders[device.address]._qmk_found = True |  | ||||||
|                         else: |  | ||||||
|                             name = KNOWN_BOOTLOADERS[(int2hex(device.idVendor), int2hex(device.idProduct))] |  | ||||||
|                             cli.log.info('Bootloader Connected: {style_bright}{fg_magenta}%s', name) |  | ||||||
|                             device._qmk_found = True |  | ||||||
|                             live_bootloaders[device.address] = device |  | ||||||
| 
 |  | ||||||
|                     for device in list(live_bootloaders): |  | ||||||
|                         if live_bootloaders[device]._qmk_found: |  | ||||||
|                             live_bootloaders[device]._qmk_found = False |  | ||||||
|                         else: |  | ||||||
|                             name = KNOWN_BOOTLOADERS[(int2hex(live_bootloaders[device].idVendor), int2hex(live_bootloaders[device].idProduct))] |  | ||||||
|                             cli.log.info('Bootloader Disconnected: {style_bright}{fg_magenta}%s', name) |  | ||||||
|                             del live_bootloaders[device] |  | ||||||
| 
 |  | ||||||
|                 sleep(.1) |  | ||||||
| 
 |  | ||||||
|             except KeyboardInterrupt: |  | ||||||
|                 break |  | ||||||
| 
 |  | ||||||
|     def is_bootloader(self, hid_device): |  | ||||||
|         """Returns true if the device in question matches a known bootloader vid/pid. |  | ||||||
|         """ |  | ||||||
|         return (int2hex(hid_device.idVendor), int2hex(hid_device.idProduct)) in KNOWN_BOOTLOADERS |  | ||||||
| 
 |  | ||||||
|     def is_console_hid(self, hid_device): |  | ||||||
|         """Returns true when the usage page indicates it's a teensy-style console. |  | ||||||
|         """ |  | ||||||
|         return hid_device['usage_page'] == 0xFF31 and hid_device['usage'] == 0x0074 |  | ||||||
| 
 |  | ||||||
|     def is_filtered_device(self, hid_device): |  | ||||||
|         """Returns True if the device should be included in the list of available consoles. |  | ||||||
|         """ |  | ||||||
|         return int2hex(hid_device['vendor_id']) == self.vid and int2hex(hid_device['product_id']) == self.pid |  | ||||||
| 
 |  | ||||||
|     def find_devices_by_report(self, hid_devices): |  | ||||||
|         """Returns a list of available teensy-style consoles by doing a brute-force search. |  | ||||||
| 
 |  | ||||||
|         Some versions of linux don't report usage and usage_page. In that case we fallback to reading the report (possibly inaccurately) ourselves. |  | ||||||
|         """ |  | ||||||
|         devices = [] |  | ||||||
| 
 |  | ||||||
|         for device in hid_devices: |  | ||||||
|             path = device['path'].decode('utf-8') |  | ||||||
| 
 |  | ||||||
|             if path.startswith('/dev/hidraw'): |  | ||||||
|                 number = path[11:] |  | ||||||
|                 report = Path(f'/sys/class/hidraw/hidraw{number}/device/report_descriptor') |  | ||||||
| 
 |  | ||||||
|                 if report.exists(): |  | ||||||
|                     rp = report.read_bytes() |  | ||||||
| 
 |  | ||||||
|                     if rp[1] == 0x31 and rp[3] == 0x09: |  | ||||||
|                         devices.append(device) |  | ||||||
| 
 |  | ||||||
|         return devices |  | ||||||
| 
 |  | ||||||
|     def find_bootloaders(self): |  | ||||||
|         """Returns a list of available bootloader devices. |  | ||||||
|         """ |  | ||||||
|         return list(filter(self.is_bootloader, usb.core.find(find_all=True))) |  | ||||||
| 
 |  | ||||||
|     def find_devices(self): |  | ||||||
|         """Returns a list of available teensy-style consoles. |  | ||||||
|         """ |  | ||||||
|         hid_devices = hid.enumerate() |  | ||||||
|         devices = list(filter(self.is_console_hid, hid_devices)) |  | ||||||
| 
 |  | ||||||
|         if not devices: |  | ||||||
|             devices = self.find_devices_by_report(hid_devices) |  | ||||||
| 
 |  | ||||||
|         if self.vid and self.pid: |  | ||||||
|             devices = list(filter(self.is_filtered_device, devices)) |  | ||||||
| 
 |  | ||||||
|         # Add index numbers |  | ||||||
|         device_index = {} |  | ||||||
|         for device in devices: |  | ||||||
|             id = ':'.join((int2hex(device['vendor_id']), int2hex(device['product_id']))) |  | ||||||
| 
 |  | ||||||
|             if id not in device_index: |  | ||||||
|                 device_index[id] = 0 |  | ||||||
| 
 |  | ||||||
|             device_index[id] += 1 |  | ||||||
|             device['index'] = device_index[id] |  | ||||||
| 
 |  | ||||||
|         return devices |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def int2hex(number): |  | ||||||
|     """Returns a string representation of the number as hex. |  | ||||||
|     """ |  | ||||||
|     return "%04X" % number |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def list_devices(device_finder): |  | ||||||
|     """Show the user a nicely formatted list of devices. |  | ||||||
|     """ |  | ||||||
|     devices = device_finder.find_devices() |  | ||||||
| 
 |  | ||||||
|     if devices: |  | ||||||
|         cli.log.info('Available devices:') |  | ||||||
|         for dev in devices: |  | ||||||
|             color = LOG_COLOR['colors'][LOG_COLOR['next']] |  | ||||||
|             LOG_COLOR['next'] = (LOG_COLOR['next'] + 1) % len(LOG_COLOR['colors']) |  | ||||||
|             cli.log.info("\t%s%s:%s:%d{style_reset_all}\t%s %s", color, int2hex(dev['vendor_id']), int2hex(dev['product_id']), dev['index'], dev['manufacturer_string'], dev['product_string']) |  | ||||||
| 
 |  | ||||||
|     if cli.args.bootloaders: |  | ||||||
|         bootloaders = device_finder.find_bootloaders() |  | ||||||
| 
 |  | ||||||
|         if bootloaders: |  | ||||||
|             cli.log.info('Available Bootloaders:') |  | ||||||
| 
 |  | ||||||
|             for dev in bootloaders: |  | ||||||
|                 cli.log.info("\t%s:%s\t%s", int2hex(dev.idVendor), int2hex(dev.idProduct), KNOWN_BOOTLOADERS[(int2hex(dev.idVendor), int2hex(dev.idProduct))]) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @cli.argument('--bootloaders', arg_only=True, default=True, action='store_boolean', help='displaying bootloaders.') |  | ||||||
| @cli.argument('-d', '--device', help='Device to select - uses format <pid>:<vid>[:<index>].') |  | ||||||
| @cli.argument('-l', '--list', arg_only=True, action='store_true', help='List available hid_listen devices.') |  | ||||||
| @cli.argument('-n', '--numeric', arg_only=True, action='store_true', help='Show VID/PID instead of names.') |  | ||||||
| @cli.argument('-t', '--timestamp', arg_only=True, action='store_true', help='Print the timestamp for received messages as well.') |  | ||||||
| @cli.argument('-w', '--wait', type=int, default=1, help="How many seconds to wait between checks (Default: 1)") |  | ||||||
| @cli.subcommand('Acquire debugging information from usb hid devices.', hidden=False if cli.config.user.developer else True) |  | ||||||
| def console(cli): |  | ||||||
|     """Acquire debugging information from usb hid devices |  | ||||||
|     """ |  | ||||||
|     vid = None |  | ||||||
|     pid = None |  | ||||||
|     index = 1 |  | ||||||
| 
 |  | ||||||
|     if cli.config.console.device: |  | ||||||
|         device = cli.config.console.device.split(':') |  | ||||||
| 
 |  | ||||||
|         if len(device) == 2: |  | ||||||
|             vid, pid = device |  | ||||||
| 
 |  | ||||||
|         elif len(device) == 3: |  | ||||||
|             vid, pid, index = device |  | ||||||
| 
 |  | ||||||
|             if not index.isdigit(): |  | ||||||
|                 cli.log.error('Device index must be a number! Got "%s" instead.', index) |  | ||||||
|                 exit(1) |  | ||||||
| 
 |  | ||||||
|             index = int(index) |  | ||||||
| 
 |  | ||||||
|             if index < 1: |  | ||||||
|                 cli.log.error('Device index must be greater than 0! Got %s', index) |  | ||||||
|                 exit(1) |  | ||||||
| 
 |  | ||||||
|         else: |  | ||||||
|             cli.log.error('Invalid format for device, expected "<pid>:<vid>[:<index>]" but got "%s".', cli.config.console.device) |  | ||||||
|             cli.print_help() |  | ||||||
|             exit(1) |  | ||||||
| 
 |  | ||||||
|         vid = vid.upper() |  | ||||||
|         pid = pid.upper() |  | ||||||
| 
 |  | ||||||
|     device_finder = FindDevices(vid, pid, index, cli.args.numeric) |  | ||||||
| 
 |  | ||||||
|     if cli.args.list: |  | ||||||
|         return list_devices(device_finder) |  | ||||||
| 
 |  | ||||||
|     print('Looking for devices...', flush=True) |  | ||||||
|     device_finder.run_forever() |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Zach White
						Zach White