mlafactory 0.1.0__tar.gz

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.
Files changed (32) hide show
  1. mlafactory-0.1.0/LICENSE +11 -0
  2. mlafactory-0.1.0/MANIFEST.in +1 -0
  3. mlafactory-0.1.0/PKG-INFO +337 -0
  4. mlafactory-0.1.0/README.md +312 -0
  5. mlafactory-0.1.0/pyproject.toml +57 -0
  6. mlafactory-0.1.0/setup.cfg +4 -0
  7. mlafactory-0.1.0/src/mlafactory/FactoryRunner.py +411 -0
  8. mlafactory-0.1.0/src/mlafactory/FactorySimulator.py +349 -0
  9. mlafactory-0.1.0/src/mlafactory/Inventory.py +96 -0
  10. mlafactory-0.1.0/src/mlafactory/Machine.py +149 -0
  11. mlafactory-0.1.0/src/mlafactory/MachineDispatcher.py +182 -0
  12. mlafactory-0.1.0/src/mlafactory/__init__.py +0 -0
  13. mlafactory-0.1.0/src/mlafactory/aux_arguments.py +229 -0
  14. mlafactory-0.1.0/src/mlafactory/aux_files.py +42 -0
  15. mlafactory-0.1.0/src/mlafactory/aux_intervals.py +75 -0
  16. mlafactory-0.1.0/src/mlafactory/aux_reports.py +149 -0
  17. mlafactory-0.1.0/src/mlafactory/minimal_example/__init__.py +0 -0
  18. mlafactory-0.1.0/src/mlafactory/minimal_example/bom.json +90 -0
  19. mlafactory-0.1.0/src/mlafactory/minimal_example/initial_inventory.json +31 -0
  20. mlafactory-0.1.0/src/mlafactory/minimal_example/machines.json +16 -0
  21. mlafactory-0.1.0/src/mlafactory/minimal_example/orders_demand.json +12 -0
  22. mlafactory-0.1.0/src/mlafactory/minimal_example/reorder_delays.json +23 -0
  23. mlafactory-0.1.0/src/mlafactory/minimal_example/stock_limits.json +106 -0
  24. mlafactory-0.1.0/src/mlafactory/run_factory.py +48 -0
  25. mlafactory-0.1.0/src/mlafactory.egg-info/PKG-INFO +337 -0
  26. mlafactory-0.1.0/src/mlafactory.egg-info/SOURCES.txt +30 -0
  27. mlafactory-0.1.0/src/mlafactory.egg-info/dependency_links.txt +1 -0
  28. mlafactory-0.1.0/src/mlafactory.egg-info/entry_points.txt +2 -0
  29. mlafactory-0.1.0/src/mlafactory.egg-info/requires.txt +4 -0
  30. mlafactory-0.1.0/src/mlafactory.egg-info/top_level.txt +1 -0
  31. mlafactory-0.1.0/tests/test_mlafactory.py +819 -0
  32. mlafactory-0.1.0/tests/test_run_factory.py +113 -0
