Event-based hardware simulation framework

Related tags

Hardwaretickit
Overview

tickit

Code CI Docs CI Test Coverage Latest PyPI version Apache License

An event-based multi-device simulation framework providing configuration and orchestration of complex multi-device simulations.

PyPI pip install tickit
Source code https://github.com/dls-controls/tickit
Documentation https://dls-controls.github.io/tickit
Changelog https://github.com/dls-controls/tickit/blob/master/CHANGELOG.rst

An example device which emits a random value between 0 and 255 whenever called and asks to be called again once the simulation has progressed by the callback_period:

None: self.callback_period = SimTime(callback_period) def update(self, time: SimTime, inputs: Inputs) -> DeviceUpdate[Outputs]: output = randint(0, 255) LOGGER.debug( "Boing! (delta: {}, inputs: {}, output: {})".format(time, inputs, output) ) return DeviceUpdate( RandomTrampoline.Outputs(output=output), SimTime(time + self.callback_period), ) ">
class RandomTrampoline(ConfigurableDevice):

Inputs: TypedDict = TypedDict("Inputs", {})
Outputs: TypedDict = TypedDict("Outputs", {"output": int})

def __init__(self, callback_period: int = int(1e9)) -> None:
    self.callback_period = SimTime(callback_period)

def update(self, time: SimTime, inputs: Inputs) -> DeviceUpdate[Outputs]:
    output = randint(0, 255)
    LOGGER.debug(
        "Boing! (delta: {}, inputs: {}, output: {})".format(time, inputs, output)
    )
    return DeviceUpdate(
        RandomTrampoline.Outputs(output=output),
        SimTime(time + self.callback_period),
    )

An example simulation defines a RemoteControlled device named tcp_contr and a Sink device named contr_sink. The observed output of tcp_contr is wired to the input input of contr_sink. Additionally, extenal control of tcp_contr is afforded by a RemoteControlledAdapter which is exposed extenally through a TCPServer:

- tickit.core.components.device_simulation.DeviceSimulation:
    adapters:
    - examples.devices.remote_controlled.RemoteControlledAdapter:
        server:
        tickit.adapters.servers.tcp.TcpServer:
            format: "%b\r\n"
    device:
    examples.devices.remote_controlled.RemoteControlled: {}
    inputs: {}
    name: tcp_contr
- tickit.core.components.device_simulation.DeviceSimulation:
    adapters: []
    device:
    tickit.devices.sink.Sink: {}
    inputs:
    input: tcp_contr:observed
    name: contr_sink

See https://dls-controls.github.io/tickit for more detailed documentation.

