Dataclasses for the data representation
This commit is contained in:
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.venv/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.egg-info/
|
||||
build/
|
||||
dist/
|
||||
.pytest_cache/
|
||||
.vscode/*
|
||||
!.vscode/tasks.json
|
||||
.ruff_cache/
|
||||
31
pyproject.toml
Normal file
31
pyproject.toml
Normal file
@@ -0,0 +1,31 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=69"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "bedit"
|
||||
version = "0.2.0"
|
||||
description = "A Bondgraph and block scheme simulator"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"msgpack>=1.0,<2",
|
||||
"PySide6>=6.7,<7",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"pytest>=8",
|
||||
"ruff>=0.5",
|
||||
]
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
addopts = "--strict-config --strict-markers -ra"
|
||||
testpaths = ["tests"]
|
||||
markers = [
|
||||
"unit: fast tests without GUI event-loop interaction",
|
||||
"gui: tests that create or interact with Qt objects",
|
||||
]
|
||||
124
src/bedit_core/models.py
Normal file
124
src/bedit_core/models.py
Normal file
@@ -0,0 +1,124 @@
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Any, Annotated
|
||||
from uuid import uuid4
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ID:
|
||||
value: str = field(default_factory=lambda: str(uuid4()))
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if not isinstance(self.value, str):
|
||||
raise TypeError("ID value must be a string")
|
||||
if not self.value:
|
||||
raise ValueError("ID value cannot be empty")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value
|
||||
|
||||
class ComponentID(ID):
|
||||
pass
|
||||
|
||||
class ConnectionID(ID):
|
||||
pass
|
||||
|
||||
class ParameterID(ID):
|
||||
pass
|
||||
|
||||
class PortID(ID):
|
||||
pass
|
||||
|
||||
class SignalDirection(Enum):
|
||||
INPUT = "input"
|
||||
OUTPUT = "output"
|
||||
|
||||
class BondCausality(Enum):
|
||||
NONE = "none"
|
||||
EFFORT_OUT = "effort_out"
|
||||
FLOW_OUT = "flow_out"
|
||||
|
||||
class PortCausality(Enum):
|
||||
INDIFFERENT = "indifferent"
|
||||
FIXED_EFFORT_OUT = "fixed_effort_out"
|
||||
FIXED_FLOW_OUT = "fixed_flow_out"
|
||||
PREFERRED_EFFORT_OUT = "preferred_effort_out"
|
||||
PREFERRED_FLOW_OUT = "preferred_flow_out"
|
||||
LIKES_EFFORT_OUT = "likes_effort_out"
|
||||
LIKES_FLOW_OUT = "likes_flow_out"
|
||||
|
||||
@dataclass
|
||||
class Document:
|
||||
format_version: int
|
||||
id: ID
|
||||
name: str
|
||||
root: dict[ComponentID, Component]
|
||||
metadata: dict[str, Any] | None = None
|
||||
|
||||
@dataclass
|
||||
class Component:
|
||||
name: str
|
||||
interface: Interface
|
||||
parameters: dict[ParameterID, Parameter]
|
||||
implementation: GraphImplementation | EquationImplementation
|
||||
|
||||
@dataclass
|
||||
class Interface:
|
||||
ports: dict[PortID, Port] = field(default_factory=dict)
|
||||
|
||||
@dataclass
|
||||
class Port:
|
||||
name: str
|
||||
direction: SignalDirection
|
||||
multiplicity: bool = False
|
||||
matrix_size: Annotated[list[int], 2] = field(default_factory=lambda: [1, 1])
|
||||
description: str | None = None
|
||||
|
||||
@dataclass
|
||||
class SignalPort(Port):
|
||||
value_type: str = "Real"
|
||||
quantity: str | None = None
|
||||
unit: str | None = None
|
||||
|
||||
@dataclass
|
||||
class BondPort(Port):
|
||||
domain: str = ""
|
||||
causality_preference: PortCausality = PortCausality.INDIFFERENT
|
||||
|
||||
@dataclass
|
||||
class Parameter:
|
||||
name: str
|
||||
value: Any = 1.0
|
||||
value_type: str = "Real"
|
||||
quantity: str | None = None
|
||||
unit: str | None = None
|
||||
description: str | None = None
|
||||
|
||||
@dataclass
|
||||
class GraphImplementation:
|
||||
graph: Graph
|
||||
|
||||
@dataclass
|
||||
class EquationImplementation:
|
||||
declarations: list[str] = field(default_factory=list)
|
||||
initial_equations: list[str] = field(default_factory=list)
|
||||
equations: list[str] = field(default_factory=list)
|
||||
|
||||
@dataclass
|
||||
class Graph:
|
||||
components: dict[ComponentID, Component] = field(default_factory=dict)
|
||||
connections: dict[ConnectionID, Connection] = field(default_factory=dict)
|
||||
|
||||
@dataclass
|
||||
class Connection:
|
||||
source: PortID
|
||||
target: PortID
|
||||
|
||||
@dataclass
|
||||
class SignalConnection(Connection):
|
||||
pass
|
||||
|
||||
@dataclass
|
||||
class BondConnection(Connection):
|
||||
causality: BondCausality = BondCausality.NONE
|
||||
undesired: bool = False
|
||||
317
untitled.bedit.json
Normal file
317
untitled.bedit.json
Normal file
@@ -0,0 +1,317 @@
|
||||
{
|
||||
"file_format_version": 1,
|
||||
"format_version": 1,
|
||||
"id": "3b6780c7-488b-471e-a784-392db7632090",
|
||||
"name": "Current Document",
|
||||
"root": {
|
||||
"50e6ef97-f686-4400-bc01-e5a352e8cc22": {
|
||||
"name": "New Graph Block 1",
|
||||
"interface": {
|
||||
"ports": {}
|
||||
},
|
||||
"parameters": {},
|
||||
"implementation": {
|
||||
"implementation_type": "graph",
|
||||
"graph": {
|
||||
"components": {
|
||||
"43b3aee6-0b38-429b-9c6d-d38fc097297f": {
|
||||
"name": "C",
|
||||
"interface": {
|
||||
"ports": {
|
||||
"c87881f1-23b4-4a69-b586-8e3c7bf6e21e": {
|
||||
"port_type": "bond",
|
||||
"name": "p",
|
||||
"direction": "input",
|
||||
"multiplicity": false,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"domain": "power",
|
||||
"causality_preference": "preferred_effort_out"
|
||||
},
|
||||
"c62de8eb-e13b-4849-bea5-c8cc5332269e": {
|
||||
"port_type": "signal",
|
||||
"name": "state",
|
||||
"direction": "output",
|
||||
"multiplicity": false,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"value_type": "real",
|
||||
"quantity": "",
|
||||
"unit": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"parameter-d056bc27": {
|
||||
"name": "c",
|
||||
"value": "1",
|
||||
"value_type": "Real",
|
||||
"quantity": null,
|
||||
"unit": null,
|
||||
"description": null
|
||||
}
|
||||
},
|
||||
"implementation": {
|
||||
"implementation_type": "equation",
|
||||
"declarations": [],
|
||||
"initial_equations": ["state = 0;"],
|
||||
"equations": ["der(state) = p.f;", "p.e = state/c;"]
|
||||
}
|
||||
},
|
||||
"9ee2f42b-5ed1-446d-8790-c2a1df6b61d3": {
|
||||
"name": "j1",
|
||||
"interface": {
|
||||
"ports": {
|
||||
"4306701a-6b1b-4d19-b8ff-45dbfa04f2d3": {
|
||||
"port_type": "bond",
|
||||
"name": "p",
|
||||
"direction": "input",
|
||||
"multiplicity": true,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"domain": "power",
|
||||
"causality_preference": "indifferent"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {},
|
||||
"implementation": {
|
||||
"implementation_type": "equation",
|
||||
"declarations": [
|
||||
"parameter Real s[$p_N$] = $p_S$;",
|
||||
"Real f;"
|
||||
],
|
||||
"initial_equations": [],
|
||||
"equations": [
|
||||
"f = s[1] * p[1].f;",
|
||||
"sum(s[i] * p[i].e for i in 1:$p_N$) = 0;",
|
||||
"for i in 2:$p_N$ loop",
|
||||
" s[i] * p[i].f = s[i-1] * p[i-1].f;",
|
||||
"end for;"
|
||||
]
|
||||
}
|
||||
},
|
||||
"5a8b2e8d-489f-467b-8282-7e344dfad576": {
|
||||
"name": "R",
|
||||
"interface": {
|
||||
"ports": {
|
||||
"0ac7d4ea-77f7-4c0d-8e37-406ef66e4740": {
|
||||
"port_type": "bond",
|
||||
"name": "p",
|
||||
"direction": "input",
|
||||
"multiplicity": false,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"domain": "power",
|
||||
"causality_preference": "indifferent"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"parameter-d056bc27": {
|
||||
"name": "r",
|
||||
"value": "1",
|
||||
"value_type": "Real",
|
||||
"quantity": null,
|
||||
"unit": null,
|
||||
"description": null
|
||||
}
|
||||
},
|
||||
"implementation": {
|
||||
"implementation_type": "equation",
|
||||
"declarations": [],
|
||||
"initial_equations": [],
|
||||
"equations": ["p.e = r*p.f;"]
|
||||
}
|
||||
},
|
||||
"2804f2f1-6123-4a53-aff1-87a3a8202711": {
|
||||
"name": "Se",
|
||||
"interface": {
|
||||
"ports": {
|
||||
"5b6a8a0c-0875-402c-bd74-11d086aac372": {
|
||||
"port_type": "bond",
|
||||
"name": "p",
|
||||
"direction": "output",
|
||||
"multiplicity": false,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"domain": "power",
|
||||
"causality_preference": "fixed_effort_out"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"parameter-d056bc27": {
|
||||
"name": "e",
|
||||
"value": "1",
|
||||
"value_type": "Real",
|
||||
"quantity": null,
|
||||
"unit": null,
|
||||
"description": null
|
||||
}
|
||||
},
|
||||
"implementation": {
|
||||
"implementation_type": "equation",
|
||||
"declarations": ["Real f;"],
|
||||
"initial_equations": [],
|
||||
"equations": ["p.e = e;", "f = p.f;"]
|
||||
}
|
||||
},
|
||||
"9f392c28-6bef-4b10-9305-93e250747007": {
|
||||
"name": "j0",
|
||||
"interface": {
|
||||
"ports": {
|
||||
"497b1f74-1186-471f-976a-36b07a451caf": {
|
||||
"port_type": "bond",
|
||||
"name": "p",
|
||||
"direction": "input",
|
||||
"multiplicity": true,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"domain": "power",
|
||||
"causality_preference": "indifferent"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {},
|
||||
"implementation": {
|
||||
"implementation_type": "equation",
|
||||
"declarations": ["Real e;"],
|
||||
"initial_equations": [],
|
||||
"equations": [
|
||||
"e = p[1].e;",
|
||||
"sum(p[i].f for i in 1:$p_N$) = 0;",
|
||||
"for i in 2:$p_N$ loop",
|
||||
" p[i].e = p[i-1].e;",
|
||||
"end for;"
|
||||
]
|
||||
}
|
||||
},
|
||||
"77701f68-b14c-4b98-8929-c5fba0261962": {
|
||||
"name": "R0",
|
||||
"interface": {
|
||||
"ports": {
|
||||
"4a3f69f2-b305-4305-92e3-3998634ff226": {
|
||||
"port_type": "bond",
|
||||
"name": "p",
|
||||
"direction": "input",
|
||||
"multiplicity": false,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"domain": "power",
|
||||
"causality_preference": "indifferent"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"parameter-d056bc27": {
|
||||
"name": "r",
|
||||
"value": "10",
|
||||
"value_type": "Real",
|
||||
"quantity": null,
|
||||
"unit": null,
|
||||
"description": null
|
||||
}
|
||||
},
|
||||
"implementation": {
|
||||
"implementation_type": "equation",
|
||||
"declarations": [],
|
||||
"initial_equations": [],
|
||||
"equations": ["p.e = r*p.f;"]
|
||||
}
|
||||
},
|
||||
"033b930e-bf79-403a-8b0b-a159f3c81ce9": {
|
||||
"name": "I",
|
||||
"interface": {
|
||||
"ports": {
|
||||
"0b9036b1-e4e4-437e-8c35-f5bb391b6cbd": {
|
||||
"port_type": "bond",
|
||||
"name": "p",
|
||||
"direction": "input",
|
||||
"multiplicity": false,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"domain": "power",
|
||||
"causality_preference": "preferred_flow_out"
|
||||
},
|
||||
"fb25f35d-4c0c-4cfa-92d4-1a18a71e2c11": {
|
||||
"port_type": "signal",
|
||||
"name": "state",
|
||||
"direction": "output",
|
||||
"multiplicity": false,
|
||||
"matrix_size": [1, 1],
|
||||
"description": "",
|
||||
"value_type": "real",
|
||||
"quantity": "",
|
||||
"unit": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"parameter-d056bc27": {
|
||||
"name": "i",
|
||||
"value": "1",
|
||||
"value_type": "Real",
|
||||
"quantity": null,
|
||||
"unit": null,
|
||||
"description": null
|
||||
}
|
||||
},
|
||||
"implementation": {
|
||||
"implementation_type": "equation",
|
||||
"declarations": [],
|
||||
"initial_equations": ["state = 0;"],
|
||||
"equations": ["der(state) = p.e;", "p.f = state/i;"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"connections": {
|
||||
"7e293c73-1e07-4d4c-b750-6f43870c71c4": {
|
||||
"connection_type": "bond",
|
||||
"source": "5b6a8a0c-0875-402c-bd74-11d086aac372",
|
||||
"target": "4306701a-6b1b-4d19-b8ff-45dbfa04f2d3",
|
||||
"causality": "flow_out",
|
||||
"undesired": false
|
||||
},
|
||||
"66414b62-ca76-4be6-8da4-72551f8ffc0e": {
|
||||
"connection_type": "bond",
|
||||
"source": "497b1f74-1186-471f-976a-36b07a451caf",
|
||||
"target": "4a3f69f2-b305-4305-92e3-3998634ff226",
|
||||
"causality": "effort_out",
|
||||
"undesired": false
|
||||
},
|
||||
"8aaa96b3-45ed-4674-8f7a-06b28178a5c8": {
|
||||
"connection_type": "bond",
|
||||
"source": "4306701a-6b1b-4d19-b8ff-45dbfa04f2d3",
|
||||
"target": "c87881f1-23b4-4a69-b586-8e3c7bf6e21e",
|
||||
"causality": "effort_out",
|
||||
"undesired": false
|
||||
},
|
||||
"ff606583-d31f-4638-93f7-926163db2665": {
|
||||
"connection_type": "bond",
|
||||
"source": "4306701a-6b1b-4d19-b8ff-45dbfa04f2d3",
|
||||
"target": "0ac7d4ea-77f7-4c0d-8e37-406ef66e4740",
|
||||
"causality": "flow_out",
|
||||
"undesired": false
|
||||
},
|
||||
"1f52dc5a-1847-4982-aabc-2538cf99a86f": {
|
||||
"connection_type": "bond",
|
||||
"source": "497b1f74-1186-471f-976a-36b07a451caf",
|
||||
"target": "0b9036b1-e4e4-437e-8c35-f5bb391b6cbd",
|
||||
"causality": "flow_out",
|
||||
"undesired": false
|
||||
},
|
||||
"5af42b61-2317-48a8-b32b-0e2dfd88368e": {
|
||||
"connection_type": "bond",
|
||||
"source": "4306701a-6b1b-4d19-b8ff-45dbfa04f2d3",
|
||||
"target": "497b1f74-1186-471f-976a-36b07a451caf",
|
||||
"causality": "effort_out",
|
||||
"undesired": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {}
|
||||
}
|
||||
Reference in New Issue
Block a user