@@ -0,0 +1,11 @@
1
+ Copyright 2025 University of Luxembourg
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ recursive-include src/mlafactory/minimal_example *.json
@@ -0,0 +1,337 @@
1
+ Metadata-Version: 2.4
2
+ Name: mlafactory
3
+ Version: 0.1.0
4
+ Summary: Digital Multi-Level Assembly (MLA) manufacturing factory simulation made with SimPy
5
+ Author-email: "Oscar J. Castro-Lopez" <oscar.castro@uni.lu>
6
+ Maintainer-email: Pierrick Pochelu <pierrick.pochelu@gmail.com>, Georgios Kafanas <georgios.kafanas@uni.lu>
7
+ License-Expression: BSD-3-Clause
8
+ Project-URL: Homepage, https://gitlab.com/uniluxembourg/hpc/research/cadom/mla_factory
9
+ Project-URL: Repository, https://gitlab.com/uniluxembourg/hpc/research/cadom/mla_factory
10
+ Project-URL: Documentation, https://gitlab.com/uniluxembourg/hpc/research/cadom/mla_factory
11
+ Keywords: simulation,manufacturing,factory,MLA
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Topic :: Scientific/Engineering
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: simpy
21
+ Requires-Dist: pandas
22
+ Requires-Dist: numpy
23
+ Requires-Dist: pyyaml
24
+ Dynamic: license-file
25
+
26
+ # mlafactory
27
+
28
+ [![PyPI version](https://badge.fury.io/py/mlafactory.svg)](https://badge.fury.io/py/mlafactory)
29
+ [![License: BSD-3](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
30
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
31
+
32
+ `mlafactory` is an open-source discrete-event simulation framework for modeling **Multi-Level Assembly (MLA)** manufacturing systems. Built on top of [SimPy](https://simpy.readthedocs.io/), it enables flexible simulation of factories with dynamic inventory management, heterogeneous machine pools, stochastic order arrivals, and configurable production and replenishment policies.
33
+
34
+ The framework is designed for **research, experimentation, and reproducible evaluation** of manufacturing strategies.
35
+
36
+ ---
37
+
38
+ ## Features
39
+
40
+ - **Multi-level bill of materials (BOM)** — recursive assembly of products from sub-components and raw materials
41
+ - **Heterogeneous machine pools** — multiple machine types with configurable setup times, cycle times, and costs
42
+ - **Dynamic inventory management** — min/max stock policies with async waiting and automatic replenishment
43
+ - **Stochastic order arrivals** — fixed, random, spread, or distribution-based inter-order intervals
44
+ - **Configurable replenishment** — per-component reorder delays for raw materials
45
+ - **Multiple inventory initialization strategies** — zero, min, max, or random initial stock levels
46
+ - **Rich reporting** — production service levels, machine utilization, and inventory summaries exported as CSV
47
+ - **CLI and Python API** — run simulations without writing code or integrate programmatically
48
+ - **YAML / JSON configuration** — fully reproducible experiments via configuration files
49
+
50
+ ---
51
+
52
+ ## Requirements
53
+
54
+ - Python 3.9+
55
+ - SimPy >= 4.0
56
+ - pandas
57
+ - PyYAML
58
+
59
+ ---
60
+
61
+ ## Installation
62
+
63
+ <!-- To be completed
64
+ ```bash
65
+ pip install mlafactory
66
+ ```
67
+ -->
68
+ Install from source:
69
+
70
+ ```bash
71
+ git clone https://gitlab.com/uniluxembourg/hpc/research/cadom/mla_factory.git
72
+ cd mla_factory
73
+ pip install -e .
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Quick Start
79
+
80
+ ### Command Line
81
+
82
+ `mlafactory` ships with a built-in bike factory example:
83
+
84
+ ```bash
85
+ mlafactory --show-output
86
+ ```
87
+
88
+ To run with a custom configuration file:
89
+
90
+ ```bash
91
+ mlafactory --factory-config my_factory.yml --show-output
92
+ ```
93
+
94
+ ### Python API
95
+
96
+ ```python
97
+ from mlafactory.FactoryRunner import FactoryRunner
98
+
99
+ # Load from a configuration file
100
+ simulator = FactoryRunner.from_config("my_factory.yml")
101
+ result = simulator.run()
102
+
103
+ # Or configure programmatically
104
+ simulator = FactoryRunner(
105
+ factory_name="BikeFactory",
106
+ bom=bom,
107
+ initial_inventory=initial_inventory,
108
+ reorder_delays=reorder_delays,
109
+ product_demand=product_demand,
110
+ machines=machines,
111
+ stock_limits=stock_limits,
112
+ months=12,
113
+ hours_per_month=160,
114
+ inventory_strategy="max",
115
+ show_output=True,
116
+ export_reports=True,
117
+ output_dir="output/",
118
+ )
119
+ result = simulator.run()
120
+ ```
121
+
122
+ ### Expected Output
123
+
124
+ ```
125
+ Elapsed real time: 0.02940058708190918
126
+ Total simulated time: 1920 hours
127
+ ======================================== Production Results ========================================
128
+ product demand fulfilled inventory production fulfillment_ratio production_ratio
129
+ 0 RoadBike 52 26 6 32 0.500000 0.615385
130
+ 1 MountainBike 65 57 6 63 0.876923 0.969231
131
+ 2 ElectricBike 63 28 3 31 0.444444 0.492063
132
+ 3 TOTAL 180 111 15 126 0.616667 0.692226
133
+ ======================================== Machines Summary ========================================
134
+ type name setup_time cycle_time n_setups n_cycles setup_cost cycle_cost tt_setup tt_build tt_idle
135
+ 0 bike bk01 1.0 25.0 13 32 0 0.0 0.216667 13.333333 1906.450000
136
+ 1 bike bk02 2.0 20.0 13 32 0 0.0 0.433333 10.666667 1908.900000
137
+ 2 bike bk03 3.0 19.0 14 31 0 0.0 0.700000 9.816667 1909.483333
138
+ 3 bike bk04 4.0 17.0 14 31 0 0.0 0.933333 8.783333 1910.283333
139
+ 4 frame fr01 2.0 15.0 3 43 0 0.0 0.100000 10.750000 1909.150000
140
+ 5 frame fr02 3.0 12.0 2 39 0 0.0 0.100000 7.800000 1912.100000
141
+ 6 frame fr03 3.0 13.0 3 39 0 0.0 0.150000 8.450000 1911.400000
142
+ 7 frame fr04 4.0 14.0 2 53 0 0.0 0.133333 12.366667 1907.500000
143
+ 8 wheel wl01 3.0 8.0 29 43 0 0.0 1.450000 5.733333 1912.816667
144
+ 9 wheel wl02 10.0 5.0 29 43 0 0.0 4.833333 3.583333 1911.583333
145
+ 10 wheel wl03 1.0 10.0 4 42 0 0.0 0.066667 7.000000 1912.933333
146
+ 11 wheel wl04 2.0 7.0 4 42 0 0.0 0.133333 4.900000 1914.966667
147
+ 12 wheel wl05 9.0 6.0 4 42 0 0.0 0.600000 4.200000 1915.200000
148
+ 13 wheel wl06 3.0 5.0 4 42 0 0.0 0.200000 3.500000 1916.300000
149
+ ======================================== Inventory Summary ========================================
150
+ item initial consumed final n_reorders
151
+ 0 MountainBike 0.0 57.0 6.0 NaN
152
+ 1 RoadBike 0.0 26.0 6.0 NaN
153
+ 2 ElectricBike 0.0 28.0 3.0 NaN
154
+ 3 wheel_a 0.0 126.0 1.0 NaN
155
+ 4 wheel_b 0.0 126.0 1.0 NaN
156
+ 5 frame_a 0.0 97.0 27.0 NaN
157
+ 6 frame_b 0.0 32.0 18.0 NaN
158
+ 7 pedal 10.0 258.0 16.0 22.0
159
+ 8 crank_arm 5.0 129.0 13.0 22.0
160
+ 9 front_derailleur 4.0 129.0 12.0 22.0
161
+ 10 chain 3.0 129.0 12.0 22.0
162
+ 11 chain_rings 2.0 129.0 12.0 22.0
163
+ 12 rear_brakes 1.0 129.0 12.0 22.0
164
+ 13 cogset 2.0 129.0 12.0 22.0
165
+ 14 rear_derailleur 3.0 129.0 12.0 22.0
166
+ 15 spokes 25.0 6350.0 10.0 127.0
167
+ 16 hub 1.0 256.0 17.0 24.0
168
+ 17 rim 1.0 256.0 17.0 24.0
169
+ 18 tire 1.0 256.0 17.0 24.0
170
+ 19 valve 1.0 256.0 17.0 24.0
171
+ 20 top_tube 1.0 174.0 14.0 10.0
172
+ 21 down_tube 1.0 174.0 14.0 10.0
173
+ 22 seat_tube 1.0 174.0 14.0 10.0
174
+ 23 seat_stay 1.0 174.0 14.0 10.0
175
+ 24 chain_stay 1.0 174.0 14.0 10.0
176
+ 25 paint 3.0 261.0 10.0 12.0
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Documentation
182
+
183
+ Full documentation is available in the [`docs/`](docs/) directory:
184
+
185
+ | File | Description |
186
+ |---|---|
187
+ | [`docs/cli.md`](docs/cli.md) | Command-line interface reference |
188
+ | [`docs/simulation_model.md`](docs/simulation_model.md) | Simulation architecture and event flow |
189
+ ---
190
+
191
+ ## Minimal Configuration Example
192
+
193
+ ```yaml
194
+ factory_name: "BikeFactory"
195
+ months: 12
196
+ hours_per_month: 160
197
+ show_output: true
198
+
199
+ product_demand:
200
+ "order_01":
201
+ MountainBike: 10
202
+
203
+ bom:
204
+ MountainBike:
205
+ type: bike
206
+ bom:
207
+ frame_a: { type: frame, qty: 1 }
208
+ wheel_a: { type: wheel, qty: 2 }
209
+ pedal: { type: raw, qty: 2 }
210
+
211
+ frame_a:
212
+ type: frame
213
+ bom:
214
+ tubes: { type: raw, qty: 1 }
215
+ seat_stay: { type: raw, qty: 1 }
216
+ chain_stay: { type: raw, qty: 1 }
217
+ paint: { type: raw, qty: 1.5 }
218
+
219
+ wheel_a:
220
+ type: wheel
221
+ bom:
222
+ spokes: { type: raw, qty: 15 }
223
+ hub: { type: raw, qty: 1 }
224
+ rim: { type: raw, qty: 1 }
225
+ tire: { type: raw, qty: 1 }
226
+ valve: { type: raw, qty: 1 }
227
+
228
+ reorder_delays:
229
+ pedal: { reorder_delay: 10 }
230
+ tubes: { reorder_delay: 10 }
231
+ seat_stay: { reorder_delay: 10 }
232
+ chain_stay: { reorder_delay: 10 }
233
+ paint: { reorder_delay: 10 }
234
+ spokes: { reorder_delay: 15 }
235
+ hub: { reorder_delay: 10 }
236
+ rim: { reorder_delay: 10 }
237
+ tire: { reorder_delay: 10 }
238
+ valve: { reorder_delay: 10 }
239
+
240
+ initial_inventory:
241
+ MountainBike: 0
242
+
243
+ stock_limits:
244
+ MountainBike: { min: 5, max: 20 }
245
+ frame_a: { min: 5, max: 15 }
246
+ wheel_a: { min: 5, max: 20 }
247
+ pedal: { min: 10, max: 30 }
248
+ spokes: { min: 30, max: 60 }
249
+ hub: { min: 10, max: 20 }
250
+ rim: { min: 10, max: 20 }
251
+ tire: { min: 10, max: 20 }
252
+ valve: { min: 10, max: 20 }
253
+ tubes: { min: 10, max: 25 }
254
+ seat_stay: { min: 10, max: 25 }
255
+ chain_stay: { min: 10, max: 25 }
256
+ paint: { min: 10, max: 25 }
257
+
258
+
259
+ machines:
260
+ - { name: bk01, type: bike, setup_time: 5, cycle_time: 20 }
261
+ - { name: fr01, type: frame, setup_time: 3, cycle_time: 15 }
262
+ - { name: wl01, type: wheel, setup_time: 2, cycle_time: 8 }
263
+ ```
264
+
265
+ ---
266
+
267
+ ## Project Structure
268
+
269
+ ```
270
+ mla_factory/
271
+ ├── src/mlafactory
272
+ │ ├── Inventory.py # Inventory management and async waiting
273
+ │ ├── Machine.py # Machine production process
274
+ │ ├── MachineDispatcher.py # Task routing and machine pool management
275
+ │ ├── FactorySimulator.py # Core factory coordination
276
+ │ ├── FactoryRunner.py # Orchestrator: validation, run, reporting
277
+ │ ├── aux_files.py # I/O utilities and custom exceptions
278
+ │ ├── aux_intervals.py # Order interval generation
279
+ │ ├── aux_reports.py # Result collection and export
280
+ │ └── minimal_example/ # Built-in bike factory example
281
+ ├── docs/
282
+ ├── tests/
283
+ └── README.md
284
+ ```
285
+
286
+ ---
287
+
288
+ ## Running Tests
289
+
290
+ ```bash
291
+ pip install pytest
292
+ pytest tests/
293
+ ```
294
+
295
+ ---
296
+
297
+ ## License
298
+
299
+ BSD 3-Clause License. See [LICENSE](LICENSE) for details.
300
+
301
+ ---
302
+
303
+ ## Citation
304
+
305
+ To be completed.
306
+ <!--
307
+ If you use mlafactory in your research, please cite:
308
+
309
+ ```bibtex
310
+ @article{mlafactory2025,
311
+ title = {mlafactory: A Discrete-Event Simulation Framework for Multi-Level Assembly Systems},
312
+ author = {Your Name},
313
+ journal = {Journal of Open Source Software},
314
+ year = {2025},
315
+ doi = {10.xxxx/joss.xxxxx}
316
+ }
317
+ ```
318
+ -->
319
+ ---
320
+
321
+ ## Authors
322
+
323
+ Developer and maintainer:
324
+
325
+ **Oscar J. Castro-Lopez**:
326
+ Research Associate, University of Luxembourg
327
+
328
+ Contributors:
329
+
330
+ - **Pierrick Pochelu** DevOps, LuxProvide
331
+ - **Georgios Kafanas** Infrastructure and Architecture Engineer, University of Luxembourg
332
+
333
+ Contributions welcome — please open an issue or pull request on GitLab.
334
+
335
+ ## Acknowledgements
336
+
337
+ This project was created with the support of the Luxembourg National Research Fund (FNR) under project 17941664. Supported by the Ministry of Economy (MECO) under project 17941664.
@@ -0,0 +1,312 @@
1
+ # mlafactory
2
+
3
+ [![PyPI version](https://badge.fury.io/py/mlafactory.svg)](https://badge.fury.io/py/mlafactory)
4
+ [![License: BSD-3](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
5
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
6
+
7
+ `mlafactory` is an open-source discrete-event simulation framework for modeling **Multi-Level Assembly (MLA)** manufacturing systems. Built on top of [SimPy](https://simpy.readthedocs.io/), it enables flexible simulation of factories with dynamic inventory management, heterogeneous machine pools, stochastic order arrivals, and configurable production and replenishment policies.
8
+
9
+ The framework is designed for **research, experimentation, and reproducible evaluation** of manufacturing strategies.
10
+
11
+ ---
12
+
13
+ ## Features
14
+
15
+ - **Multi-level bill of materials (BOM)** — recursive assembly of products from sub-components and raw materials
16
+ - **Heterogeneous machine pools** — multiple machine types with configurable setup times, cycle times, and costs
17
+ - **Dynamic inventory management** — min/max stock policies with async waiting and automatic replenishment
18
+ - **Stochastic order arrivals** — fixed, random, spread, or distribution-based inter-order intervals
19
+ - **Configurable replenishment** — per-component reorder delays for raw materials
20
+ - **Multiple inventory initialization strategies** — zero, min, max, or random initial stock levels
21
+ - **Rich reporting** — production service levels, machine utilization, and inventory summaries exported as CSV
22
+ - **CLI and Python API** — run simulations without writing code or integrate programmatically
23
+ - **YAML / JSON configuration** — fully reproducible experiments via configuration files
24
+
25
+ ---
26
+
27
+ ## Requirements
28
+
29
+ - Python 3.9+
30
+ - SimPy >= 4.0
31
+ - pandas
32
+ - PyYAML
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ <!-- To be completed
39
+ ```bash
40
+ pip install mlafactory
41
+ ```
42
+ -->
43
+ Install from source:
44
+
45
+ ```bash
46
+ git clone https://gitlab.com/uniluxembourg/hpc/research/cadom/mla_factory.git
47
+ cd mla_factory
48
+ pip install -e .
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Quick Start
54
+
55
+ ### Command Line
56
+
57
+ `mlafactory` ships with a built-in bike factory example:
58
+
59
+ ```bash
60
+ mlafactory --show-output
61
+ ```
62
+
63
+ To run with a custom configuration file:
64
+
65
+ ```bash
66
+ mlafactory --factory-config my_factory.yml --show-output
67
+ ```
68
+
69
+ ### Python API
70
+
71
+ ```python
72
+ from mlafactory.FactoryRunner import FactoryRunner
73
+
74
+ # Load from a configuration file
75
+ simulator = FactoryRunner.from_config("my_factory.yml")
76
+ result = simulator.run()
77
+
78
+ # Or configure programmatically
79
+ simulator = FactoryRunner(
80
+ factory_name="BikeFactory",
81
+ bom=bom,
82
+ initial_inventory=initial_inventory,
83
+ reorder_delays=reorder_delays,
84
+ product_demand=product_demand,
85
+ machines=machines,
86
+ stock_limits=stock_limits,
87
+ months=12,
88
+ hours_per_month=160,
89
+ inventory_strategy="max",
90
+ show_output=True,
91
+ export_reports=True,
92
+ output_dir="output/",
93
+ )
94
+ result = simulator.run()
95
+ ```
96
+
97
+ ### Expected Output
98
+
99
+ ```
100
+ Elapsed real time: 0.02940058708190918
101
+ Total simulated time: 1920 hours
102
+ ======================================== Production Results ========================================
103
+ product demand fulfilled inventory production fulfillment_ratio production_ratio
104
+ 0 RoadBike 52 26 6 32 0.500000 0.615385
105
+ 1 MountainBike 65 57 6 63 0.876923 0.969231
106
+ 2 ElectricBike 63 28 3 31 0.444444 0.492063
107
+ 3 TOTAL 180 111 15 126 0.616667 0.692226
108
+ ======================================== Machines Summary ========================================
109
+ type name setup_time cycle_time n_setups n_cycles setup_cost cycle_cost tt_setup tt_build tt_idle
110
+ 0 bike bk01 1.0 25.0 13 32 0 0.0 0.216667 13.333333 1906.450000
111
+ 1 bike bk02 2.0 20.0 13 32 0 0.0 0.433333 10.666667 1908.900000
112
+ 2 bike bk03 3.0 19.0 14 31 0 0.0 0.700000 9.816667 1909.483333
113
+ 3 bike bk04 4.0 17.0 14 31 0 0.0 0.933333 8.783333 1910.283333
114
+ 4 frame fr01 2.0 15.0 3 43 0 0.0 0.100000 10.750000 1909.150000
115
+ 5 frame fr02 3.0 12.0 2 39 0 0.0 0.100000 7.800000 1912.100000
116
+ 6 frame fr03 3.0 13.0 3 39 0 0.0 0.150000 8.450000 1911.400000
117
+ 7 frame fr04 4.0 14.0 2 53 0 0.0 0.133333 12.366667 1907.500000
118
+ 8 wheel wl01 3.0 8.0 29 43 0 0.0 1.450000 5.733333 1912.816667
119
+ 9 wheel wl02 10.0 5.0 29 43 0 0.0 4.833333 3.583333 1911.583333
120
+ 10 wheel wl03 1.0 10.0 4 42 0 0.0 0.066667 7.000000 1912.933333
121
+ 11 wheel wl04 2.0 7.0 4 42 0 0.0 0.133333 4.900000 1914.966667
122
+ 12 wheel wl05 9.0 6.0 4 42 0 0.0 0.600000 4.200000 1915.200000
123
+ 13 wheel wl06 3.0 5.0 4 42 0 0.0 0.200000 3.500000 1916.300000
124
+ ======================================== Inventory Summary ========================================
125
+ item initial consumed final n_reorders
126
+ 0 MountainBike 0.0 57.0 6.0 NaN
127
+ 1 RoadBike 0.0 26.0 6.0 NaN
128
+ 2 ElectricBike 0.0 28.0 3.0 NaN
129
+ 3 wheel_a 0.0 126.0 1.0 NaN
130
+ 4 wheel_b 0.0 126.0 1.0 NaN
131
+ 5 frame_a 0.0 97.0 27.0 NaN
132
+ 6 frame_b 0.0 32.0 18.0 NaN
133
+ 7 pedal 10.0 258.0 16.0 22.0
134
+ 8 crank_arm 5.0 129.0 13.0 22.0
135
+ 9 front_derailleur 4.0 129.0 12.0 22.0
136
+ 10 chain 3.0 129.0 12.0 22.0
137
+ 11 chain_rings 2.0 129.0 12.0 22.0
138
+ 12 rear_brakes 1.0 129.0 12.0 22.0
139
+ 13 cogset 2.0 129.0 12.0 22.0
140
+ 14 rear_derailleur 3.0 129.0 12.0 22.0
141
+ 15 spokes 25.0 6350.0 10.0 127.0
142
+ 16 hub 1.0 256.0 17.0 24.0
143
+ 17 rim 1.0 256.0 17.0 24.0
144
+ 18 tire 1.0 256.0 17.0 24.0
145
+ 19 valve 1.0 256.0 17.0 24.0
146
+ 20 top_tube 1.0 174.0 14.0 10.0
147
+ 21 down_tube 1.0 174.0 14.0 10.0
148
+ 22 seat_tube 1.0 174.0 14.0 10.0
149
+ 23 seat_stay 1.0 174.0 14.0 10.0
150
+ 24 chain_stay 1.0 174.0 14.0 10.0
151
+ 25 paint 3.0 261.0 10.0 12.0
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Documentation
157
+
158
+ Full documentation is available in the [`docs/`](docs/) directory:
159
+
160
+ | File | Description |
161
+ |---|---|
162
+ | [`docs/cli.md`](docs/cli.md) | Command-line interface reference |
163
+ | [`docs/simulation_model.md`](docs/simulation_model.md) | Simulation architecture and event flow |
164
+ ---
165
+
166
+ ## Minimal Configuration Example
167
+
168
+ ```yaml
169
+ factory_name: "BikeFactory"
170
+ months: 12
171
+ hours_per_month: 160
172
+ show_output: true
173
+
174
+ product_demand:
175
+ "order_01":
176
+ MountainBike: 10
177
+
178
+ bom:
179
+ MountainBike:
180
+ type: bike
181
+ bom:
182
+ frame_a: { type: frame, qty: 1 }
183
+ wheel_a: { type: wheel, qty: 2 }
184
+ pedal: { type: raw, qty: 2 }
185
+
186
+ frame_a:
187
+ type: frame
188
+ bom:
189
+ tubes: { type: raw, qty: 1 }
190
+ seat_stay: { type: raw, qty: 1 }
191
+ chain_stay: { type: raw, qty: 1 }
192
+ paint: { type: raw, qty: 1.5 }
193
+
194
+ wheel_a:
195
+ type: wheel
196
+ bom:
197
+ spokes: { type: raw, qty: 15 }
198
+ hub: { type: raw, qty: 1 }
199
+ rim: { type: raw, qty: 1 }
200
+ tire: { type: raw, qty: 1 }
201
+ valve: { type: raw, qty: 1 }
202
+
203
+ reorder_delays:
204
+ pedal: { reorder_delay: 10 }
205
+ tubes: { reorder_delay: 10 }
206
+ seat_stay: { reorder_delay: 10 }
207
+ chain_stay: { reorder_delay: 10 }
208
+ paint: { reorder_delay: 10 }
209
+ spokes: { reorder_delay: 15 }
210
+ hub: { reorder_delay: 10 }
211
+ rim: { reorder_delay: 10 }
212
+ tire: { reorder_delay: 10 }
213
+ valve: { reorder_delay: 10 }
214
+
215
+ initial_inventory:
216
+ MountainBike: 0
217
+
218
+ stock_limits:
219
+ MountainBike: { min: 5, max: 20 }
220
+ frame_a: { min: 5, max: 15 }
221
+ wheel_a: { min: 5, max: 20 }
222
+ pedal: { min: 10, max: 30 }
223
+ spokes: { min: 30, max: 60 }
224
+ hub: { min: 10, max: 20 }
225
+ rim: { min: 10, max: 20 }
226
+ tire: { min: 10, max: 20 }
227
+ valve: { min: 10, max: 20 }
228
+ tubes: { min: 10, max: 25 }
229
+ seat_stay: { min: 10, max: 25 }
230
+ chain_stay: { min: 10, max: 25 }
231
+ paint: { min: 10, max: 25 }
232
+
233
+
234
+ machines:
235
+ - { name: bk01, type: bike, setup_time: 5, cycle_time: 20 }
236
+ - { name: fr01, type: frame, setup_time: 3, cycle_time: 15 }
237
+ - { name: wl01, type: wheel, setup_time: 2, cycle_time: 8 }
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Project Structure
243
+
244
+ ```
245
+ mla_factory/
246
+ ├── src/mlafactory
247
+ │ ├── Inventory.py # Inventory management and async waiting
248
+ │ ├── Machine.py # Machine production process
249
+ │ ├── MachineDispatcher.py # Task routing and machine pool management
250
+ │ ├── FactorySimulator.py # Core factory coordination
251
+ │ ├── FactoryRunner.py # Orchestrator: validation, run, reporting
252
+ │ ├── aux_files.py # I/O utilities and custom exceptions
253
+ │ ├── aux_intervals.py # Order interval generation
254
+ │ ├── aux_reports.py # Result collection and export
255
+ │ └── minimal_example/ # Built-in bike factory example
256
+ ├── docs/
257
+ ├── tests/
258
+ └── README.md
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Running Tests
264
+
265
+ ```bash
266
+ pip install pytest
267
+ pytest tests/
268
+ ```
269
+
270
+ ---
271
+
272
+ ## License
273
+
274
+ BSD 3-Clause License. See [LICENSE](LICENSE) for details.
275
+
276
+ ---
277
+
278
+ ## Citation
279
+
280
+ To be completed.
281
+ <!--
282
+ If you use mlafactory in your research, please cite:
283
+
284
+ ```bibtex
285
+ @article{mlafactory2025,
286
+ title = {mlafactory: A Discrete-Event Simulation Framework for Multi-Level Assembly Systems},
287
+ author = {Your Name},
288
+ journal = {Journal of Open Source Software},
289
+ year = {2025},
290
+ doi = {10.xxxx/joss.xxxxx}
291
+ }
292
+ ```
293
+ -->
294
+ ---
295
+
296
+ ## Authors
297
+
298
+ Developer and maintainer:
299
+
300
+ **Oscar J. Castro-Lopez**:
301
+ Research Associate, University of Luxembourg
302
+
303
+ Contributors:
304
+
305
+ - **Pierrick Pochelu** DevOps, LuxProvide
306
+ - **Georgios Kafanas** Infrastructure and Architecture Engineer, University of Luxembourg
307
+
308
+ Contributions welcome — please open an issue or pull request on GitLab.
309
+
310
+ ## Acknowledgements
311
+
312
+ This project was created with the support of the Luxembourg National Research Fund (FNR) under project 17941664. Supported by the Ministry of Economy (MECO) under project 17941664.