Git Product home page Git Product logo

Comments (1)

DePierre avatar DePierre commented on June 20, 2024

Current draft is using argparse.ArgumentParser to let the heavy lifting do the standard module.

The new Command class is currently named NewCommand only for the dev phase and will be renamed Command once we agree on the proposal and once the complete codebase has been updated in a future PR.

Updating the replay module to use the new command class:

class replay(CANModule):
    # . . .
    def do_init(self, params):
        # . . .
        self.register_command(NewCommand(prog='g', description='Enable/disable sniffing to collect CAN packets', callback=self.cmd_sniff))
        self.register_command(NewCommand(prog='p', description='Print count of loaded CAN packets', callback=self.cmd_show_count))
        new_cmd = NewCommand(prog='l', description='Load CAN packets from file', callback=self.cmd_load)
        new_cmd.add_argument('filename', help='Filename where to load the packets from')
        self.register_command(new_cmd)
        new_cmd = NewCommand(prog='r', description='Replay range from loaded CAN packets', callback=self.cmd_replay_range)
        new_cmd.add_argument('start', nargs='?', type=int, default=-1, help='Index of the first packet to replay')
        new_cmd.add_argument('end', nargs='?', type=int, default=-1, help='Index of the last packet to replay')
        self.register_command(new_cmd)
        new_cmd = NewCommand(prog='d', description='Save range of loaded CAN packets', callback=self.cmd_save_dump)
        new_cmd.add_argument('start', nargs='?', type=int, default=-1, help='Index of the first packet to save')
        new_cmd.add_argument('end', nargs='?', type=int, default=-1, help='Index of the last packet to save')
        new_cmd.add_argument('filename', nargs='?', default='replay.save', help='Filename where to store the packets')
        self.register_command(new_cmd)
        self.register_command(NewCommand(prog='c', description='Reset loaded CAN packets', callback=self.cmd_reset))
    # . . .
    def cmd_save_dump(self, start, end, filename=None):
        """Save a range of CAN messages from the loaded packets.

        :param int start: Index of the first frame to replay.
        :param int end: Index of the last frame to replay.
        :param str filename: Filename where to write the CAN frames to.
        """
        filename = filename or self.filename
        start = max(0, start)
        end = min(end, len(self.replay))
        return self.replay.save_dump(filename, start, end - start)

Using argparse and shlex, the callback mechanism becomes much simpler:

class CANModule:
    # . . .
        def raw_write(self, string):
        """Call the command specified in `string` and return its result. Used for direct input.

        :param str string: The full command with its parameters (e.g. 's' to stop the module)

        :returns: str -- Result of the command execution.
        """
        self.thr_block.wait(timeout=self._timeout)  # Timeout of 3 seconds
        self.thr_block.clear()
        command_name, *params = shlex.split(string)
        if command_name not in self.commands:
            raise KeyError("Module '{}' does not have the command '{}'".format(self.__class__.__name__, command_name))
        command = self.commands[command_name]
        if not command.enabled:
            ret = 'Error: command {} is disabled!'.format(command_name)
        else:
            args = vars(command.parse_args(params))
            try:
                ret = command.callback(**args)
            except Exception as e:
                ret = 'Error: {}'.format(e)
                traceback.print_exc()
        self.thr_block.set()
        return ret

Writing a new command is already almost 100% documented since it inherits from ArgumentParser (see https://docs.python.org/3/library/argparse.html). As shown in the replay module, the developer simply has to set prog to the command name, specify a callback function and add each arguments to the command. The developer can specify optional arguments, the type of the arguments and their description/help. For instance, in cmd_save_dump, start and end are already of type int when reaching the callback function.

With the new command, the help can be shown easily. For instance in the CLI:

cantoolz -g c -c examples/can_replay.py


   _____          _   _ _______          _
  / ____|   /\   | \ | |__   __|        | |
 | |       /  \  |  \| |  | | ___   ___ | |____
 | |      / /\ \ | . ` |  | |/ _ \ / _ \| |_  /
 | |____ / ____ \| |\  |  | | (_) | (_) | |/ /
  \_____/_/    \_\_| \_|  |_|\___/ \___/|_/___|



CANToolz prompt.   Type help or ? to list commands.

>> help 0
Module replay: Replay module


    This module allows loading/saving CAN messages for replay.

    Init parameters:
        - 'load_from': 'filename'  # Load packets from file (optional)
        - 'save_to': 'filename'    # Save to file (mod_replay.save by default)

    Module parameters: none
        - 'delay': 0               # Delay in second between each frame (0 by default)
        - 'ignore_time': False     # Ignore the CAN message timestamps during replay

    Example:
        {'delay': .2}

    
Commands:
	S - Current status
	s - Stop/activate current module
	g - Enable/disable sniffing to collect CAN packets
	p - Print count of loaded CAN packets
	l filename - Load CAN packets from file
	r [start] [end] - Replay range from loaded CAN packets
	d [start] [end] [filename] - Save range of loaded CAN packets
	c - Reset loaded CAN packets

>> 

In the Web UI, hovering the mouse on the Replay range from loaded CAN packets input field shows the following tooltip:
screen shot 2018-01-03 at 5 39 14 pm

from cantoolz.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.