SingleRun + HasDelayPlugin#
This example notebook shows how you can integrate percentual delays in your simulation. We demonstrate how you can use the HasDelayPlugin, and how you can give it a certain delay percentage.
0. Import libraries#
import datetime, time
import simpy
import shapely.geometry
import pandas as pd
import openclsim.core as core
import openclsim.model as model
import openclsim.plot as plot
import openclsim.plugins as plugins
1. Initialise simpy environment#
# setup environment (simulation time needs to match the available weather data)
simulation_start = 0
my_env = simpy.Environment(initial_time=simulation_start)
2. Define object classes#
# create a Site object based on desired mixin classes
Site = type(
"Site",
(
core.Identifiable,
core.Log,
core.Locatable,
core.HasContainer,
core.HasResource,
),
{},
)
# create a TransportProcessingResource object based on desired mixin classes
TransportProcessingResource = type(
"TransportProcessingResource",
(
core.ContainerDependentMovable,
core.Processor,
core.HasResource,
core.LoadingFunction,
core.UnloadingFunction,
core.Identifiable,
core.Log,
),
{},
)
3. Create objects#
3.1. Create site object(s)#
# prepare input data for from_site
location_from_site = shapely.geometry.Point(4.18055556, 52.18664444)
data_from_site = {"env": my_env,
"name": "from_site",
"geometry": location_from_site,
"capacity": 12,
"level": 12
}
# instantiate from_site
from_site = Site(**data_from_site)
# prepare input data for to_site
location_to_site = shapely.geometry.Point(4.25222222, 52.11428333)
data_to_site = {"env": my_env,
"name": "to_site",
"geometry": location_to_site,
"capacity": 12,
"level": 0
}
# instantiate to_site
to_site = Site(**data_to_site)
3.2. Create vessel object(s)#
# prepare input data for vessel_01
data_vessel01 = {"env": my_env,
"name": "vessel01",
"geometry": location_from_site,
"loading_rate": 1,
"unloading_rate": 1,
"capacity": 4,
"compute_v": lambda x: 10
}
# instantiate vessel_01
vessel01 = TransportProcessingResource(**data_vessel01)
3.3 Create activity/activities#
# initialise registry
registry = {}
keep_resources = {}
# create delay sequence activities
DelaySequenceActivity = type(
"TestShiftActivity",
(
plugins.HasDelayPlugin,
model.SequentialActivity, # the order is critical!
),
{},
)
DelayWhileActivity = type(
"TestShiftActivity",
(
plugins.HasDelayPlugin,
model.WhileActivity, # the order is critical!
),
{},
)
DelayMoveActivity = type(
"TestMoveActivity",
(
plugins.HasDelayPlugin,
model.MoveActivity, # the order is critical!
),
{},
)
DelayShiftActivity = type(
"TestShiftActivity",
(
plugins.HasDelayPlugin,
model.ShiftAmountActivity, # the order is critical!
),
{},
)
DelayBasicActivity = type(
"TestShiftActivity",
(
plugins.HasDelayPlugin,
model.BasicActivity, # the order is critical!
),
{},
)
# create a list of the sub processes
sub_processes = [
DelayMoveActivity(
env=my_env,
name="sailing empty",
registry=registry,
mover=vessel01,
destination=from_site,
delay_percentage=10,
),
DelayShiftActivity(
env=my_env,
name="load cargo",
registry=registry,
processor=vessel01,
origin=from_site,
destination=vessel01,
amount=4,
duration=10,
delay_percentage=10,
),
DelayMoveActivity(
env=my_env,
name="sailing full",
registry=registry,
mover=vessel01,
destination=to_site,
delay_percentage=10,
),
DelayShiftActivity(
env=my_env,
name="unload cargo",
registry=registry,
processor=vessel01,
origin=vessel01,
destination=to_site,
amount=4,
duration=10,
delay_percentage=10,
),
DelayBasicActivity(
env=my_env,
name="Basic activity",
registry=registry,
duration=0,
additional_logs=[vessel01],
delay_percentage=10,
),
]
# create a 'sequential activity' that is made up of the 'sub_processes'
sequential_activity = DelaySequenceActivity(
env=my_env,
name="Single run process",
registry=registry,
sub_processes=sub_processes,
delay_percentage=10,
)
# create a while activity that executes the 'sequential activity' while a stop condition is not met
while_activity = DelayWhileActivity(
env=my_env,
name="While activity",
registry=registry,
sub_processes=[sequential_activity],
condition_event=[{"type": "container", "concept": to_site, "state": "full"}],
delay_percentage=10,
)
4. Register processes and run simpy#
model.register_processes([while_activity])
my_env.run()
5. Inspect results#
5.1 Inspect logs#
pd.concat([plot.get_log_dataframe(act, [while_activity, sequential_activity, *sub_processes]) for act in sub_processes]).sort_values(by='Timestamp')
Activity | Timestamp | ActivityState | type | ref | |
---|---|---|---|---|---|
0 | sailing empty | 1970-01-01 00:00:00.000000 | START | NaN | NaN |
1 | sailing empty | 1970-01-01 00:00:00.000000 | STOP | NaN | NaN |
2 | sailing empty | 1970-01-01 00:00:00.000000 | WAIT_START | plugin | delay |
3 | sailing empty | 1970-01-01 00:00:00.000000 | WAIT_STOP | plugin | delay |
0 | load cargo | 1970-01-01 00:00:00.000000 | START | NaN | NaN |
1 | load cargo | 1970-01-01 00:00:10.000000 | STOP | NaN | NaN |
2 | load cargo | 1970-01-01 00:00:10.000000 | WAIT_START | plugin | delay |
3 | load cargo | 1970-01-01 00:00:11.000000 | WAIT_STOP | plugin | delay |
0 | sailing full | 1970-01-01 00:00:11.000000 | START | NaN | NaN |
2 | sailing full | 1970-01-01 00:15:53.824591 | WAIT_START | plugin | delay |
1 | sailing full | 1970-01-01 00:15:53.824591 | STOP | NaN | NaN |
3 | sailing full | 1970-01-01 00:17:28.107050 | WAIT_STOP | plugin | delay |
0 | unload cargo | 1970-01-01 00:17:28.107050 | START | NaN | NaN |
2 | unload cargo | 1970-01-01 00:17:38.107050 | WAIT_START | plugin | delay |
1 | unload cargo | 1970-01-01 00:17:38.107050 | STOP | NaN | NaN |
2 | Basic activity | 1970-01-01 00:17:39.107050 | WAIT_START | plugin | delay |
1 | Basic activity | 1970-01-01 00:17:39.107050 | STOP | NaN | NaN |
0 | Basic activity | 1970-01-01 00:17:39.107050 | START | NaN | NaN |
3 | unload cargo | 1970-01-01 00:17:39.107050 | WAIT_STOP | plugin | delay |
3 | Basic activity | 1970-01-01 00:17:39.107050 | WAIT_STOP | plugin | delay |
4 | sailing empty | 1970-01-01 00:19:25.017755 | START | NaN | NaN |
5 | sailing empty | 1970-01-01 00:35:07.842347 | STOP | NaN | NaN |
6 | sailing empty | 1970-01-01 00:35:07.842347 | WAIT_START | plugin | delay |
4 | load cargo | 1970-01-01 00:36:42.124806 | START | NaN | NaN |
7 | sailing empty | 1970-01-01 00:36:42.124806 | WAIT_STOP | plugin | delay |
6 | load cargo | 1970-01-01 00:36:52.124806 | WAIT_START | plugin | delay |
5 | load cargo | 1970-01-01 00:36:52.124806 | STOP | NaN | NaN |
4 | sailing full | 1970-01-01 00:36:53.124806 | START | NaN | NaN |
7 | load cargo | 1970-01-01 00:36:53.124806 | WAIT_STOP | plugin | delay |
6 | sailing full | 1970-01-01 00:52:35.949397 | WAIT_START | plugin | delay |
5 | sailing full | 1970-01-01 00:52:35.949397 | STOP | NaN | NaN |
7 | sailing full | 1970-01-01 00:54:10.231856 | WAIT_STOP | plugin | delay |
4 | unload cargo | 1970-01-01 00:54:10.231856 | START | NaN | NaN |
6 | unload cargo | 1970-01-01 00:54:20.231856 | WAIT_START | plugin | delay |
5 | unload cargo | 1970-01-01 00:54:20.231856 | STOP | NaN | NaN |
7 | unload cargo | 1970-01-01 00:54:21.231856 | WAIT_STOP | plugin | delay |
5 | Basic activity | 1970-01-01 00:54:21.231856 | STOP | NaN | NaN |
6 | Basic activity | 1970-01-01 00:54:21.231856 | WAIT_START | plugin | delay |
7 | Basic activity | 1970-01-01 00:54:21.231856 | WAIT_STOP | plugin | delay |
4 | Basic activity | 1970-01-01 00:54:21.231856 | START | NaN | NaN |
8 | sailing empty | 1970-01-01 00:57:50.853266 | START | NaN | NaN |
10 | sailing empty | 1970-01-01 01:13:33.677858 | WAIT_START | plugin | delay |
9 | sailing empty | 1970-01-01 01:13:33.677858 | STOP | NaN | NaN |
11 | sailing empty | 1970-01-01 01:15:07.960317 | WAIT_STOP | plugin | delay |
8 | load cargo | 1970-01-01 01:15:07.960317 | START | NaN | NaN |
9 | load cargo | 1970-01-01 01:15:17.960317 | STOP | NaN | NaN |
10 | load cargo | 1970-01-01 01:15:17.960317 | WAIT_START | plugin | delay |
8 | sailing full | 1970-01-01 01:15:18.960317 | START | NaN | NaN |
11 | load cargo | 1970-01-01 01:15:18.960317 | WAIT_STOP | plugin | delay |
9 | sailing full | 1970-01-01 01:31:01.784908 | STOP | NaN | NaN |
10 | sailing full | 1970-01-01 01:31:01.784908 | WAIT_START | plugin | delay |
8 | unload cargo | 1970-01-01 01:32:36.067367 | START | NaN | NaN |
11 | sailing full | 1970-01-01 01:32:36.067367 | WAIT_STOP | plugin | delay |
9 | unload cargo | 1970-01-01 01:32:46.067367 | STOP | NaN | NaN |
10 | unload cargo | 1970-01-01 01:32:46.067367 | WAIT_START | plugin | delay |
10 | Basic activity | 1970-01-01 01:32:47.067367 | WAIT_START | plugin | delay |
8 | Basic activity | 1970-01-01 01:32:47.067367 | START | NaN | NaN |
9 | Basic activity | 1970-01-01 01:32:47.067367 | STOP | NaN | NaN |
11 | unload cargo | 1970-01-01 01:32:47.067367 | WAIT_STOP | plugin | delay |
11 | Basic activity | 1970-01-01 01:32:47.067367 | WAIT_STOP | plugin | delay |
5.2 Visualise gantt charts#
objects = [while_activity, sequential_activity, vessel01, from_site, to_site]
objects.extend(sub_processes)
plot.get_gantt_chart(objects)