:anger: Annotation Commands

The following annotation directives are supported:

 

!waitfree

Suppress processing of the annotated tasks until they all free of external predecessors (the term external is explained below). Semantically, this has the effect of grouping the annotated tasks and processing them only when they are all free of external predecessors. This is implemented as a constraint and hence is specific to the equipment only (as opposed to !dependfree ), at the cost of greater performance.

Here, 'external' refers to predecessors that are not part of the annotated tasks themselves. To provide an intuitive explanation of why this is done, consider the following path:

Strip/1/2/12-8/60-50 ' !waitfree

This line contains multiple benches. If there is a top-down dependency in place, it is likely that the tasks at RL 50 have a dependency to wait on the tasks at RL 60. It is not constructive for these dependencies to be included in the wait, as they effectively set a circular dependency (strictly speaking not a dependency per se) and hence they are excluded.

!waitfree examples

Example Description
Strip/1/2/12-8/C/60 '!waitfree
Strip/1/2/12-8/C/60 '!waitfree delay=3days Once the tasks are free, delay an additional 3 days. This may be useful for modelling cleanup activities.

Note that waitfree, while powerful, often leads to confusion when it is misused. Some additional notes about troubleshooting this are discussed in the Snapshot Troubleshooting section.

 

!waiton

Prevent processing of all tasks until all of the specified tasks in the argument have been completed.

This is implemented as a constraint and hence is specific to the equipment only (as opposed to !dependon), at the cost of greater performance.

!waiton examples

Example Description
Strip/1/2/12-8/C/60 ' !waiton Strip/1/1/12-8/C <coal>
Strip/1/2/12-8/C/60 ' !waiton s:Strip/1/1/12-8/C <coal> Explicitly indicate the predecessor tasks are source tasks
Strip/1/2/12-8/C/60 ' !waiton d:dump1/1/1/14 Explicitly indicate the predecessor tasks are destination tasks
Strip/1/2/12-8/C/60 ' !waiton Strip/1/1/12-8/C <coal> delay=1day Once predecessor tasks are complete, delay for an additional day
Strip/1/2/12-8/C/60 ' !waiton s:Strip/1/1/12-8/C <coal> delay=4hours Combination of above
Strip/1/2/12-8/C/60 ' !waiton d:dump1/1/1/14 delay=30min Combination of above

Note that waiton, while powerful, often leads to confusion when it is misused. Some additional notes about troubleshooting this are discussed in the troubleshooting section below.

!dependfree

Set dependency so all annotated tasks in path will wait on all predecessors of annotated tasks in path. This is effectively a cross-dependency - for N annotated tasks with a total of M dependencies across them, the number of dependencies set will be N x M. It is implemented as a dependency and hence the restriction will apply to all equipment and will perform faster than !waitfree.

!dependfree examples

Example Description
Strip/1/2/12-8/C/60 '!dependfree
Strip/1/2/12-8/C/60 '!dependfree delay=3day Once the tasks are free, delay an additional 3 days. This may be useful for modelling cleanup activities.

 

!dependon

Set dependency so all annotated tasks in path will wait on all predecessors of annotated tasks in path. This is effectively a cross-dependency - for N annotated tasks with a total of M dependencies across them, the number of dependencies set will be N x M. It is implemented as a dependency and hence the restriction will apply to all equipment and will perform faster than !waiton.

!dependon examples

Example Description
Strip/1/2/12-8/C/60 ' !dependon Strip/1/1/12-8/C <coal>
Strip/1/2/12-8/C/60 ' !dependon s:Strip/1/1/12-8/C <coal> Explicitly indicate the predecessor tasks are source tasks
Strip/1/2/12-8/C/60 ' !dependon d:dump1/1/1/14 Explicitly indicate the predecessor tasks are destination tasks
Strip/1/2/12-8/C/60 ' !dependon Strip/1/1/12-8/C <coal> delay=1day Once predecessor tasks are complete, delay for an additional day
Strip/1/2/12-8/C/60 ' !dependon s:Strip/1/1/12-8/C <coal> delay=4hours Combination of above
Strip/1/2/12-8/C/60 ' !dependon d:dump1/1/1/14 delay=30min Combination of above

 

!dependclear

Clear annotated tasks of predecessors.

Arguments can be applied to limit the time of application and predecessors cleared.

Note: this feature was originally implemented before the Ignore Dependencies directive was implemented in source paths. It is left in for legacy reasons but it is worth considering if the directive may be more applicable.

!dependclear examples

Example Description
Strip/1/2/12-8/C/60 ' !dependclear Immediately clear all predecessors from annotated tasks
Strip/1/2/12-8/C/60 ' !dependclear A/1/2 <asdf> Immediately clear predecessor tasks in the range A/1/2 from annotated tasks
Strip/1/2/12-8/C/60 ' !dependclear on=1/1/2023 Clear all predecessors from annotated tasks on 1/1/2023
Strip/1/2/12-8/C/60 ' !dependclear A/1/2 <asdf> on=4 April 2023 Combination of above

 

!remove

Remove the annotated line from the equipment source path based on a variety of triggers.

This is intended to be used with the Allow Duplicates: On directive. Without this directive, subsequent path lines intended to process the same tasks are removed by the Scheduling Engine (for optimisation/performance reasons), so removal of the path would permanently prevent the equipment from processing removed tasks. This behaviour may or may not be desired.

This removes only the annotated line from the equipment source path. If Allow Duplicates is enabled it is possible that tasks in the annotated line still exist elsewhere in the equipment source path.

!remove examples

