anfeny f5be61c9d9 Add topic blacklist to trace logger and conduct several experiments 2 달 전
..
data_models d8c2b640e5 Add second broker listening to realtime simulation + basis for external message injection 2 달 전
devs_models f5be61c9d9 Add topic blacklist to trace logger and conduct several experiments 2 달 전
logs f5be61c9d9 Add topic blacklist to trace logger and conduct several experiments 2 달 전
pythonpdevs 892d271027 Initial commit with previous projects 2 달 전
test 892d271027 Initial commit with previous projects 2 달 전
utils 033d7a488f Add capturing of mqtt traces of real and sim at runtime. Logs to file. 2 달 전
.env.example 636bbb1578 Add configuration based on .env files 2 달 전
PythonPDEVS-master.zip 892d271027 Initial commit with previous projects 2 달 전
README.md 636bbb1578 Add configuration based on .env files 2 달 전
config.py 636bbb1578 Add configuration based on .env files 2 달 전
experiment_realtime.py 892d271027 Initial commit with previous projects 2 달 전
fast_simulation.py 892d271027 Initial commit with previous projects 2 달 전
flowchart.md 8fd1fa23af Add MQTT message queue, to make factory more robust 2 달 전
realtime_simulation.py f5be61c9d9 Add topic blacklist to trace logger and conduct several experiments 2 달 전
requirements.txt 636bbb1578 Add configuration based on .env files 2 달 전

README.md

FischerTechnik-DEVS (Simulator)

A DEVS simulation model of the FischerTechnik Lernfabrik 9V

Requirements

This project was built using Python 3.10 and the packages listed in requirements.txt plus PythonPDEVS which is included in this repository. I recommend the same or higher versions of these packages.

  • PythonPDEVS 2.4.2 (delivered in repo)
  • loguru 0.7.3
  • paho-mqtt 2.1.0
  • python-dotenv 1.1.0

Configuration

This project uses a .env file for runtime configuration.

To set it up, copy the example file:

cp .env.example .env

You can edit the broker addresses or logging settings inside.

For a full explanation of the variables, see the see the main project README

Flowchart Example


flowchart LR
	subgraph Generator
		Generator_out("out")
		Generator_mqtt_out("mqtt_out")
	end
	subgraph InputBay
		InputBay_out("out")
		InputBay_inp("inp")
		InputBay_inp ~~~ InputBay_out
	end
	subgraph Transporter
		Transporter_in_B("in_B")
		Transporter_out_B("out_B")
		Transporter_mqtt_out("mqtt_out")
		Transporter_mqtt_in("mqtt_in")
		Transporter_in_A("in_A")
		Transporter_out_A("out_A")
		Transporter_in_A ~~~ Transporter_out_A
		Transporter_in_B ~~~ Transporter_out_B
		Transporter_mqtt_in ~~~ Transporter_mqtt_out
	end
	subgraph Conveyor
		Conveyor_inp("inp")
		Conveyor_out("out")
		Conveyor_inp ~~~ Conveyor_out
	end
	subgraph Collector
		Collector_inp("inp")
	end
	subgraph MQTTControlUnit
		MQTTControlUnit_mqtt_in("mqtt_in")
		MQTTControlUnit_mqtt_out("mqtt_out")
		MQTTControlUnit_mqtt_in ~~~ MQTTControlUnit_mqtt_out
	end
	Generator_out --> InputBay_inp
	Generator_mqtt_out --> MQTTControlUnit_mqtt_in
	InputBay_out --> Transporter_in_A
	Transporter_out_B --> Conveyor_inp
	Conveyor_out --> Collector_inp
	MQTTControlUnit_mqtt_out --> Transporter_mqtt_in

Factory Flowchart

