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.

: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

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.