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

Prepare for xDEVS Python 3.0.0 #17

Merged
merged 62 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
56ca6c3
Real time simulation
OscarFdezS Dec 19, 2022
31be89b
Real time simulation V2
OscarFdezS Dec 20, 2022
080b1ba
Real time simulation V2
OscarFdezS Dec 20, 2022
9839d94
Merge remote-tracking branch 'origin/dev-rt' into dev-rt
OscarFdezS Dec 21, 2022
b85d16a
Real time simulation V3
OscarFdezS Dec 31, 2022
5542677
Real time simulation V4
OscarFdezS Jan 23, 2023
74e0731
Update .gitignore
romancardenas Jan 23, 2023
8e2590d
Update sim.py
romancardenas Jan 23, 2023
391df81
Experimental external event injection
romancardenas Feb 3, 2023
de04ff0
Update sim.py
romancardenas Feb 9, 2023
beae260
Manager_rt
OscarFdezS Mar 3, 2023
7127c40
Manager_rt V2
OscarFdezS Mar 5, 2023
51b3886
rt_manager
OscarFdezS Mar 6, 2023
dc9f7d1
Review
romancardenas Mar 6, 2023
76b9396
Minor changes
romancardenas Mar 6, 2023
370f300
Window msg update
OscarFdezS Mar 7, 2023
fc5c252
Review
romancardenas Mar 8, 2023
f61be28
InputHandler (wip)
OscarFdezS Mar 10, 2023
3508093
Review
romancardenas Mar 12, 2023
6a9c4c5
csv_InputHandler (wip)
OscarFdezS Mar 12, 2023
156a834
CSV handler review
romancardenas Mar 13, 2023
9d37a5b
CSV documentation & format file check
OscarFdezS Mar 13, 2023
cc019f8
pretty-print errors
romancardenas Mar 14, 2023
8ab2807
OutputHandler and some documentation
OscarFdezS Apr 10, 2023
65ebf4c
Review
romancardenas Apr 11, 2023
65006b4
TCP handlers
OscarFdezS Apr 25, 2023
0d7d629
TCPOutputHandler
OscarFdezS Apr 25, 2023
e4b0f44
TCPOutputHandler update.
OscarFdezS Apr 26, 2023
7dd3ca5
Review (WIP)
romancardenas Apr 27, 2023
a078b1a
TCP reviewed
OscarFdezS Apr 29, 2023
5707683
Better logging and docs
romancardenas May 3, 2023
87eca7e
PoC: socket server instead of TCP server
romancardenas May 3, 2023
7b51314
MQTT approach
OscarFdezS May 7, 2023
3aceed8
AproachToDemoSystem
OscarFdezS May 10, 2023
b99032e
BackUpALL
OscarFdezS May 10, 2023
962d291
BackUpALL_2
OscarFdezS Jun 28, 2023
d91b1ee
LastCodeReview
OscarFdezS Oct 5, 2023
5fc964c
First approach JSON
OscarFdezS Oct 6, 2023
b591a8a
Coupled obtained from json
OscarFdezS Oct 17, 2023
dec580d
Component Factory implementation
OscarFdezS Oct 26, 2023
e282923
Doc
OscarFdezS Oct 27, 2023
1ce5b3c
Make MQTT dependency optional
romancardenas Oct 27, 2023
3ec278a
requests for change
romancardenas Oct 27, 2023
14a2a7a
Code organization and documentation
OscarFdezS Oct 30, 2023
1d5ec79
cleaning up repository
romancardenas Nov 14, 2023
5488450
cleaning everything for v3
romancardenas May 27, 2024
c1fd4f6
cleaning everything for v3
romancardenas May 27, 2024
5813aab
setting up CI
romancardenas May 27, 2024
2f81b63
fix conflicts
romancardenas May 27, 2024
20f9695
Add Cell-DEVS support
romancardenas Jun 25, 2024
c6c38ae
Fix Processor model
romancardenas Jun 25, 2024
7ad49b9
Fix transducible inheritance in Cell-DEVS messages
romancardenas Jun 25, 2024
b9055be
GPT example doc
OscarFdezS Jun 26, 2024
eeeb767
Renamed RTCoord simulate_rt method and refractor
OscarFdezS Jun 26, 2024
d8b4356
Fixed Tests
OscarFdezS Jun 27, 2024
7be80fd
README for abc and json
OscarFdezS Jun 27, 2024
95838c1
Renamed json example
OscarFdezS Jun 27, 2024
b139a1f
Fixed MQTT examples + some doc
OscarFdezS Jun 27, 2024
497765c
Project README + additional doc
OscarFdezS Jun 27, 2024
cc931d1
Doc clarification
OscarFdezS Jun 28, 2024
3d2949a
Add vsc to gitignore
OscarFdezS Jul 10, 2024
ba35bcb
Remove vsc files
OscarFdezS Jul 10, 2024
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
33 changes: 33 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Build and test
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
merge_group:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade importlib-metadata
pip install pytest
- name: install xDEVS
run: |
python -m pip install .
- name: Test with pytest
run: |
pytest
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,11 @@ dmypy.json

