enhance documentation

- flatten hierarchy (some links do not work when using folders)
+ fix a bug with the redorder flag in Override
+ allow removal of parameters
+ clean description using inspect.cleandoc

Change-Id: I3dde4f4cb29c46e8a21014f1fad7aa3ad610a1bf
This commit is contained in:
2021-01-25 15:12:47 +01:00
parent e411ded55b
commit bc5edec06f
32 changed files with 608 additions and 381 deletions

View File

@ -1,9 +1,10 @@
/* this is for the sphinx_rtd_theme
/* this is for the sphinx_rtd_theme */
div.wy-nav-content
{
max-width: 100% !important;
}
*/
/* this is for the alabaser theme */
div.body {
max-width: 100%;
}
@ -32,4 +33,19 @@ pre, tt, code {
}
}
dd {
padding-bottom: 0.5em;
}
/* make nested bullet lists nicer (ales too much space above inner nested list) */
.rst-content .section ul li ul {
margin-top: 0px;
margin-bottom: 6px;
}
/* make some bullet lists more dense (this rule exists in theme.css, but not important)*/
.wy-plain-list-disc li p:last-child, .rst-content .section ul li p:last-child, .rst-content .toctree-wrapper ul li p:last-child, article ul li p:last-child {
margin-bottom: 0 !important;
}

View File

@ -89,9 +89,10 @@ pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# sort by source instead of alphabetic
autodoc_member_order = 'bysource'
autodoc_default_options = {
'member-order': 'bysource',
'show-inheritance': True,
}
default_role = 'any'
# -- Options for HTML output ----------------------------------------------
@ -99,9 +100,19 @@ default_role = 'any'
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
#import sphinx_rtd_theme
#html_theme = 'sphinx_rtd_theme'
html_theme = 'alabaster'
if False: # alabaster
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'page_width': '100%',
'fixed_sidebar': True,
}
else:
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
@ -110,14 +121,6 @@ html_theme = 'alabaster'
html_last_updated_fmt = '%Y-%m-%d %H:%M'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'page_width': '100%',
'fixed_sidebar': True,
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,

View File

@ -1,6 +0,0 @@
Demo cryostat
=============
.. automodule:: secop_demo.cryo
:members:

View File

@ -1,12 +0,0 @@
Demo
====
Specific sample environments
----------------------------
.. toctree::
:maxdepth: 3
cryo
test

View File

@ -1,6 +0,0 @@
Test devices
=============
.. automodule:: secop_demo.test
:members:

View File

@ -1,11 +0,0 @@
ESS
===
Frameworks
----------
.. toctree::
:maxdepth: 3
epics

View File

@ -1,10 +0,0 @@
Facility specific functionalities
=================================
.. toctree::
:maxdepth: 3
demo/index
mlz/index
ess/index
psi/index

View File

@ -1,6 +0,0 @@
ANTARES magnet (amagnet)
========================
.. automodule:: secop_mlz.amagnet
:members:

View File

@ -1,6 +0,0 @@
Entangle
========
.. automodule:: secop_mlz.entangle
:members:

View File

@ -1,20 +0,0 @@
MLZ
===
Frameworks
----------
.. toctree::
:maxdepth: 3
entangle
Specific sample environments
----------------------------
.. toctree::
:maxdepth: 3
amagnet

View File

@ -1,10 +0,0 @@
PSI
===
.. toctree::
:maxdepth: 3
ppms
ls370res

View File

@ -1,7 +0,0 @@
LakeShore 370 resistivity
=========================
.. automodule:: secop_psi.ls370res
:members:

View File

@ -1,7 +0,0 @@
PPMS
====
.. automodule:: secop_psi.ppms
:members:

View File

