ifctrano 0.10.0__py3-none-any.whl → 0.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ifctrano/main.py CHANGED
@@ -2,14 +2,17 @@ import shutil
2
2
  import webbrowser
3
3
  from pathlib import Path
4
4
  from tempfile import TemporaryDirectory
5
- from typing import Annotated, get_args
5
+ from typing import Annotated, get_args, Callable
6
6
 
7
7
  import typer
8
8
  from rich.progress import Progress, SpinnerColumn, TextColumn
9
+ from trano.data_models.conversion import convert_network # type: ignore
10
+ from trano.elements.library.library import Library # type: ignore
9
11
  from trano.reporting.html import to_html_reporting # type: ignore
10
12
  from trano.reporting.reporting import ModelDocumentation # type: ignore
11
13
  from trano.reporting.types import ResultFile # type: ignore
12
14
  from trano.simulate.simulate import simulate # type: ignore
15
+ from trano.topology import Network # type: ignore
13
16
  from trano.utils.utils import is_success # type: ignore
14
17
 
15
18
  from ifctrano.base import Libraries
@@ -22,6 +25,45 @@ CHECKMARK = "[green]✔[/green]"
22
25
  CROSS_MARK = "[red]✘[/red]"
23
26
 
24
27
 
28
+ def _create_network(model: str, library: str) -> Network:
29
+ library_ = Library.from_configuration(library)
30
+ model_ = Path(model).resolve()
31
+ return convert_network(str(model_.stem), model_, library=library_)
32
+
33
+
34
+ def _simulate(
35
+ modelica_model_path: Path, create_network_callable: Callable[[], Network]
36
+ ) -> None:
37
+ print("Simulating...")
38
+ try:
39
+ results = simulate(modelica_model_path.parent, create_network_callable())
40
+ except Exception as e:
41
+ print(f"{CROSS_MARK} Simulation failed: {e}")
42
+ return
43
+ if not is_success(results):
44
+ print(f"{CROSS_MARK} Simulation failed. See logs for more information.")
45
+ return
46
+
47
+ result_path = (
48
+ Path(modelica_model_path.parent)
49
+ / "results"
50
+ / f"{modelica_model_path.stem.lower()}.building_res.mat"
51
+ )
52
+ if not result_path.exists():
53
+ print(
54
+ f"{CROSS_MARK} Simulation failed. Result file not found in {result_path}."
55
+ )
56
+ return
57
+ reporting = ModelDocumentation.from_network(
58
+ create_network_callable(),
59
+ result=ResultFile(path=result_path),
60
+ )
61
+ html = to_html_reporting(reporting)
62
+ report_path = Path(modelica_model_path.parent / f"{modelica_model_path.stem}.html")
63
+ report_path.write_text(html)
64
+ webbrowser.open(f"file://{report_path}")
65
+
66
+
25
67
  @app.command()
