Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update configuration examples in docs #135

Merged
merged 4 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ Added:
Changed:

- Reworked config (de)serialization

- User may now reference the :code:`ComponentConfig`, which encapsulate a device and adapters
- Device & Adapter config classes are no longer autmatically generated, configuration should be performed via the :code:`ComponentConfig`
- Device & Adapter config classes are no longer automatically generated, configuration should be performed via the :code:`ComponentConfig`

- Made :code:`Device` a typed :code:`Generic` of :code:`InMap` and :code:`OutMap`

Expand All @@ -56,7 +56,7 @@ Initial release, with:
- EPICS
- Example Devices:
- Remote Controlled (properties set via an adapter)
- Shutter (I/O iteraction and continuous motion)
- Shutter (I/O interaction and continuous motion)
- Trampoline & RandomTrampoline (recurring call-backs)
- Real Devices:
- Cryostream (sample cryo-cooler)
Expand Down
10 changes: 5 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Documentation https://dls-controls.github.io/tickit
Releases https://github.com/dls-controls/tickit-devices/releases
============== ==============================================================

An example simulation consits of a simple counter and a sink. The counter
An example simulation consists of a simple counter and a sink. The counter
increments up a given value and then passes this value to a sink.

A simulation is defined using a yaml file, in which the graphing of the required
Expand All @@ -24,22 +24,22 @@ to the input of **counter_sink**.
.. code-block:: yaml

- examples.devices.counter.Counter:
name: counter
name: counter
inputs: {}
- tickit.devices.sink.Sink:
name: counter_sink
inputs:
input: counter:_value


This file is executed to run the simultation.
This file is executed to run the simulation.

.. code-block:: bash

python -m tickit all examples/configs/counter.yaml


The simulation will output logs depicting the incerementing of the counter:
The simulation will output logs depicting the incrementing of the counter:

.. code-block:: bash

Expand All @@ -52,7 +52,7 @@ The simulation will output logs depicting the incerementing of the counter:
DEBUG:tickit.core.management.schedulers.base:Scheduling counter for wakeup at 1000000000
DEBUG:tickit.core.components.component:counter_sink got Input(target='counter_sink', time=0, changes=immutables.Map({}))
DEBUG:tickit.devices.sink:Sunk {}
DEBUG:tickit.core.management.schedulers.base:Scheduler got Output(source='counter_sink', time=0, changes=immutables.Map({}), call_at=None)
DEBUG:tickit.core.management.schedulers.base:Scheduler got Output(source='counter_sink', time=0, changes=immutables.Map({}), call_at=None)
DEBUG:tickit.core.management.ticker:Doing tick @ 1000000000
DEBUG:tickit.core.components.component:counter got Input(target='counter', time=1000000000, changes=immutables.Map({}))
DEBUG:examples.devices.counter:Counter incremented to 2
Expand Down
36 changes: 18 additions & 18 deletions docs/developer/explanations/framework-details.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ Framework Details
=================

Tickit is an event-based simulation framework allowing for the simulation of
complex mutli-device systems.
complex multi-device systems.

A tickit simulation consists of a scheduler and components, all of which
communicate via a message bus.
communicate via a message bus.

.. figure:: ../../images/tickit-overview-full.svg
:align: center
Expand All @@ -24,33 +24,33 @@ The scheduler
-------------

The main parts of the scheduler are the state consumer and producer, and the
ticker.
ticker.

State Consumer and producer
+++++++++++++++++++++++++++

The consumer and producer are for the messaging between the scheduler and
the system components via the message bus. This is organised with topics that
messages can be published to and that consumers can be subsribed to in order to
recieve those messages. The scheduler sets up the consumer to handle messages
in a given way and subscribes its self to the output topic of every component
messages can be published to and that consumers can be subscribed to in order to
receive those messages. The scheduler sets up the consumer to handle messages
in a given way and subscribes itself to the output topic of every component
in the system.

Whenever a device produces a device update, the scheduler consumes that output
and propgates it to the relevent inputs via the ticker.
and propagates it to the relevant inputs via the ticker.

The ticker
++++++++++

The ticker contains the logic for the propogation of an update through the system.
The ticker contains the logic for the propagation of an update through the system.



One update cycle
----------------

When the simulation starts it initalises all of the components and runs through
its first tick.
When the simulation starts it initialises all of the components and runs through
its first tick.


The scheduler contains a list of wakeups, which is a dictionary of component ids
Expand All @@ -59,31 +59,31 @@ and simtimes of when that component wants calling back.
(these wakeups are the callbacks requested with the `DeviceUpdate` returned when
you run a device update.)

If there are no scheduled wakeups then the system will wait untill a new wake up
is created. This is done via an interupt. These can be caused by an adapter
If there are no scheduled wakeups then the system will wait until a new wake up
is created. This is done via an interrupt. These can be caused by an adapter
changing something on a device. In this case an immediate wake up is scheduled
for the device the adapter is connected to.