@ -1,67 +0,0 @@
Framework documentation
=======================
Module Base Classes
-------------------
.. autoclass:: secop.core.Module
:members: startModule
.. autoclass:: secop.core.Readable
:members: pollerClass, Status
.. autoclass:: secop.core.Writable
.. autoclass:: secop.core.Drivable
:members: Status, isBusy, isDriving, do_stop
Parameters, Commands and Properties
-----------------------------------
.. autoclass:: secop.core.Parameter
.. autoclass:: secop.core.Command
.. autoclass:: secop.core.Override
.. autoclass:: secop.core.Property
.. autoclass:: secop.core.Attached
Datatypes
---------
.. autoclass:: secop.core.FloatRange
.. autoclass:: secop.core.IntRange
.. autoclass:: secop.core.BoolType
.. autoclass:: secop.core.ScaledInteger
.. autoclass:: secop.core.EnumType
.. autoclass:: secop.core.StringType
.. autoclass:: secop.core.TupleOf
.. autoclass:: secop.core.ArrayOf
.. autoclass:: secop.core.StructOf
.. autoclass:: secop.core.BLOBType
Communication
-------------
.. autoclass:: secop.core.Communicator
:members: do_communicate
.. autoclass:: secop.core.StringIO
:members: do_communicate, do_multicomm
.. autoclass:: secop.core.HasIodev
.. autoclass:: secop.core.IOHandlerBase
:members:
.. autoclass:: secop.core.IOHandler
:members:
Exception classes
-----------------
.. automodule:: secop.errors
:members:

View File

@ -1,18 +1,16 @@
Welcome to the FRAPPY documentation!
====================================
Frappy Programming Guide
========================
.. toctree::
:maxdepth: 2
tutorial/tutorial
server
framework
facility/index
Indices and tables
==================
introduction
tutorial
reference
secop_psi
secop_demo
secop_mlz
secop_ess
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -0,0 +1,70 @@
Introduction
============
Frappy - a Python Framework for SECoP
-------------------------------------
*Frappy* is a Python framework for creating Sample Environment Control Nodes (SEC Node) with
a SECoP interface. A *SEC Node* is a service, running usually a computer or microcomputer,
which accesses the hardware over the interfaces given by the manufacturer of the used
electronic devices. It provides access to the data in an abstracted form over the SECoP interface.
`SECoP <https://github.com/SampleEnvironment/SECoP/tree/master/protocol>`_ is a protocol for
communicating with Sample Environment and other mobile devices, specified by a committee of
the `ISSE <https://sampleenvironment.org>`_.
The Frappy framework deals with all the details of the SECoP protocol, so the programmer
can concentrate on the details of accessing the hardware with support for different types
of interfaces (TCP or Serial, ASCII or binary). However, the programmer should be aware of
the basic principle of the SECoP protocol: the hardware abstraction.
Hardware Abstraction
--------------------
The idea of hardware abstraction is to hide the details of hardware access from the SECoP interface.
A SECoP module is a logical component of an abstract view of the sample environment.
It is one independent value of measurement like a temperature or pressure or a physical output like
a current or voltage. This corresponds roughly to an EPICS channel or a NICOS device. On the
hardware side we may have devices with several channels, like a typical temperature controller,
which will be represented individual SECoP modules.
On the other hand a SECoP channel might be linked with several hardware devices, for example if
you imagine a superconducting magnet controller built of separate electronic devices like a power
supply, switch heater and coil temperature monitor. The latter case does not mean that we have
to hide the details in the SECoP interface. For an expert it might be useful to give at least
read access to hardware specific data by providing them as separate SECoP modules. But the
magnet module should be usable without knowledge of all the inner details.
A SECoP module has:
* **properties**: static information describing the module, for example a human readable
*description* of the module or information about the intended *visibility*.
* **parameters**: changing information about the state of a module (for example the *status*
containing information about the state of the module) or modifiable information influencing
the measurement (for example a "ramp" rate).
* **commands**: actions, for example *stop*.
A SECoP module belongs to an interface class, mainly *Readable* or *Drivable*. A *Readable*
has at least the parameters *value* and *status*, a *Drivable* in addition *target*. *value* is
the main value of the module and is read only. *status* is a tuple (status code, status text),
and *target* is the target value. When the *target* parameter value of a *Drivable* changes,
the status code changes normally to a busy code. As soon as the target value is reached,
the status code changes back to an idle code, if no error occurs.
**Programmers Hint:** before starting to code, choose carefully the main SECoP modules you want
to provide to the user.
Programming a Driver
--------------------
Programming a driver means extending one of the base classes like :class:`secop.modules.Readable`
or :class:`secop.modules.Drivable`. The parameters are defined in the dict :py:attr:`parameters`, as a
class attribute of the extended class, using the :class:`secop.params.Parameter` constructor, or in case
of altering the properties of an inherited parameter, :class:`secop.params.Override`.
Parameters usually need a method :meth:`read_<name>()`
implementing the code to retrieve their value from the hardware. Writeable parameters
(with the argument ``readonly=False``) usually need a method :meth:`write_<name>(<value>)`
implementing how they are written to the hardware. Above methods may be omitted, when
there is no interaction with the hardware involved.

