Example #1
0
class TimeTerminatedInterface(StreamInterface):
    """
    A simple device where commands are terminated by a timeout.

    This demonstrates how to implement devices that do not have standard
    terminators and where a command is considered terminated after a certain
    time delay of not receiving more data.

    To interact with this device, you must switch telnet into char mode, or use
    netcat with special tty settings:

        $ telnet host port
        ^]
        telnet> mode char
        [type command and wait]

        $ stty -icanon && nc host port
        hello world!
        foobar!

    The following commands are available:

     - ``hello ``: Reply with "world!"
     - ``foo``: Replay with "bar!"
     - ``P``: Returns the device parameter
     - ``P=something``: Set parameter to specified value

    """

    commands = {
        # Space as \x20 represents a custom 'terminator' for this command only
        # However, waiting for the timeout still applies
        Cmd("say_world", pattern=scanf("hello\x20")),
        Cmd("say_bar", pattern=scanf("foo")),
        Var("param", read_pattern=scanf("P"), write_pattern=scanf("P=%d")),
    }

    # An empty in_terminator triggers "timeout mode"
    # Otherwise, a ReadTimeout is considered an error.
    in_terminator = ""
    out_terminator = "\r\n"

    # Unusually long, for easier manual entry
    readtimeout = 2500

    def handle_error(self, request, error):
        return "An error occurred: " + repr(error)
Example #2
0
class ExampleMotorStreamInterface(StreamInterface):
    """
    TCP-stream based example motor interface

    This motor simulation can be controlled via telnet:

        $ telnet host port

    Where the host and port-parameter are part of the dynamically created documentation for
    a concrete device instance.

    The motor starts moving immediately when a new target position is set. Once it's moving,
    it has to be stopped to receive a new target, otherwise an error is generated.
    """

    commands = {
        Cmd('get_status', regex(r'^S\?$')),  # explicit regex
        Cmd('get_position', r'^P\?$'),  # implicit regex
        Cmd('get_target', r'^T\?$'),
        Cmd('set_target', scanf('T=%f')),  # scanf format specification
        Cmd('stop',
            r'^H$',
            return_mapping=lambda x: 'T={},P={}'.format(x[0], x[1])),
    }

    in_terminator = '\r\n'
    out_terminator = '\r\n'

    def get_status(self):
        """Returns the status of the device, which is one of 'idle' or 'moving'."""
        return self.device.state

    def get_position(self):
        """Returns the current position in mm."""
        return self.device.position

    def get_target(self):
        """Returns the current target in mm."""
        return self.device.target

    def set_target(self, new_target):
        """
        Sets the new target in mm, the movement starts immediately. If the value is outside
        the interval [0, 250] or the motor is already moving, an error is returned, otherwise
        the new target is returned."""
        try:
            self.device.target = new_target
            return 'T={}'.format(new_target)
        except RuntimeError:
            return 'err: not idle'
        except ValueError:
            return 'err: not 0<=T<=250'