diff --git a/client/eepprog.py b/client/eepprog.py index 58837d0..617fe3f 100755 --- a/client/eepprog.py +++ b/client/eepprog.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import click +import serial.tools.list_ports from helpers import CliContext, Logger, EepromProgrammer @@ -12,14 +13,13 @@ from helpers import CliContext, Logger, EepromProgrammer metavar='BAUDRATE', help="Set the baud rate of the serial device") @click.option('--verbose', '-v', is_flag=True, help='Print debug output') @click.pass_context -def eepprog(ctx: click.Context, device: str, baud: int, verbose: bool): +def eepprog(ctx: click.Context, device: str, baud: int, verbose: bool) -> None: # Create dependencies logger = Logger(verbose=verbose) eeprom_programmer = EepromProgrammer(logger=logger, device=device, baudrate=baud) - logger.debug("Creating CLI context (device: {}, bauds: {})".format(device, baud)) - # Create CLI context + logger.debug("Creating CLI context") ctx.obj = CliContext( logger=logger, eeprom_programmer=eeprom_programmer, @@ -31,7 +31,7 @@ def eepprog(ctx: click.Context, device: str, baud: int, verbose: bool): @eepprog.command('hello', short_help='Say hello. :)') @click.pass_obj -def hello(context: CliContext): +def hello(context: CliContext) -> None: """ Say hello. :) @@ -48,17 +48,34 @@ def hello(context: CliContext): @eepprog.command('test', short_help="Send INIT command to the programmer and read answer") @click.pass_obj -def test(context: CliContext): +def test(context: CliContext) -> None: """ Send an 'INIT' command to the programmer and read the answer. Test command for debugging. """ - context.eeprom_programmer.test() + context.eeprom_programmer.test_command() + + +@eepprog.command('list-devices', short_help="List available serial ports") +@click.pass_obj +def list_devices(context: CliContext) -> None: + """ + List serial ports that are available on the system. + + Internally uses 'serial.tools.list_ports' of pySerial. + """ + context.logger.debug("Getting list of serial ports") + ports = serial.tools.list_ports.comports() + + context.logger.debug() # Print empty line + click.echo("Found {} serial ports:".format(len(ports))) + for port in ports: + click.echo('' + str(port)) + -# TODO command: list-devices -> serial.tools.list_ports # TODO shell: Run an interactive shell if __name__ == '__main__': - eepprog() + eepprog(max_content_width=120) diff --git a/client/helpers/EepromProgrammer.py b/client/helpers/EepromProgrammer.py index d529ddc..19f55ec 100644 --- a/client/helpers/EepromProgrammer.py +++ b/client/helpers/EepromProgrammer.py @@ -1,5 +1,5 @@ from serial import Serial -from typing import Optional +from typing import Optional, Union from . import Logger @@ -20,33 +20,49 @@ class EepromProgrammer: self._device_file = device self._baudrate = baudrate - # TODO - def open(self): + def open(self) -> None: """ Open and setup serial port. """ assert self.serial is None, 'Serial port is already opened!' - self.logger.debug("Setting up serial device '{}' with baudrate {}".format(self._device_file, self._baudrate)) + self.logger.debug("Opening serial device '{}' with {} bauds".format(self._device_file, self._baudrate)) self.serial = Serial(self._device_file, self._baudrate) - def close(self): - if self.serial is None: - self.logger.debug("Serial port is already closed") - return + def close(self) -> None: + """ + Closes the serial port. + """ + if self.serial is not None: + self.logger.debug("Closing serial port") + self.serial.close() - self.logger.debug("Closing serial port") - self.serial.close() + def write(self, data: Union[bytes, bytearray]) -> int: + """ + Writes bytes to the serial port and writes debug log. + """ + self.logger.debug('Writing: {}'.format(str(data))) + return self.serial.write(data) # TODO - def test(self): + def test_command(self) -> None: # Open serial port if self.serial is None: self.open() + # TODO where to do this? in open() or when needed? + self.serial.timeout = 1 + # Write a test command - self.logger.info("Sending 'INIT' ...") - self.serial.write(b"INIT\n") + self.logger.info("Sending INIT command ...") + self.write(b'INIT BINARY\n') # Just read some stuff - self.logger.info("Read line: ", self.serial.readline(80)) + self.logger.info("Received line: ", self.serial.readline(80)) + + # Send a READ command + self.logger.info("Sending READ command ...") + self.write(b'READ 0000:0010\n') + + while True: + self.logger.info("Received line: ", self.serial.readline(80))