Comments
  • Change deserialization based around ComponentConfig instances

    Change deserialization based around ComponentConfig instances

    The YAML looks cleaner now, but there's some ugliness:

    • DeviceSimulation sets Adapter.device and Adapter.raise_interrupt~~, mypy complains about the latter~~
    • Component vs BaseComponent, mypy doesn't like returning a DeviceSimulation when the call signature says it wants a Component
    • I find myself wanting to write class TCPServer(Server). Should Server, Adapter, Component be abstract base classes instead of protocols?
    • Does the contents of configurable.py belong in component.py?

    I expect there will be more issues as I convert the rest, but I wanted to PR early...

    Fixes #4

    opened by thomascobb 7
  • 'click' module not included in default installation.

    'click' module not included in default installation.

    When trying to run tickit using the default installation I discovered that the click module is missing. This does raise the question of what else might be missing from the default installation and whether this points to a gap in our testing suite that this went unnoticed until now.

    bug 
    opened by collang 5
  • Simulate a motorRecord

    Simulate a motorRecord

    It would be useful to be able to use an EpicsAdapter to simulate a motorRecord. Currently we cannot do this as https://github.com/dls-controls/pythonSoftIOC does not support motor records

    opened by DominicOram 4
  • Configuration snippits in README.md and docs/* are outdataed

    Configuration snippits in README.md and docs/* are outdataed

    The configuration snippet in README.md and those throughout the documentation were not updated alongside #16, as such the continue to contain the outdated, verbose, configuration format. These snippets should be updated to conform to the current format.

    documentation 
    opened by garryod 3
  • Bugged entries in

    Bugged entries in "Pipfile.lock"

    There's a few entries in the master branch of Pipfile.lock which cause issues with the installation:

    On python3.8 and python3.9 I get apischema.validation.ValidationError("No module named typing-extensions"). As we can see, the module will only be installed for python<3.8.

    "typing-extensions": {
                "hashes": [
                    "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e",
                    "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7",
                    "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"
                ],
                "markers": "python_version < '3.8' and python_version < '3.8'",
                "version": "==3.10.0.2"
            },
    

    As I understand, this module should only be required for python<=3.8 but the error will also be raised when running python3.9.

    Similarly, mypy will only be installed for python==3.7:

    "mypy": {
                "hashes": [
                    "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9",
                    "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a",
                    "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9",
                    "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e",
                    "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2",
                    "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212",
                    "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b",
                    "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885",
                    "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150",
                    "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703",
                    "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072",
                    "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457",
                    "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e",
                    "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0",
                    "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb",
                    "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97",
                    "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8",
                    "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811",
                    "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6",
                    "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de",
                    "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504",
                    "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921",
                    "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"
                ],
                "markers": "python_version < '3.8'",
                "version": "==0.910"
            }
    

    Steps to reproduce:

    1. make a new virtual environment with python>3.7
    2. install pipenv to the virtual environment
    3. make sure your version of tickit is up to date with the master branch
    4. run pipenv install --dev
    5. run python3 -m tickit all examples/configs/current-monitor.yaml, you should get an apischema.validation.errors.ValidationError
    6. run python3 -m pytest tests/, you should receive a ModuleNotFoundError: No module named 'mypy' message.
    opened by collang 3
  • Increase test coverage

    Increase test coverage

    Adds tests for EpicsAdapter, CryostreamBase Cryostream, Femto, Pneumatic and Cli.

    Some general improvements to the Femto, CryostreamBase and EpicsAdapter have also ended up here.

    opened by collang 3
  • Containerise Tickit

    Containerise Tickit

    TODO:

    • [x] Dockerfile which contains a 3-stage build, see https://github.com/epics-containers/epics-base/blob/main/Dockerfile for an example multi-stage build.
    • [x] Stage 1: Base stage
    • [x] Stage 2: Dev stage
    • [x] Stage 3: Runtime stage
    • [x] Stages 2 and 3 are based on 1
    • [x] CI to publish images, see https://github.com/epics-containers/epics-base/blob/main/.github/workflows/buiild.yml

    Add to review: @callumforrester @thomascobb @gilesknap

    enhancement 
    opened by callumforrester 3
  • (De)serialization rework

    (De)serialization rework

    The current (de)serialization system is clunky, it requires significant rework to improve usability of the library.

    Current System

    The current system operates by defining "config" classes for each interface (e.g. DeviceConfig for Device(Protocol)); such classes act as an apischema tagged union of derived "config" classes. User classes are made configurable by the addition of a nested "config" class (via a decorator or inheritance of a type which applies the decorator), which joins the tagged union of it's template.

    At deserilization time, all classes referenced by the configuration file must be loaded prior to apischema deserialzation such that the nested config classes can be created. This necessitates an ugly two stage process in which the config file is first parsed for fully qualified names to load them, and then parsed again to perform deserialization.

    On the end user front, this requires the following boilerplate:

    class MyDevice(ConfigurableDevice):
        ...
    

    Such that MyDevice can be given a nested class MyDeviceConfig which subtypes DeviceConfig, allowing for apischema deserialization by tagged union where the qualified name of MyDevice.

    Target System

    An ideal system would have the following benefits over the current system:

    • Requires no additional boilerplate for the end user
    • Removes the need for passing of "config" objects
    • Perform a single parsing of the configuration file

    Proposed System

    I expect deserialization would likely operate as follows, though I would love to hear suggestions of alternatives:

    The config file (yaml) is read & parsed with `PyYAML`
    Recursively, for each object in the parsed config:
        If module of object not already loaded:
            Load module of object
            Generate config (data)class for object type - based on __init__ signature
        Check class is instance of the expected type
        Check generated config class is instance of the config of the expected type (possibly superfluous)
        Instantiate config with configured parameters
        Build object and pass / pass config
    

    The primary issue with this system stems from the fact that we wish to inject some init arguments during the instantiation process, there exist several possible solutions to this problem, the merits of which must be weighed:

    1. Allow for passing of either built objects or configs which implement a build() method which takes injected arguments
    2. Do not perform argument injection in __init__, instead pass them to methods such as run_forever()
    3. Require passing of configs which implement a build() method which takes injected arguments
    enhancement 
    opened by garryod 3
  • Pin flake8 version

    Pin flake8 version

    See https://github.com/tholo/pytest-flake8/issues/87

    To test:

    • Run the CI with no lock on main, confirm flake8 is broken
    • Run on this branch, confirm it works
    opened by DominicOram 1
  • Update docs

    Update docs

    Updating the docs to be split into user and dev docs.

    I am currently moderately happy with the state of the user docs and could do with feedback @callumforrester .

    I have not yet really done anything for the dev docs, I figured once I had figured out the right level for the user ones it would become more clear, which I think it has.

    I also tried to partially adopt the new pip3 skeleton style docs as it has the preferential format, but that does not build the docs right now.

    opened by abbiemery 2
  • Make user interface for components more friendly

    Make user interface for components more friendly

    Currently to set up a component you have to override the __call__ method of ComponentConfig. This is user facing so should be made to avoid a dunder method.

    Maybe something like:

    @component
    def my_detector(thing: int, other_thing: str) -> Component:
        return DeviceSimulation(
            MyDetectorDevice(thing),
            MyDetectorAdapter(other_thing)
        )
    
    needed next 
    opened by abbiemery 0
  • Fix Disjoining Components

    Fix Disjoining Components

    The disjoining component fix didn't actually work and so needs fixing. It is likely to be fixed within the future developments needed for the Zebra since we would want all simulations run as 'tickit in tickit' system simulations, so any disconnected input is actually connected to a shared larger starting input.

    However, I wanted to note this down in case somebody found it not working.

    needed next 
    opened by abbiemery 0
  • 93 change regex command

    93 change regex command

    Requires #89 Fixes #92 and #93 Required for #90

    • Allows for RegexCommand to parse from data of type AnyStr rather than just bytes.
    • RegexCommand.parse now also returns the start and end indices of the match within the message, as well as the length of the message matched against. This gives enough information for MultiCommandInterprerter to strip off a matched command and for CommandInterpreter to check for a full match.
    • CommandInterpreter.handle logic updated to use the new return signature.
    • Tests added for RegexCommand and CommandInterpreter
    opened by MattPrit 1
  • Have RegexCommand.parse return more information

    Have RegexCommand.parse return more information

    Required for #90 The more complex MultiCommandInterpreter requires more information to be returned form parse. Specifically, it requires information about where within the message a match is found; these indices need to be with respect to the original message, not (if applicable) the message after it has been decoded. This could be achieved by encoding the regex pattern rather than decoding the message when format is not None. Since there will be changes to the return signature of Command.parse, the handle method of CommandInterpreter will need to be updated.

    opened by MattPrit 0
Releases(0.1.1)
Owner
Diamond Light Source Controls Group
Diamond Light Source Controls Group
Sticklog2heatmap - Draw a heatmap of RC sticks from OpenTX logs or USB HID device

sticklog2heatmap Draw a heatmap of RC sticks from OpenTX logs or USB HID device

2 Feb 02, 2022
Skykettle ha - Redmond SkyKettle integration for Home Assistant

Redmond SkyKettle integration for Home Assistant This integration allows to cont

Alexey 'Cluster' Avdyukhin 48 Jan 06, 2023
Estimation of whether or not the persons given information will have diabetes.

Diabetes Business Problem : It is desired to develop a machine learning model that can predict whether people have diabetes when their characteristics

Barış TOKATLIOĞLU 0 Jan 20, 2022
Inykcal is a software written in python for selected E-Paper displays.

Inykcal is a software written in python for selected E-Paper displays. It converts these displays into useful information dashboards. It's open-source, free for personal use, fully modular and user-f

Ace 727 Jan 02, 2023
Ingeniamotion is a library that works over ingenialink and aims to simplify the interaction with Ingenia's drives.

Ingeniamotion Ingeniamotion is a library that works over ingenialink and aims to simplify the interaction with Ingenia's drives. Requirements Python 3

Ingenia Motion Control 7 Dec 15, 2022
This is an incredible led matrix simulation using the ultimate mosaik co-simulation framework.

This project uses the mosaik co-simulation framework, developed by the brilliant developers at the high-ranked Offis institue for computer science, Oldenburg, Germany, to simulate multidimensional LE

Felix 1 Jan 28, 2022
Transform a Raspberry Pi into a network diagnostic machine.

EtherView Last updated jan 30, 2022. Welcome to the EtherView project! This is a project to transform a RaspberryPi into a portable network diagnostic

1 Jan 30, 2022
This repo uses a stereo camera and gray-code-based structured light to realize dense 3D reconstruction.

Structured-light-stereo This repo uses a stereo camera and gray-code-based structured light to realize dense 3D reconstruction. . How to use: STEP 1:

FEI 20 Dec 31, 2022
A script that publishes power usage data of iDrac enabled servers to an MQTT broker for integration into automation and power monitoring systems

iDracPowerMonitorMQTT This script publishes iDrac power draw data for iDrac 6 enabled servers to an MQTT broker. This can be used to integrate the pow

Lucas Zanchetta 10 Oct 06, 2022
A Python program that makes it easy to manage modules on a CircuitPython device!

CircuitPython-Bundle-Manager-v2 A Python program that makes it easy to manage modules on a CircuitPython device! The CircuitPython Bundle Manager v2 i

Ckyiu 1 Dec 18, 2021
Home Assistant custom components MPK-Lodz

MPK Łódź sensor This sensor uses unofficial API provided by MPK Łódź. Configuration options Key Type Required Default Description name string False MP

Piotr Machowski 3 Nov 01, 2022
Pure micropython ESP32 SPI driver for sdcard and screen at the same SPI bus

micropython-esp32-spi-sdcard-and-screen-driver Proof of concept of Pure micropython espidf SPI driver for sdcard with screen at the same SPI bus (exam

Thomas Favennec 7 Mar 14, 2022
Modeling and Simulation of Satellite Servicing Manipulators

Modeling and Simulation of Satellite Servicing Manipulators Final Project for the course ENPM662: Introduction to Robot Modeling (Fall 2021). This pro

Adarsh M 1 Jan 24, 2022
A iot Bike sytem based on RaspberryPi, Ardiuino

Cyclic 's Kernel ---- A iot Bike sytem based on RaspberryPi, Ardiuino, etc 0x1 What is This? Cyclic 's Kernel is an independent System With self-produ

Retr0mous 2 Oct 09, 2022
This application works with serial communication. Use a simple gui to send and receive serial data from arduino and control leds and motor direction

This application works with serial communication. Use a simple gui to send and receive serial data from arduino and control leds and motor direction

ThyagoKZKR 2 Jul 18, 2022
Hardware: CTWingSKIT_BC28 Development Toolkit

IoT Portal Monitor Tools hardware: CTWingSKIT_BC28 Development Toolkit serial port driver: ST-LINK hardware development environment: Keli 5 MDK IoT pl

Fengming Zhang 1 Nov 07, 2021
Play a song with a 3D printer.

MIDI to GCODE Play a song with a FDM 3D printer. SLA printers don't have motors, so they cannot play music. Warning: Be ready to turn off the 3D print

Patrick 6 Apr 11, 2022
Examples to accompany the

Examples to accompany the "Raspberry Pi Pico Python SDK" book published by Raspberry Pi Trading, which forms part of the technical documentation in support of Raspberry Pi Pico and the MicroPython po

Raspberry Pi 589 Jan 08, 2023
A small Python app to converse between MQTT messages and 433MHz RF signals.

mqtt-rf-bridge A small Python app to converse between MQTT messages and 433MHz RF signals. This acts as a bridge between Paho MQTT and rpi-rf. Require

David Swarbrick 3 Jan 27, 2022
An IoT Trivia app that shows you how to take a JSON web API such as the opentdb.com API and stream and display it on a FeatherS2 in an OLED display.

CircuitPython IoT Trivia ESP32-S2 OLED Version An IoT Trivia app that shows you how to take a JSON web API such as the opentdb.com API and stream and

Kevin Thomas 1 Nov 27, 2021