Skip to content

Commit

Permalink
Merge pull request #227 from DMSC-Instrument-Data/216_scanf_for_var_cmd
Browse files Browse the repository at this point in the history
scanf format specification for Cmd and Var
  • Loading branch information
MikeHart85 committed May 26, 2017
2 parents 9ff5a82 + 4d70a52 commit b9a368b
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 43 deletions.
15 changes: 9 additions & 6 deletions docs/developer_guide/writing_devices.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Writing Device Simulators
=========================

The following section describes how to write a new device simulator, what to
The following section describes how to write a new device simulator, what to
consider, and how to get the changes upstream.

Getting Lewis Source Code
Expand Down Expand Up @@ -226,14 +226,14 @@ According to the specifications above, the commands are defined like this:

.. code:: python
from lewis.adapters.stream import StreamInterface, Cmd
from lewis.adapters.stream import StreamInterface, Cmd, scanf
class ExampleMotorStreamInterface(StreamInterface):
commands = {
Cmd('get_status', r'^S\?$'),
Cmd('get_position', r'^P\?$'),
Cmd('get_target', r'^T\?$'),
Cmd('set_target', r'^T=([-+]?[0-9]*\.?[0-9]+)$', argument_mappings=(float,)),
Cmd('set_target', scanf('T=%f'), argument_mappings=(float,)),
Cmd('stop', r'^H$',
return_mapping=lambda x: 'T={},P={}'.format(x[0], x[1])),
}
Expand All @@ -260,15 +260,18 @@ According to the specifications above, the commands are defined like this:
return 'err: not 0<=T<=250'
The first argument to :class:`~lewis.adapters.stream.Cmd` specifies the method
name the command is bound to, whereas the second argument is the regular expression that a
request coming in over the TCP stream must match. If a method has
name the command is bound to, whereas the second argument is a pattern that a
request coming in over the TCP stream must match. If the pattern is specified as a string,
it is treated as a regular expression. In the above example, :class:`~lewis.adapters.stream.scanf`
is used for one of the functions, it allows for ``scanf``-like format specifiers. If a method has
arguments (such as ``set_target``), these need to be defined as capture
groups in the regular expression. These groups are passed as strings to
the bound method. If any sort of conversion is required for these
arguments, the ``argument_mapping``-parameter can be a tuple of
conversion functions with the same lengths as the number of capture
groups in the regular expression. In the case of ``set_target`` it's
enough to convert the string to float. Return values (except ``None``)
enough to convert the string to float, but :class:`~lewis.adapters.stream.scanf` does that
automatically, so it is not strictly required here. Return values (except ``None``)
are converted to strings automatically, but this conversion can be
overridden by supplying a callable object to ``return_mapping``, as it
is the case for the ``stop``-command.
Expand Down
30 changes: 27 additions & 3 deletions docs/release_notes/release_1_1_0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,34 @@ This release is currently in progress.
New features
------------

The control client, lewis-control, now provides a version argument via ``--version`` or ``-v``.
- :mod:`~lewis.adapters.stream` has been extended. Besides regular expressions, it is now
possible to use `scanf` format specifications to define commands. This makes handling
of for example floating point numbers much more convenient:

::
.. sourcecode:: python

$ lewis-control -v
from lewis.adapters import StreamInterface, Cmd, scanf

class SomeInterface(StreamInterface):
commands = {
Cmd(lambda x: x**2, scanf('SQ %f'))
}

:class:`~lewis.adapters.stream.scanf` provides argument mappings for the matched arguments
automatically, so it is optional to pass them to ``Cmd``. In the case outlined above, the
argument is automatically converted to ``float``.

If a string is specified directly (instead of ``scanf(...)``), it is treated as a regular
expression like in earlier versions.

Internally, the scanf_ package is used for handling these patterns, please check the package
documentation for all available format specifiers.

- The control client, lewis-control, now provides a version argument via ``--version`` or ``-v``.

::

$ lewis-control -v

Bug fixes and other improvements
--------------------------------
Expand Down Expand Up @@ -63,3 +86,4 @@ Upgrade guide
.. _source repository: https://github.com/DMSC-Instrument-Data/lewis/docs/resources/logo
.. _Rubik: https://github.com/googlefonts/rubik
.. _inkscape: https://inkscape.org/
.. _scanf: https://github.com/joshburnett/scanf

0 comments on commit b9a368b

Please sign in to comment.