When we have a scheduled wakeups the scheduler will check its dictionary of wakeups
to find the shortest time to the next wakeup and will then find the set of
components which requested a wakeup at that time. This will often only be one component
components which requested a wakeup at that time. This will often only be one component
but could be multiple.

We then wait for one of two events to occur. Either the time until the wake up
elapses, or we are interupted in that time by an immidiate wakeup.
elapses, or we are interrupted in that time by an immediate wakeup.

Lets say we are not interupted and the scheduled wakeup occurs.
Lets say we are not interrupted and the scheduled wakeup occurs.

The ticker is then called for that time, with each component in the set in turn.
one call of the ticker will begin a tick at that time, update the component,
wait for the scheduler to recieve back an output and use that to acknoladge the
wait for the scheduler to receive back an output and use that to acknowledge the
component has updated, produce the input in the correct channel, then get the
next component in the graph to update. This propagates untill the last component
next component in the graph to update. This propagates until the last component
has updated and it passed back to the scheduler.

The real time is then stored and we go back to looking for the next wakeup.

Each tick as far as the simulation is concerned is instantanous, therefore over
Each tick as far as the simulation is concerned is instantaneous, therefore over
time we can expect sim time to lag real time. This is mostly negligible but
could potentially cause issues in larger more complex systems.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Whilst if *Component A* is the **root** all components require an update.
Schedule possible updates
~~~~~~~~~~~~~~~~~~~~~~~~~

Next, we schedule updates for all components whos dependencies have been
Next, we schedule updates for all components whose dependencies have been
resolved; Dependency resolution is established by checking whether any of their
dependencies remain in ``to_update``. In the example where *Component A* serves
as the **root**, only *Component A* may have an update scheduled as all other
Expand All @@ -50,12 +50,12 @@ Handle responses
~~~~~~~~~~~~~~~~

When a component update is completed and the corresponding response is
recieved, the component can be removed from ``to_update`` and `schedule
received, the component can be removed from ``to_update`` and `schedule
possible updates if incomplete`_.

Schedule possible updates if incomplete
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If ``to_update`` is now empty we can assert that the state of the simulation
has been brought up to date and complete the tick, otherwise we `schedule
possible updates`_ and `handle responses`_ as performed previously.
possible updates`_ and `handle responses`_ as performed previously.
5 changes: 2 additions & 3 deletions docs/developer/explanations/why-tickit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ devices.
event-based
-----------

Being event based each device in the system only updates when relevent. A
Being event based each device in the system only updates when relevant. A
device update can be triggered by interrupts caused by changes from other
linked devices or adapters, or by a devices own scheduled callbacks.

Expand All @@ -36,7 +36,6 @@ downstream device.
Bus based communication
-----------------------

Tickit uses message busses as a basis for the communication between its
Tickit uses message buses as a basis for the communication between its
devices. This was chosen in an attempt to simplify communication and to try
and produce a less coupled system than is achievable with RPC.

2 changes: 0 additions & 2 deletions docs/developer/how-to/lint.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,3 @@ VSCode support

The ``.vscode/settings.json`` will run black and isort formatters as well as
flake8 checking on save. Issues will be highlighted in the editor window.