Example Description
Strip/1/2/12-8/C/60 ' !remove Immediately remove this line from the equipment path
Strip/1/2/12-8/C/60 ' !remove tasks=A/1/2 <asdf> event=available Remove this line from the equipment path when the tasks A/1/2 become available (free of dependencies)
Strip/1/2/12-8/C/60 ' !remove tasks=A/1/2 <asdf> event=completed Remove this line from the equipment path when the tasks A/1/2 have been completed
Strip/1/2/12-8/C/60 ' !remove tasks=A/1/2 <asdf> event=completed delay=12h Remove this line from the equipment path 12 hours after the tasks A/1/2 have been completed
Strip/1/2/12-8/C/60 ' !remove tasks=A/1/2 <asdf> event=available delay=12h Remove this line from the equipment path 12 hours after the tasks A/1/2 become available (free of dependencies)
Strip/1/2/12-8/C/60 ' !remove on=1/1/2023 Remove this line from the equipment path on the 1/1/2023

 

!timeconstrain

Prevent processing of annotated tasks based on hard time limits. This can be used to either allow activity within the specific limits, or suppress activity within the specific limits.

!timeconstrain examples

Example Description
Strip/1/2/12-8/C/60 ' !timeconstrain Prevent processing of annotated tasks from the start to end of the schedule
Strip/1/2/12-8/C/60 ' !timeconstrain mode=suppress start=1/1/2023 end=1/2/2023 Prevent processing of annotated tasks between 1/1/2023 and 1/2/2023
Strip/1/2/12-8/C/60 ' !timeconstrain mode=allow start=1/1/2023 end=1/2/2023 Allow processing of annotated tasks only between 1/1/2023 and 1/2/2023
Strip/1/2/12-8/C/60 ' !timeconstrain mode=allow start=1/1/2023 Allow processing of annotated tasks only after 1/1/2023
Strip/1/2/12-8/C/60 ' !timeconstrain mode=suppress end=1/1/2023 Prevent processing of annotated tasks until 1/1/2023

 

!deadhead / !delayafter

Apply a delay after the annotated tasks have been completed.

This delay occurs even if the tasks are completed by other equipment.

!deadhead examples

Example Description
Strip/1/2/12-8/C/60 ' !deadhead 12h Delay for 12 hours after the annotated tasks have been completed. The equipment's nonproductive process will be used for the delay
Strip/1/2/12-8/C/60 ' !deadhead 16h process=Deadheading Delay for 16 hours after the annotated tasks have been completed. The nonproductive process 'deadheading' will be used for the delay

 

!forcecompletion

Force the line to complete at a specific date.

The completion is achieved by setting the source rate to a sufficiently high value to complete instantaneously. This will have implications for any trucking calculations.

!forcecompletion examples

Example Description
Strip/1/2/12-8/C/60 ' !forcecompletion Force the tasks to instantaneously complete at the start of the schedule
Strip/1/2/12-8/C/60 ' !forcecompletion on=1/1/2017 Force the tasks to be instantaneously completed on the 1st January 2017
Strip/1/2/12-8/C/60 ' !forcecompletion on=1/1/2017 obey=all Attempt to force the tasks to be instantaneously completed on the 1st January 2017. However, still honour any dependencies and/or constraints
Strip/1/2/12-8/C/60 ' !forcecompletion on=1/1/2017 obey=dep Attempt to force the tasks to be instantaneously completed on the 1st January 2017. However, still honour any dependencies
Strip/1/2/12-8/C/60 ' !forcecompletion on=1/1/2017 obey=con Attempt to force the tasks to be instantaneously completed on the 1st January 2017. However, still honour any constraints

 

!reprioritise

When the equipment acquires any of the tasks on this line, these tasks will be moved to the top of theequipment path list. This has the effect of reprioritising them, hence the name.

This is generally only meaningful with use of Allow Advance: On , as it is only with this directive that the equipment can 'advance' past tasks.

The envisioned usage here is basically to allow equipment to advance past previous tasks, but then 'lock on' to these tasks (i.e. it will attempt to finish what it starts).

The existence of this feature should not be taken as an endorsement to use it. Allow Advance: On is generally not recommended with this script. However the implementation was done as part of the never-ending arms race between bad practice and the features designed to mitigate the negative outcomes of such bad practice.

 

!injectschedulepath

Inject a schedule path from another scenario.

This may be useful when trying to "frankenstein" cases together. It should be noted that it simply converts existing schedule steps from another schedule into an input path for this case. As an input path is an attempt to schedule, there is no guarantee that it actually will for any number of reasons (dependencies, constraints, mismatching volumes, preschedule, prefilter, already processed, etc).

In general, it is expected that the source Case closely matches the Case that this is implemented in (with regards to processes, preschedule, reserves etc).

The order of this command relative to other path elements is (or should be) honoured.

!injectschedulepath examples

Example Description
' !injectschedulepath case=Other Case Copy output schedule from case named other case, for the equipment with the same full path name as this equipment. Ignore all dependencies and constraints.
' !injectschedulepath case=Other Case start=1/1/2018 end=1/6/2018 Copy output schedule only for period from 1/1/2018 to 1/6/2018
' !injectschedulepath case=Other Case type=input Copy input schedule from case named other case
' !injectschedulepath case=Other Case equipment=Excavators/EX1000 Same as first example but path from equipment named Excavators/EX1000
' !injectschedulepath case=Other Case obey=all Honour dependencies and constraints
' !injectschedulepath case=Other Case obey=dep Honour Dependencies
' !injectschedulepath case=Other Case obey=con Honour Constraints