Path Annotation Script
Introduction
READ THE GIANT WARNINGS
The equipment path annotation script allows users who are using the source scheduling component of Micromine Spry to inline basic constraints, dependency directives as well as some controls for path rewriting. While similar outcomes can be achieved using the existing Dependencies and Constraints section, this functionality assists in streamlining source scheduling. This is particularly useful in short-term scenarios where equipment interactions are a major concern and frequent rescheduling takes place. The constructs are implemented as a series of special comments that are attached to specific source path lines. For example:
Strip/1/2/12-8/C/60-50 'waitfree delay=3days
In a more general form, this is:
<annotated task> ' !<directive> <argument>
The annotation script can then be configured to recognize these directives (normally, they are comments which are ignored by Micromine Spry) and add additional behaviours to them. By convention, the comments are intended to affect behaviour related to the annotated tasks.
GIANT WARNINGS
Use of this script is intended for competent users only and is not officially supported. It represents a prototyping framework to test and receive feedback for proposed future features in Micromine Spry source paths.
There is no guarantee that the capabilities implemented herein will eventually be incorporated into - or even remain compatible with - future versions of Micromine Spry or even the script itself. As with anything, this is to be used at your own risk.
When the behaviour of this script is used in conjunction with stockpiles has not been tested and is effectively undefined. As this is still undergoing testing, there is a high chance that breaking changes will occur. More so than normal, use at your own risk.
The functionality described herein is not a default of Micromine Spry functionality. This functionality added via the use of a script that hooks into the schedule run. Please do not expect this to work in all models. It is necessary to read this document and then apply critical assessment.
Try to avoid using Allow Advance with the path annotation script. One of the major motivations in the creation of this script was to obviate the need for Allow Advance.
Installation
This script can be downloaded from the Attachments tab.
Add the attached script to the Micromine Spry scripting area, and then in the Case Settings, to invoke the script on scheduling setup:
Note that if you already have an existing setup script, you can add a line to the script to invoke the path annotator:
For convenience, you can copy and past the appropriate code into your scripts below:
print(sys.path)
public class ExistingSetupScript { public static void Setup(SchedulingEngine se) { // existing logic here // .. EquipmentPathAnnotation.SetupEngine(se); } }
For any equipment you use the path annotation syntax for, you must explicitly enable the path annotation by adding this line to the top of the file (or at least before any other annotation commands):
'!equipmentpathannotation_enable
This uses the equipment path annotation script. It is an unsupported utility with some documentation provided on the Micromine help site.
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 |
Argument Formatting
Some types of arguments are common amongst the different directives. This section discusses the appropriate formatting options available to them.
Delay Formats
Various directives allow for a delay= argument to be applied. This argument specifies a delay period between the event trigger time and when an item is released. In essence, the format is [number][unit specifier], where number is a numeric value and the unit specifier is m , h , d or w for minute, hour, day or week respectively.
Example | Description |
---|---|
20m | 20 Minutes |
2.5h | 2.5 Hours |
1d | 1 Day |
2.25w | 2.25 Weeks |
Source \ Destination Formats
Some directives can take a subset of tasks as an argument. As tasks can be either source tasks or destination tasks, the s: or d: prefix can be used to explicitly specify what type of tasks where applicable. Without this prefix, it will default assuming the argument relates to source tasks.
Source \ Destination Format Examples
Example | Description |
---|---|
s:A/1/1 | Source Tasks |
d:A/1/1 | Destination Tasks |
A/1/1 | Source Tasks; because no prefix is specified, source tasks are assumed |
Dates
Various directives allow for a on= , start= , end= argument to be applied. This argument specifies a date at which a particular event should occur.
Internally, the script calls the C# method System.DateTime.Parse, so theoretically any string accepted by that method should be valid.
The behaviour of this parse method also depends on the region/locale settings of the host Operating System. Different locales can produce different results for the same literal string. For instance, the string 1/12/2023 will represent the date 1st December 2023 in an Australian locale. In a US locale, this will represent the date 12 January 2023.
Date Examples
Example | Description |
---|---|
1/1/2023 | 1/1/2023 12:00 AM (Midnight) |
5/7/2023 2:37 PM | 5/7/2023 2:37 PM |
5/7/2023 2:37 AM | 5/7/2023 2:37 AM |
5/7/2023 2:37 | 5/7/2023 2:37 AM |
5/7/2023 14:37 | 5/7/2023 2:37 PM |
Snapshot Troubleshooting
The path annotation directives provide substantial power in more expressive scheduling, but this comes with concomitant complexity that can be difficult to troubleshoot. Some integration with the schedule snapshot tool is provided to assist with this.
Dependencies
For !depend directives, the dependency will describe the relevant Equipment Source Path Line where the dependency was set:
Wait Constraints
For !wait directives, the snapshot viewer will explain the relevant Equipment Source Path line where the constraint was set. This can come in three forms:
-
A wait is currently in effect. Here the drill task is waiting on 5 tasks which have not yet completed due to a directive set on line 3 of the drill's source path.
-
A wait is currently in effect. Here the drill task is still constrained because it has been subject to a release delay. The tasks it was previously waiting on have been completed, but a delay has been specified (in this case 1 day) and the tasks will be constrained until 1 day after the completion.
-
No wait is being applied. The drill task was previously waiting on 5 tasks, but these have been completed. This information is provided for debugging purposes.