2 changes: 1 addition & 1 deletion docs/developer/how-to/run-tests.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ like tests`_, and run them to check for errors. You can run it with::

$ tox -e pytest

It will also report coverage to the commandline and to ``cov.xml``.
It will also report coverage to the command line and to ``cov.xml``.

.. _pytest: https://pytest.org/
.. _look like tests: https://docs.pytest.org/explanation/goodpractices.html#test-discovery
12 changes: 6 additions & 6 deletions docs/user/explanations/adapters.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Adapters
========

Adpaters are user implemented classes associated with a device which facilitate
Adapters are user implemented classes associated with a device which facilitate
interactions between that device and components external to the simulation.
Adapters allow us to influence the device from outside the simulation, such as
using a TCP client to alter a parameter on a device. A device may have multiple
Expand All @@ -21,12 +21,12 @@ the hosting of an external messaging protocol to a server and message handling
to an interpreter.

Tickit currently includes one server implementation, a TCP server, and one
interpreter, the command interpreter.
interpreter, the command interpreter.

The command interpreter is a generic interpreter which identifies commands from
incoming messages. Commands are defined via decoration of adapter methods and
the only such command type currently is a `RegexCommand`. This matches incoming
messages to regex patterns and processes the command approprately.
messages to regex patterns and processes the command appropriately.

Tickit also includes three interpreter wrappers for the command interpreter.
These wrap the command interpreter to allow for more complex message handling
Expand All @@ -49,8 +49,8 @@ An adapter that hosts an HTTP server, e.g. for devices with REST APIs.
EPICS adapter
-------------
An adapter implementation that acts as an EPICS IOC. It utilises pythonSoftIOC
create an IOC in the process which hosts PV's which can be linked to attributes
create an IOC in the process which hosts PVs which can be linked to attributes
on the device.

This is useful for the simulation of devices which use hard IOC's since these
cannot interact with simulated devices.
This is useful for the simulation of devices which use hard IOCs since these
cannot interact with simulated devices.
28 changes: 14 additions & 14 deletions docs/user/explanations/components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,32 @@ System simulations can also contain their own system simulation components
allowing for the construction of reasonably complex systems.

System simulations can be nested inside other components in the config so that
the master scheduler's wiring is correct, for example:
the master scheduler's wiring is correct, for example:

.. code-block:: yaml

- examples.devices.trampoline.RandomTrampoline:
name: random_trampoline
inputs: {}
callback_period: 10000000000
name: random_trampoline
inputs: {}
callback_period: 10000000000
- tickit.core.components.system_simulation.SystemSimulation:
name: internal_tickit
inputs:
input_1: random_trampoline:output
input_1: random_trampoline:output
components:
- tickit.devices.sink.Sink:
name: internal_sink
inputs:
- tickit.devices.sink.Sink:
name: internal_sink
inputs:
sink_1: external:input_1
- examples.devices.remote_controlled.RemoteControlled:
name: internal_tcp_controlled
inputs: {}
- examples.devices.remote_controlled.RemoteControlled:
name: internal_tcp_controlled
inputs: {}
expose:
output_1: internal_tcp_controlled:observed
output_1: internal_tcp_controlled:observed
- tickit.devices.sink.Sink:
name: external_sink
inputs:
sink_1: internal_tickit:output_1
sink_1: internal_tickit:output_1

(See `SystemSimulationComponent`.)

Expand All @@ -73,4 +73,4 @@ A simulation containing both types of component will look something like this:


.. _DeviceSimulation: <tickit.core.device_simulation.DeviceSimulation>
.. _SystemSimulationComponent: <tickit.core.system_simulation.SystemSimulationComponent>
.. _SystemSimulationComponent: <tickit.core.system_simulation.SystemSimulationComponent>
2 changes: 1 addition & 1 deletion docs/user/explanations/devices.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Devices
=======

Tickit simulations revolve around devices. Devices are user implemented classes
which behaviours mimic the hardware you wish to simulate.
with behaviour that mimics the hardware you wish to simulate.

Any new device created must extend `Device`, have an update method, and must
have Input and Output maps as members. If these are not used they can be left
Expand Down
24 changes: 12 additions & 12 deletions docs/user/explanations/framework-summary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Framework Summary
=================

Tickit is an event-based simulation framework allowing for the simulation of
complex mutli-device systems.
complex multi-device systems.

A tickit simulation consists of a scheduler and :doc:`components<components>`, all of which
communicate via a message bus. The scheduler keeps simulation time running and
Expand All @@ -25,7 +25,7 @@ alter a parameter on a device.

Using the example Shutter_ to demonstrate. The ``ShutterDevice`` contains the
behaviour, the ``ShutterAdapter`` enables a TCP interface with the shutter, but
the actual ``Shutter`` is the component which encpsulates both.
the actual ``Shutter`` is the component which encapsulates both.

Scheduler
^^^^^^^^^
Expand All @@ -35,19 +35,19 @@ a simulation and primarily encapsulates the ticker.
The scheduler is instantiated with :doc:`wiring<wiring>` from the config
file used to start up the simulation. See tutorial :doc:`creating a simulation.<../tutorials/creating-a-simulation>`
With this wiring the scheduler knows which components are connected together and
therfore how to propogate messages and updates through the system.
therefore how to propagate messages and updates through the system.

The **ticker** contains the logic for the propogation of updates through the system.
When a component requests an update, either by a callback or an interupt, the
ticker updates that component then propogates the update to any component
The **ticker** contains the logic for the propagation of updates through the system.
When a component requests an update, either by a callback or an interrupt, the
ticker updates that component then propagates the update to any component
downstream.


Running a tickit simulation
---------------------------

When we *run* a simulation, we first initialise all our components, devices,
adapters and the scheduler. The scheduler runs the system through its inital
adapters and the scheduler. The scheduler runs the system through its initial
**tick**, updating every device in the system. The scheduler will then run
time on, waiting for next time it needs to update system components.

Expand All @@ -61,12 +61,12 @@ scheduler will then check if it has been asked by any device to call it back at
a given time. If it has, it will wait until that time then update the device and
again any downstream of it.

Adapters wait to recieve external interaction with the device. When this
interaction causes something to change on the device which is interupting, an
interupt is sent to the scheduler to let it know that the device needs updating
Adapters wait to receive external interaction with the device. When this
interaction causes something to change on the device which is interrupting, an
interrupt is sent to the scheduler to let it know that the device needs updating
immediately. The scheduler updates that device and then begins the cycle of
updating the rest. When it finishes the tick caused by the interupt, the scheduler
updating the rest. When it finishes the tick caused by the interrupt, the scheduler
continues to wait until the next update.


.. _Shutter: https://github.com/dls-controls/tickit/blob/master/examples/devices/shutter.py
.. _Shutter: https://github.com/dls-controls/tickit/blob/master/examples/devices/shutter.py
Loading