77
doc/source/reference.rst Normal file
View File

@ -0,0 +1,77 @@
Reference
---------
Module Base Classes
...................
.. autoclass:: secop.modules.Module
:members: earlyInit, initModule, startModule
.. autoclass:: secop.modules.Readable
:members: pollerClass, Status
.. autoclass:: secop.modules.Writable
.. autoclass:: secop.modules.Drivable
:members: Status, isBusy, isDriving, do_stop
Parameters, Commands and Properties
...................................
.. autoclass:: secop.params.Parameter
.. autoclass:: secop.params.Command
.. autoclass:: secop.params.Override
.. autoclass:: secop.properties.Property
.. autoclass:: secop.modules.Attached
:show-inheritance:
Datatypes
.........
.. autoclass:: secop.datatypes.FloatRange
.. autoclass:: secop.datatypes.IntRange
.. autoclass:: secop.datatypes.BoolType
.. autoclass:: secop.datatypes.ScaledInteger
.. autoclass:: secop.datatypes.EnumType
.. autoclass:: secop.datatypes.StringType
.. autoclass:: secop.datatypes.TupleOf
.. autoclass:: secop.datatypes.ArrayOf
.. autoclass:: secop.datatypes.StructOf
.. autoclass:: secop.datatypes.BLOBType
Communication
.............
.. autoclass:: secop.modules.Communicator
:show-inheritance:
:members: do_communicate
.. autoclass:: secop.stringio.StringIO
:show-inheritance:
:members: do_communicate, do_multicomm
.. autoclass:: secop.stringio.HasIodev
:show-inheritance:
.. autoclass:: secop.iohandler.IOHandlerBase
:show-inheritance:
:members:
.. autoclass:: secop.iohandler.IOHandler
:show-inheritance:
:members:
Exception classes
.....................--
.. automodule:: secop.errors
:members:
.. include:: server.rst

10
doc/source/secop_demo.rst Normal file
View File

@ -0,0 +1,10 @@
Demo
====
.. automodule:: secop_demo.cryo
:show-inheritance:
:members:
.. automodule:: secop_demo.test
:show-inheritance:
:members:

View File

@ -1,6 +1,9 @@
EPICS modules
=============
ESS
---
EPICS
.....
.. automodule:: secop_ess.epics
:show-inheritance:
:members:

19
doc/source/secop_mlz.rst Normal file
View File

@ -0,0 +1,19 @@
MLZ
---
Amagnet (Garfield)
..................
.. automodule:: secop_mlz.amagnet
:show-inheritance:
:members:
Entangle Framework
..................
.. automodule:: secop_mlz.entangle
:show-inheritance:
:members:

19
doc/source/secop_psi.rst Normal file
View File

@ -0,0 +1,19 @@
PSI (SINQ)
----------
PPMS
....
.. automodule:: secop_psi.ppms
:show-inheritance:
:members:
LakeShore 370
.............
Calibrated sensors and control loop not yet supported.
.. automodule:: secop_psi.ls370res
:show-inheritance:
:members:

View File

@ -1,8 +1,5 @@
Configuring and Starting
========================
Configuration
-------------
.............
The configuration consists of a **NODE** section, an **INTERFACE** section and one
section per SECoP module.
@ -51,7 +48,7 @@ the SECoP interface.
Starting
--------
........
The Frappy server can be started via the **bin/secop-server** script.
@ -73,5 +70,3 @@ The Frappy server can be started via the **bin/secop-server** script.
-q, --quiet suppress non-error messages
-d, --daemonize run as daemon
-t, --test check cfg files only

7
doc/source/tutorial.rst Normal file
View File

@ -0,0 +1,7 @@
Tutorial
--------
.. toctree::
:maxdepth: 2
tutorial_helevel

View File