#MacOS stuff
.DS_Store

# Log File
*.log
*.csv

# visual studio code
.vscode/

26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Change Log

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added

- Add real-time simulation capabilities, including input and output handlers
- CI/CD pipeline for automated testing

### Changed

- Transitioned from setup.py to pyproject.toml for package configuration
- Updated dependencies to latest versions
- deltcon now does not accept any input arguments
- All abstract classes are now defined in the `abc` module
- All plugin factories are now defined in the `factory` module
- Minimum Python version is now 3.9

### Removed

- Faulty parallel simulator
File renamed without changes.
145 changes: 144 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,145 @@
# xdevs.py
# `xdevs.py`

Version of the xDEVS simulator for Python projects

The aim of this repository is to be able to simulate DEVS systems in both virtual and real-time environments using python.
However, additional features are being developed.

## Sections
1. [Quick Start](#quick-start)
2. [What to Expect](#what-to-expect)
3. [DEVS in a Nutshell](#devs-in-a-nutshell)
4. [Deepening the repository](#deepening-the-repository)


## Quick Start

1. Clone the repository:
````text
git clone https://github.com/iscar-ucm/xdevs.py.git
````
2. Navigate to the project directory
```text
cd xdevs
```
3. Install the package
```text
pip install .
```

**Now you're ready to start using xDEVS.py for your DEVS simulations!**

In case additional dependencies (`sql`, `elasticsearch` or `mqtt`) are required, they can be installed.
To add MQTT support with paho-mqtt:
```text
pip install .[mqtt]
```


## What to Expect

This section summarizes what you may find in the repository folder structure.

* ### Folder abc:
* The abstract classes folder contains the handler and transducer files. These folders contain the classes that define the general behavior and structure that each I/O handler or Transducer must follow.

* ### Folder celldevs:
* Contains the implementation of CellDEVS.

* ### Folder examples

* Inside this folder, you will find a collection of examples to try and execute in both virtual and wall-clock simulations. Each sub-folder represents an independent case study:
- CellDevs
- Devstone
- Gpt
- Json
- Store


* ### Folder plugins

* This folder encapsulates a collection of folders. Each subfolder stores the implementations of each of the abstract classes. For example, in the `input_handlers` subfolder, you will find several implementations for the Input Handler.

* ### Folder tests

* This folder is dedicated to storing the tests for GitHub Actions.

* ### Factory.py

* This script is in charge of creating the different types of implementations of an abstract class based on a key that is linked to the desired implementation.

* ### Models.py

* It has the basic `DEVS` models such as `Atomic`, `Coupled` `Component`, or `Port`.

* ### Rt.py

* It has the adaptation of the `sim.py` components to the real-time simulation methodology developed.

* ### Sim.py

* It has the `DEVS` components to carry out a simulation based on the abstract simulator mechanism.

## DEVS in a Nutshell

Discrete Event System Specification (DEVS) is a mathematical formalism with modular and hierarchical characteristics. DEVS is based on discrete event simulation where events occur chronologically in discrete instants of time and result in a change of the system.

DEVS is mainly based on atomic and coupled models.

### Atomic Model

An atomic model is the smallest representation of a system. It may remain in a state (S) for a certain time (ta); once the time has passed, it executes the internal transition function (`deltint`). This function will define what to do next for each state. However, if during that time something external occurs, the model reacts with its external transition function (`deltext`) that describes what to do in this case. If the external event occurs at the same time the `ta` has elapsed, the confluent transition function (`deltcon`) defines what to do next. Finally, the output function (`lambdaf`) defines for each state what should be done when transitioning between states. It is only executed after the internal transition function.

### Coupled Model

A coupled model defines the connections among atomic models and other coupled models.

### Simulation Mechanism

To simulate a system composed of atomic and coupled models, the abstract simulator mechanism is used. This methodology defines the simulators and coordinators. A simulator is attached to an atomic model, while the coordinator is attached to a coupled model. The coordinator will be in charge of carrying out the simulation.

Refer to the xDEVS user’s manual for further and deeper understanding [here](https://iscar-ucm.github.io/xdevs/).


## xDEVS.py Wall-clock Simulation

A real-time simulation intends to match the virtual time into a wall-clock time. The methodology followed in this repository to achieve the real-time behaviour is based on the arrival of external events. The system will remain waiting for external events between states, when an external event occurs the system will react according to its particular behaviour.

In this repository, a `RealTimeManager` and a `RealTimeCoordinator` must be combined to achieve a wall-clock simulation. In addition, if the system requires the handling of input and output events, the `input_handler` and `output_handler` will be used.

### System overview

The next picture shows the system overview and how the different components interact with each other

![System Overview](xdevs/images/sysoverview_small.png
)
1. The `input_handler` acts are the interface for any incoming event to the system sending it to the `RealTimeManager`.
2. The `RealTimeCoordinator` send the events collected from the `RealTimeManager` to the `DEVS` model.
3. The `DEVS` model may eject events out of the system, so they are routed to the `RealTimeManager`.
4. Finally, those outgoing events are forwarded to the `output_handler` which act as an interface to send the events.

In order to execute real-time simulations examples go to `xdevs.examples.gpt.README`


## Deepening the repository

In order to deepen the repository and understand the different functionalities, the following sections should be checked:


* What is a Factory? go to `xdevs.abc.README`

* xDEVS.py simulations? go to `xdevs.examples.gpt.README`

* JSON to xDEVS.py simulation? go to `xdevs.examples.json.README`

* TCP examples? go to `xdevs.examples.gps.README` or `xdevs.examples.store.README`

* MQTT examples? go to `xdevs.examples.store.README`



___

Feel free to contribute to the project by opening issues or submitting pull requests.


72 changes: 72 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
[build-system]
requires = ["setuptools >= 61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "xdevs"
version = "3.0.0"
requires-python = ">=3.9"
authors = [
{name = "Román Cárdenas"},
{name = "Óscar Fernández Sebastián"},
{name = "Kevin Henares"},
{name = "José L. Risco-Martín"},
]
maintainers = [
{name = "Román Cárdenas", email = "[email protected]"},
]
description = "xDEVS M&S framework"
readme = "README.md"
license = {file = "LICENSE.txt"}
keywords = ["DEVS", "modeling", "simulation"]

[project.optional-dependencies]
sql = ["sqlalchemy"]
elasticsearch = ["elasticsearch"]
mqtt = ["paho-mqtt"]

[project.urls]
Homepage = "https://github.com/iscar-ucm/xdevs"
Documentation = "https://github.com/iscar-ucm/xdevs"
Repository = "https://github.com/iscar-ucm/xdevs.py.git"
"Bug Tracker" = "https://github.com/iscar-ucm/xdevs.py/issues"
Changelog = "https://github.com/iscar-ucm/xdevs.py/blob/main/CHANGELOG.md"

[project.entry-points."xdevs.transducers"]
csv = "xdevs.plugins.transducers.csv:CSVTransducer"
sql = "xdevs.plugins.transducers.sql:SQLTransducer"
elasticsearch = "xdevs.plugins.transducers.elasticsearch:ElasticsearchTransducer"

[project.entry-points."xdevs.input_handlers"]
function = "xdevs.plugins.input_handlers.function:CallableFunction"
csv = "xdevs.plugins.input_handlers.csv:CSVInputHandler"
tcp = "xdevs.plugins.input_handlers.tcp:TCPInputHandler"
mqtt = "xdevs.plugins.input_handlers.mqtt:MQTTInputHandler"

[project.entry-points."xdevs.output_handlers"]
csv = "xdevs.plugins.output_handlers.csv:CSVOutputHandler"
tcp = "xdevs.plugins.output_handlers.tcp:TCPOutputHandler"
mqtt = "xdevs.plugins.output_handlers.mqtt:MQTTOutputHandler"

[project.entry-points."xdevs.components"]
generator = "xdevs.examples.gpt.models:Generator"
transducer = "xdevs.examples.gpt.models:Transducer"
processor = "xdevs.examples.gpt.models:Processor"
gpt = "xdevs.examples.gpt.models:Gpt"
ef = "xdevs.examples.gpt.models:Ef"
efp = "xdevs.examples.gpt.models:Efp"

[project.entry-points."xdevs.wrappers"]
pypdevs = "xdevs.plugins.wrappers.pypdevs:PyPDEVSWrapper"

[project.entry-points."xdevs.celldevs_outputs"]
hybrid = "xdevs.plugins.celldevs_outputs.hybrid:HybridDelayedOutput"
inertial = "xdevs.plugins.celldevs_outputs.inertial:InertialDelayedOutput"
transport = "xdevs.plugins.celldevs_outputs.transport:TransportDelayedOutput"

[tool.setuptools]
include-package-data = false

[tool.setuptools.packages.find]
include = ["xdevs*"]
exclude = ["xdevs.tests*"]
23 changes: 0 additions & 23 deletions setup.py

This file was deleted.

34 changes: 24 additions & 10 deletions xdevs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import math
from __future__ import annotations
import functools
import logging
import math
import sys
from typing import TypeVar
import warnings

T = TypeVar('T')

INFINITY = math.inf
PHASE_PASSIVE = "passive"
PHASE_ACTIVE = "active"
INFINITY: float = math.inf
PHASE_PASSIVE: str = "passive"
PHASE_ACTIVE: str = "active"

DEBUG_LEVEL = None
loggers = dict()
DEBUG_LEVEL: int | str | None = None
LOGGERS: dict[str, logging.Logger] = dict()


def get_logger(name, dl=None):
if name in loggers:
return loggers[name]
def get_logger(name: str, dl: int | str = None):
if name in LOGGERS:
return LOGGERS[name]
else:
logger = logging.getLogger(name)

Expand All @@ -24,5 +30,13 @@ def get_logger(name, dl=None):
else:
logger.disabled = True

loggers[name] = logger
LOGGERS[name] = logger
return logger


def deprecated(func):
@functools.wraps(func)
def new_func(*args, **kwargs):
warnings.warn(f"Call to deprecated function {func.__name__}.", category=DeprecationWarning, stacklevel=2)
return func(*args, **kwargs)
return new_func
24 changes: 24 additions & 0 deletions xdevs/abc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# What is a Factory

A factory is a software methodology for designing and implementing objects that have a common behavior but several possible implementations. This type of methodology is widely used in this repository for creating different components in the simulations such as transducers, handlers, models, etc.

## Example 1
_(Focused on handlers, transducer and celldevs)_

1. Firstly, a father abstract class is defined, which states the common behavior of the component under developing. (The class `InputHandler` may be found in `xdevs.abc.handler`)
2. A child class that inherits the behavior of its father defines the particular implementation. (The folder `xdevs.plugins.input_handlers.` stores several implementations for this class)
3. An entry point is defined. This name will play the role of a key that links the name to the desired implementation. (In the script `xdevs.pyproject`, the keys for Input Handlers are found after the `[project.entry-points."xdevs.input_handlers"]` statement)
4. Creating an instance of each implementation is as easy as passing to a method of the factory class the desired key and the required parameters (if any) for that specific implementation (Using the class `InputHandlers` in `xdevs.factory` and calling the method `create_input_handler`).

## Example 2

_(Focused on `JSON` to `DEVS` components)_

In case of the `JSON` to `DEVS` model conversion, the factory methodology is used to create the components defined in the `JSON` file. The `Factory` class is in charge of creating the different types of implementations of an abstract class based on a key that is linked to the desired implementation.

1. The `DEVS` model must be defined (i.e. `EFP` in `xdevs.examples.gpt.models`).
2. The entry point must be created in pyproject.toml after `[project.entry-points."xdevs.components"]`

With this methodology, adding several instances of a component for a range of simulations is easier.
Defining a key that links to the desired implementation allows for a more straightforward way to create the components
and avoids having to create and define each component for each simulation.
3 changes: 3 additions & 0 deletions xdevs/abc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .celldevs import DelayedOutput
from .handler import InputHandler, OutputHandler
from .transducer import Transducer
Loading