---
title: FischertechnikFactory
---
flowchart LR
	subgraph Generator
		Generator_out("out")
		Generator_mqtt_in("mqtt_in")
		Generator_mqtt_in ~~~ Generator_out
	end
	Generator_out --> DSI_inp
	subgraph DSI
		DSI_out("out")
		DSI_inp("inp")
		DSI_vgr_in("vgr_in")
		DSI_mqtt_out("mqtt_out")
		DSI_mqtt_in("mqtt_in")
		DSI_inp ~~~ DSI_out
		DSI_mqtt_in ~~~ DSI_mqtt_out
	end
	DSI_out --> VacuumGripper_dsi_in
	DSI_mqtt_out --> MQTTControlUnit_mqtt_in
	subgraph ReaderStation
		ReaderStation_mqtt_out("mqtt_out")
		ReaderStation_nfc_out("nfc_out")
		ReaderStation_color_in("color_in")
		ReaderStation_nfc_in("nfc_in")
		ReaderStation_color_out("color_out")
		ReaderStation_nfc_in ~~~ ReaderStation_nfc_out
		ReaderStation_color_in ~~~ ReaderStation_color_out
	end
	ReaderStation_nfc_out --> VacuumGripper_nfc_in
	ReaderStation_color_out --> VacuumGripper_color_sensor_in
	ReaderStation_mqtt_out --> MQTTControlUnit_mqtt_in
	subgraph VacuumGripper
		VacuumGripper_sld_red_in("sld_red_in")
		VacuumGripper_sld_blue_out("sld_blue_out")
		VacuumGripper_color_sensor_in("color_sensor_in")
		VacuumGripper_nfc_out("nfc_out")
		VacuumGripper_ct_out("ct_out")
		VacuumGripper_mqtt_out("mqtt_out")
		VacuumGripper_sld_red_out("sld_red_out")
		VacuumGripper_nfc_in("nfc_in")
		VacuumGripper_ct_in("ct_in")
		VacuumGripper_mqtt_in("mqtt_in")
		VacuumGripper_color_sensor_out("color_sensor_out")
		VacuumGripper_dso_out("dso_out")
		VacuumGripper_dsi_in("dsi_in")
		VacuumGripper_sld_white_in("sld_white_in")
		VacuumGripper_mpo_out("mpo_out")
		VacuumGripper_dsi_out("dsi_out")
		VacuumGripper_sld_white_out("sld_white_out")
		VacuumGripper_sld_blue_in("sld_blue_in")
		VacuumGripper_dsi_in ~~~ VacuumGripper_dsi_out
		VacuumGripper_ct_in ~~~ VacuumGripper_ct_out
		VacuumGripper_nfc_in ~~~ VacuumGripper_nfc_out
		VacuumGripper_color_sensor_in ~~~ VacuumGripper_color_sensor_out
		VacuumGripper_sld_red_in ~~~ VacuumGripper_mpo_out
		VacuumGripper_sld_blue_in ~~~ VacuumGripper_sld_red_out
		VacuumGripper_sld_white_in ~~~ VacuumGripper_sld_blue_out
		VacuumGripper_mqtt_in ~~~ VacuumGripper_sld_white_out
	end
	VacuumGripper_dsi_out --> DSI_vgr_in
	VacuumGripper_ct_out --> Transporter_right_in
	VacuumGripper_nfc_out --> ReaderStation_nfc_in
	VacuumGripper_color_sensor_out --> ReaderStation_color_in
	VacuumGripper_mpo_out --> MPO_vgr_in
	VacuumGripper_sld_red_out --> SLD_red_in
	VacuumGripper_sld_blue_out --> SLD_blue_in
	VacuumGripper_sld_white_out --> SLD_white_in
	VacuumGripper_dso_out --> DSO_inp
	VacuumGripper_mqtt_out --> MQTTControlUnit_mqtt_in
	subgraph Transporter
		Transporter_left_out("left_out")
		Transporter_mqtt_out("mqtt_out")
		Transporter_left_in("left_in")
		Transporter_right_in("right_in")
		Transporter_right_out("right_out")
		Transporter_left_in ~~~ Transporter_right_out
		Transporter_right_in ~~~ Transporter_left_out
	end
	Transporter_right_out --> VacuumGripper_ct_in
	Transporter_left_out --> HighBayWarehouse_inp
	Transporter_mqtt_out --> MQTTControlUnit_mqtt_in
	subgraph HighBayWarehouse
		HighBayWarehouse_inventory_out("inventory_out")
		HighBayWarehouse_inp("inp")
		HighBayWarehouse_out("out")
		HighBayWarehouse_mqtt_in("mqtt_in")
		HighBayWarehouse_mqtt_out("mqtt_out")
		HighBayWarehouse_inp ~~~ HighBayWarehouse_out
		HighBayWarehouse_mqtt_in ~~~ HighBayWarehouse_mqtt_out
	end
	HighBayWarehouse_out --> Transporter_left_in
	HighBayWarehouse_mqtt_out --> MQTTControlUnit_mqtt_in
	HighBayWarehouse_inventory_out --> InventoryPublisher_inp
	subgraph InventoryPublisher
		InventoryPublisher_inp("inp")
		InventoryPublisher_mqtt_out("mqtt_out")
		InventoryPublisher_inp ~~~ InventoryPublisher_mqtt_out
	end
	InventoryPublisher_mqtt_out --> MQTTControlUnit_mqtt_in
	subgraph MPO
		MPO_conveyor_out("conveyor_out")
		MPO_vgr_in("vgr_in")
		MPO_mqtt_out("mqtt_out")
		MPO_vgr_in ~~~ MPO_mqtt_out
		subgraph MPO_oven
			MPO_oven_gripper_out("gripper_out")
			MPO_oven_vgr_in("vgr_in")
			MPO_oven_mqtt_out("mqtt_out")
			MPO_oven_gripper_in("gripper_in")
			MPO_oven_vgr_in ~~~ MPO_oven_gripper_out
			MPO_oven_gripper_in ~~~ MPO_oven_mqtt_out
		end
		MPO_oven_gripper_out --> MPO_gripper_oven_in
		MPO_oven_mqtt_out --> MPO_mqtt_out
		subgraph MPO_gripper
			MPO_gripper_oven_in("oven_in")
			MPO_gripper_oven_out("oven_out")
			MPO_gripper_table_in("table_in")
			MPO_gripper_table_out("table_out")
			MPO_gripper_mqtt_out("mqtt_out")
			MPO_gripper_oven_in ~~~ MPO_gripper_oven_out
			MPO_gripper_table_in ~~~ MPO_gripper_table_out
		end
		MPO_gripper_oven_out --> MPO_oven_gripper_in
		MPO_gripper_table_out --> MPO_saw_gripper_in
		MPO_gripper_mqtt_out --> MPO_mqtt_out
		subgraph MPO_saw
			MPO_saw_gripper_in("gripper_in")
			MPO_saw_mqtt_out("mqtt_out")
			MPO_saw_gripper_out("gripper_out")
			MPO_saw_conveyor_out("conveyor_out")
			MPO_saw_gripper_in ~~~ MPO_saw_gripper_out
		end
		MPO_saw_gripper_out --> MPO_gripper_table_in
		MPO_saw_conveyor_out --> MPO_conveyor_out
		MPO_saw_mqtt_out --> MPO_mqtt_out
	end
	MPO_mqtt_out --> MQTTControlUnit_mqtt_in
	MPO_conveyor_out --> Conveyor_inp
	MPO_vgr_in --> MPO_oven_vgr_in
	subgraph Conveyor
		Conveyor_mqtt_out("mqtt_out")
		Conveyor_out("out")
		Conveyor_inp("inp")
		Conveyor_inp ~~~ Conveyor_out
	end
	Conveyor_out --> SLD_inp
	Conveyor_mqtt_out --> MQTTControlUnit_mqtt_in
	subgraph SLD
		SLD_blue_out("blue_out")
		SLD_mqtt_out("mqtt_out")
		SLD_inp("inp")
		SLD_white_in("white_in")
		SLD_red_in("red_in")
		SLD_blue_in("blue_in")
		SLD_white_out("white_out")
		SLD_red_out("red_out")
		SLD_inp ~~~ SLD_white_out
		SLD_white_in ~~~ SLD_red_out
		SLD_red_in ~~~ SLD_blue_out
		SLD_blue_in ~~~ SLD_mqtt_out
		subgraph SLD_conveyor
			SLD_conveyor_out_blue("out_blue")
			SLD_conveyor_mqtt_out("mqtt_out")
			SLD_conveyor_inp("inp")
			SLD_conveyor_out_white("out_white")
			SLD_conveyor_out_red("out_red")
			SLD_conveyor_inp ~~~ SLD_conveyor_out_white
		end
		SLD_conveyor_out_white --> SLD_white_bay_sld_in
		SLD_conveyor_out_red --> SLD_red_bay_sld_in
		SLD_conveyor_out_blue --> SLD_blue_bay_sld_in
		SLD_conveyor_mqtt_out --> SLD_mqtt_out
		subgraph SLD_white_bay
			SLD_white_bay_vgr_out("vgr_out")
			SLD_white_bay_sld_in("sld_in")
			SLD_white_bay_mqtt_out("mqtt_out")
			SLD_white_bay_vgr_in("vgr_in")
			SLD_white_bay_sld_in ~~~ SLD_white_bay_vgr_out
			SLD_white_bay_vgr_in ~~~ SLD_white_bay_mqtt_out
		end
		SLD_white_bay_vgr_out --> SLD_white_out
		SLD_white_bay_mqtt_out --> SLD_mqtt_out
		subgraph SLD_red_bay
			SLD_red_bay_vgr_out("vgr_out")
			SLD_red_bay_mqtt_out("mqtt_out")
			SLD_red_bay_sld_in("sld_in")
			SLD_red_bay_vgr_in("vgr_in")
			SLD_red_bay_sld_in ~~~ SLD_red_bay_vgr_out
			SLD_red_bay_vgr_in ~~~ SLD_red_bay_mqtt_out
		end
		SLD_red_bay_vgr_out --> SLD_red_out
		SLD_red_bay_mqtt_out --> SLD_mqtt_out
		subgraph SLD_blue_bay
			SLD_blue_bay_vgr_out("vgr_out")
			SLD_blue_bay_vgr_in("vgr_in")
			SLD_blue_bay_mqtt_out("mqtt_out")
			SLD_blue_bay_sld_in("sld_in")
			SLD_blue_bay_sld_in ~~~ SLD_blue_bay_vgr_out
			SLD_blue_bay_vgr_in ~~~ SLD_blue_bay_mqtt_out
		end
		SLD_blue_bay_vgr_out --> SLD_blue_out
		SLD_blue_bay_mqtt_out --> SLD_mqtt_out
	end
	SLD_white_out --> VacuumGripper_sld_white_in
	SLD_red_out --> VacuumGripper_sld_red_in
	SLD_blue_out --> VacuumGripper_sld_blue_in
	SLD_mqtt_out --> MQTTControlUnit_mqtt_in
	SLD_inp --> SLD_conveyor_inp
	SLD_white_in --> SLD_white_bay_vgr_in
	SLD_red_in --> SLD_red_bay_vgr_in
	SLD_blue_in --> SLD_blue_bay_vgr_in
	subgraph DSO
		DSO_inp("inp")
		DSO_mqtt_out("mqtt_out")
		DSO_mqtt_in("mqtt_in")
		DSO_out("out")
		DSO_inp ~~~ DSO_out
		DSO_mqtt_in ~~~ DSO_mqtt_out
	end
	DSO_mqtt_out --> MQTTControlUnit_mqtt_in
	subgraph MQTTControlUnit
		MQTTControlUnit_REALTIME_INTERRUPT("REALTIME_INTERRUPT")
		MQTTControlUnit_mqtt_in("mqtt_in")
		MQTTControlUnit_REALTIME_OBSERVED("REALTIME_OBSERVED")
		MQTTControlUnit_mqtt_out("mqtt_out")
		MQTTControlUnit_mqtt_in ~~~ MQTTControlUnit_mqtt_out
		MQTTControlUnit_REALTIME_INTERRUPT ~~~ MQTTControlUnit_REALTIME_OBSERVED
	end
	MQTTControlUnit_mqtt_out --> Generator_mqtt_in
	MQTTControlUnit_mqtt_out --> DSI_mqtt_in
	MQTTControlUnit_mqtt_out --> VacuumGripper_mqtt_in
	MQTTControlUnit_mqtt_out --> HighBayWarehouse_mqtt_in
	MQTTControlUnit_mqtt_out --> DSO_mqtt_in
	MQTTControlUnit_REALTIME_OBSERVED --> FischertechnikFactory_REALTIME_OBSERVED