26
68
  def config(
27
69
  model: Annotated[
@@ -54,6 +96,43 @@ def config(
54
96
  print(f"{CHECKMARK} configuration file generated: {config_path}.")
55
97
 
56
98
 
99
+ @app.command()
100
+ def from_config(
101
+ model: Annotated[
102
+ str,
103
+ typer.Argument(help="Path to the configuration yaml file."),
104
+ ],
105
+ library: Annotated[
106
+ str,
107
+ typer.Argument(help="Modelica library to be used for simulation."),
108
+ ] = "Buildings",
109
+ simulate_model: Annotated[
110
+ bool,
111
+ typer.Option(help="Simulate the generated model."),
112
+ ] = False,
113
+ ) -> None:
114
+ with Progress(
115
+ SpinnerColumn(),
116
+ TextColumn("[progress.description]{task.description}"),
117
+ transient=True,
118
+ ) as progress:
119
+ modelica_model_path = Path(model).resolve().with_suffix(".mo")
120
+ task = progress.add_task(
121
+ description=f"Generating model {modelica_model_path.name} with library {library}",
122
+ total=None,
123
+ )
124
+ network = _create_network(model, library)
125
+ modelica_model = network.model()
126
+ progress.update(task, completed=True)
127
+ task = progress.add_task(description="Writing model to file...", total=None)
128
+ modelica_model_path.write_text(modelica_model)
129
+ progress.remove_task(task)
130
+ print(f"{CHECKMARK} Model generated at {modelica_model_path}")
131
+ create_network_callable = lambda: _create_network(model, library) # noqa: E731
132
+ if simulate_model:
133
+ _simulate(modelica_model_path, create_network_callable)
134
+
135
+
57
136
  @app.command()
58
137
  def create(
59
138
  model: Annotated[
@@ -97,42 +176,11 @@ def create(
97
176
  modelica_model_path.write_text(modelica_network.model())
98
177
  progress.remove_task(task)
99
178
  print(f"{CHECKMARK} Model generated at {modelica_model_path}")
179
+ create_network_callable = lambda: building.create_network( # noqa: E731
180
+ library=library # type: ignore
181
+ )
100
182
  if simulate_model:
101
- print("Simulating...")
102
- try:
103
- results = simulate(
104
- modelica_model_path.parent,
105
- building.create_network(
106
- library=library # type: ignore
107
- ), # TODO: cannot use the network after creating he model
108
- )
109
- except Exception as e:
110
- print(f"{CROSS_MARK} Simulation failed: {e}")
111
- return
112
- if not is_success(results):
113
- print(f"{CROSS_MARK} Simulation failed. See logs for more information.")
114
- return
115
-
116
- result_path = (
117
- Path(modelica_model_path.parent)
118
- / "results"
119
- / f"{modelica_model_path.stem.lower()}.building_res.mat"
120
- )
121
- if not result_path.exists():
122
- print(
123
- f"{CROSS_MARK} Simulation failed. Result file not found in {result_path}."
124
- )
125
- return
126
- reporting = ModelDocumentation.from_network(
127
- building.create_network(library=library), # type: ignore
128
- result=ResultFile(path=result_path),
129
- )
130
- html = to_html_reporting(reporting)
131
- report_path = Path(
132
- modelica_model_path.parent / f"{modelica_model_path.stem}.html"
133
- )
134
- report_path.write_text(html)
135
- webbrowser.open(f"file://{report_path}")
183
+ _simulate(modelica_model_path, create_network_callable)
136
184
 
137
185
 
138
186
  @app.command()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ifctrano
3
- Version: 0.10.0
3
+ Version: 0.11.0
4
4
  Summary: Package for generating building energy simulation model from IFC
5
5
  License: GPL V3
6
6
  License-File: LICENSE
@@ -16,8 +16,8 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Requires-Dist: ifcopenshell (>=0.8.1.post1,<0.9.0)
17
17
  Requires-Dist: open3d (>=0.19.0,<0.20.0)
18
18
  Requires-Dist: shapely (>=2.0.7,<3.0.0)
19
- Requires-Dist: trano (>=0.12.0,<0.13.0)
20
- Requires-Dist: typer (>=0.12.5,<0.13.0)
19
+ Requires-Dist: trano (>=0.13.0,<0.14.0)
20
+ Requires-Dist: typer (>=0.19.2,<0.20.0)
21
21
  Requires-Dist: vedo (>=2025.5.3,<2026.0.0)
22
22
  Project-URL: Repository, https://github.com/andoludo/ifctrano
23
23
  Description-Content-Type: text/markdown
@@ -134,7 +134,21 @@ ifctrano create /path/to/your.ifc IDEAS
134
134
  ```bash
135
135
  ifctrano create /path/to/your.ifc reduced_order
136
136
  ```
137
+ ---
138
+
139
+ ### 📁 Generate yaml configuration from IFC
140
+
141
+ Instead of directly generating a Modelica model from an IFC file, this command creates a configuration .yaml file compatible with the Trano
142
+ Python package (https://github.com/andoludo/trano). This configuration file can be reviewed, adapted, and enriched before generating the final Modelica model, allowing for verification and customization of the translation process.
143
+ ```bash
144
+ ifctrano config /path/to/your.ifc
145
+ ```
146
+
147
+ Once the YAML configuration file has been generated and adapted, the following command can be used to generate and/or simulate the model.
137
148
 
149
+ ```bash
150
+ ifctrano from-config /path/to/your.yaml
151
+ ```
138
152
  ---
139
153
 
140
154
  ### 🧱 Show Space Boundaries
@@ -5,12 +5,12 @@ ifctrano/building.py,sha256=MgYGyCXKbLXKpqtuokLlds_b1JO3cfOSnDkK7tf1wA0,13583
5
5
  ifctrano/construction.py,sha256=I8oRRd1KbG-_sy40-X3PXIz4VCcmbR68WaJcWdpwDIA,10067
6
6
  ifctrano/example/verification.ifc,sha256=tQ9QcubT_wrbb-sc1WRRwYpb2cbkWm3dnRfXdP5GTTg,131
7
7
  ifctrano/exceptions.py,sha256=JDy_0HV7_FLfr92DkrN8F59zUHl9KdMa_lfIcfBJG6I,540
8
- ifctrano/main.py,sha256=W6Jx8ZN2Euoz44ECrU8xYetdSmdgkWBo3lngOVYXNU4,6053
8
+ ifctrano/main.py,sha256=llO_9vvGogx2bMnNN32kFlmB1H7U1_upLAaZQJIVuL4,7672
9
9
  ifctrano/space_boundary.py,sha256=VEQug6zAVtaCpm0YbX1l8UJt0MKmB0oL401JiXYX0Zg,21674
10
10
  ifctrano/types.py,sha256=FBSWrD66EL7uHvv0GveCXmYyLtCr8gGRlT7-5j7aZD8,181
11
11
  ifctrano/utils.py,sha256=zLQUGVo15RSQQ-vfOuHsJBkHy4QhpxKSAH7Au72s0s0,873
12
- ifctrano-0.10.0.dist-info/METADATA,sha256=zu_ivC9PRHxOSX7po9Iio6tCudHxtV83kU8iFajdtFU,4885
13
- ifctrano-0.10.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
14
- ifctrano-0.10.0.dist-info/entry_points.txt,sha256=_2daDejazkphufyEu0m3lOeTio53WYmjol3KmSN0JM4,46
15
- ifctrano-0.10.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
16
- ifctrano-0.10.0.dist-info/RECORD,,
12
+ ifctrano-0.11.0.dist-info/METADATA,sha256=poX0mqI8aQ-cY6fKtB2eg4vB0xsP8TBDHOEuVxHCFQ4,5546
13
+ ifctrano-0.11.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
14
+ ifctrano-0.11.0.dist-info/entry_points.txt,sha256=_2daDejazkphufyEu0m3lOeTio53WYmjol3KmSN0JM4,46
15
+ ifctrano-0.11.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
16
+ ifctrano-0.11.0.dist-info/RECORD,,