@ -1,64 +1,10 @@
Frappy Programming Guide
========================
HeLevel - a Simple Driver
=========================
Introduction
------------
*Frappy* is a Python framework for creating Sample Environment Control Nodes (SEC Node) with
a SECoP interface. A *SEC Node* is a service, running usually a computer or microcomputer,
which accesses the hardware over the interfaces given by the manufacturer of the used
electronic devices. It provides access to the data in an abstracted form over the SECoP interface.
`SECoP <https://github.com/SampleEnvironment/SECoP/tree/master/protocol>`_ is a protocol for
communicating with Sample Environment and other mobile devices, specified by a committee of
the `ISSE <https://sampleenvironment.org>`_.
The Frappy framework deals with all the details of the SECoP protocol, so the programmer
can concentrate on the details of accessing the hardware with support for different types
of interfaces (TCP or Serial, ASCII or binary). However, the programmer should be aware of
the basic principle of the SECoP protocol: the hardware abstraction.
Hardware Abstraction
--------------------
The idea of hardware abstraction is to hide the details of hardware access from the SECoP interface.
A SECoP module is a logical component of an abstract view of the sample environment.
It is one independent value of measurement like a temperature or physical output like a current or voltage.
This corresponds roughly to an EPICS channel or a NICOS device. On the hardware side we may have devices
with several channels, like a typical temperature controller, which will be represented individual SECoP modules.
On the other hand a SECoP channel might be linked with several hardware devices, for example if you imagine
a superconducting magnet controller built of seperate electronic devices like a power supply, switch heater
and coil temperature monitor. The latter case does not mean that we have to hide complete the details in the
SECoP interface. For an expert it might be useful to give at least read access to hardware specific data
by providing them as seperate SECoP modules. But the magnet module should be usable without knowledge of
all the inner details.
A SECoP module has:
* **properties**: static information describing the module, for example a human readable *description* of
the module or information about the intended *visibiliy*.
* **parameters**: changing information about the state of a module (for example the *status* containing
information about the state of the module )or modifiable information influencing the measurement
(for example a "ramp" rate)
* **commands**: actions, for example *stop*
A SECoP module belongs to an interface class, mainly *Readable* or *Drivable*. A *Readable* has at least the
parameters *value* and *status*, a *Drivable* in addition *target*. *value* is the main value of the module
and is read only. *status* is a tuple (status code, status text), and *target* is the target value.
When the *target* parameter value of a *Drivable* changes, the status code changes normally to a busy code.
As soon as the target value is reached, the status code changes back to an idle code, if no error occurs.
**Programmers Hint:** before starting to code, choose carefully the main SECoP modules you have to provide
to the user.
Tutorial Example
----------------
For this tutorial we choose as an example a cryostat with a LakeShore 336 temperature controller, a level
meter and a motorized needle value. Let us start with the level meter, as this is the simplest module.
Coding the HeLevel Driver
-------------------------
Coding the Driver
-----------------
For this tutorial we choose as an example a cryostat. Let us start with the helium level meter,
as this is the simplest module.
As mentioned in the introduction, we have to code the access to the hardware (driver), and the Frappy
framework will deal with the SECoP interface. The code for the driver is located in a subdirectory
named after the facility or institute programming the driver in our case *secop_psi*.
@ -79,11 +25,12 @@ CCU4 luckily has a very simple and logical protocol:
StringIO, HasIodev
# the class used for communication
class CCU4IO(StringIO):
"""communication with CCU4"""
# for completeness: (not needed, as it is the default)
end_of_line = '\n'
# on connect, we send 'cid' and expect a reply starting with 'CCU4'
identification = [('cid', r'CCU4.*')]
end_of_line = '\n'
# inheriting the HasIodev mixin creates us the things needed for talking
@ -108,7 +55,11 @@ CCU4 luckily has a very simple and logical protocol:
assert name == 'h' # check that we got a reply to our command
return txtvalue # the framework will automatically convert the string to a float
This is already a very simple working He Level meter driver. For a next step, we want to improve it:
The class :class:`CCU4`, an extension of (:class:`secop.stringio.StringIO`) serves as
communication class.
Above is already the code for a very simple working He Level meter driver. For a next step,
we want to improve it:
* We should inform the client about errors. That is what the *status* parameter is for.
* We want to be able to configure the He Level sensor.
@ -254,3 +205,4 @@ the parameters *empty* and *full* from the client by defining:
However, we do not do this here, as it is nice to try out chaning parameters for a test!
**name** *(x)*