Clarity's Task Automation process takes tasks configured and requested on the server and sends them to one or more machines running the task server software.
Anyone with a good understanding of the Autodesk Revit API should be able to create and deploy new, custom tasks to use in their Clarity environment.
Create a new Project in Microsoft Visual Studio or a similar .NET development environment.
Then, include references to two DLLs that are part of the Clarity Product, Clarity.PluginAPI.dll and Clarity.RevitPluginAPI.dll. You also need to reference RevitAPI.dll and possibly to RevitAPIUI.dll (depending on what your custom task does).
Once the Project is ready, create a new class for a single custom task. The task must implement the interfaces: ITaskProcessor, IRevitPlugin.
A DLL is placed into the plugins folder under the Clarity Task Server software.
When Revit starts, it reads all of the DLLs and finds the tasks capable of performing on the machine.
The Clarity Task Server application publishes the capabilities to the Central Host and makes them available on the website. This includes the type of configuration required for each task.
Once published, an administrator can configure the specific behavior of the task (which Project to run it on, whether to schedule it or launch it on demand), and specify any Task-specific parameters if required.
Once created and added to the queue of current tasks, the task becomes visible to all of the task servers. If the task is a type that this specific task server can perform, it will launch Revit (if not already running). The Clarity Task Server for Revit will then claim the task, retrieve the relevant model, and call the Task DLL to perform the required action.
The Task DLL provides information back (i.e. whether the task was successful, results the results of the task, any files produced, etc).
Verify that the task is registered at the top of the Clarity Task Sever log file.
The task places the files where required, generally in the Revit Artifacts folder provided.
The task server must arrange for any created output files to be sent back to the central host.
The task should create a temporary folder, store all of the files in that folder, and fill in the OutputFiles field with their full paths. The Task Server takes responsibility for delivering them back to the Revit Artifacts folder on the central host.
Recommended: Store the files into the task server's artifact folder (passed to you with the Initialize() method). This enables Clarity to determine the file's relative path to the task server's artifact folder, so that it can send the file to the corresponding path on the host, relative to the host's artifact folder.
Each Project is assigned an artifact folder. In that folder, artifacts useful to the entire Project are stored in the _ProjectArtifacts subfolder and are displayed on the Files page in Clarity.
Alternatively, if an output file is specific to a particular Revit model, a subfolder is created for that Revit model and the output file is placed under that subfolder. Files placed in model-specific subfolders display when viewing the details of the model in Clarity.
Instead of testing using a full deployment of Clarity, it is recommended (and helpful) to test the task in a local environment (including support for a debugger). To do so, use IMAGINiT's test-harness Clarity Task Tester application, which enables you to run your task in an isolated environment.
To receive a copy of the Clarity Task Tester application, contact devfeedback@rand.com or contact IMAGINiT Support.
ITaskProcessor requires the following methods:
|
Method Name |
Output |
Purpose |
|
GetPlugInOptions() |
PlugIn |
Returns specific information for this plugin by filling in the files on the PlugIn object. |
|
CanProcess(string taskType) |
Bool |
Verify if this task can support a given type of task. |
|
CanProcessTask(Task t) |
Bool |
Verify if this task can be performed on this server (receives a full task object, useful for a more comprehensive yes or no, based on configuration, etc). |
|
Execute(Task t) |
Bool |
Execute the task, given the task configuration. |
IRevitPlugin requires the following methods:
|
Method Name |
Output |
Purpose |
|
Initialize(Document doc, string artifactFolder, PluginExtraData extra) |
void |
This method is initialized before the execute call is performed in Revit, enabling Clarity to have access to the appropriate Document object and the artifact folder. The PluginExtraData object mostly holds the accessor object is used in the rare cases where your project must separately download or upload Revit files to the project repository. |
|
GetOpenOptions(Task t) |
OpeningOptions |
This method determines a number of options on how this task would like to have the Revit model opened. Depending on the options chosen, it may cause the model to be opened only for this specific task, or in other cases it may allow multiple tasks to be grouped into a single load of the model. |
IWindowsPlugin requires the following methods, in order to be able to run the task outside of Revit (if applicable):
|
Method Name |
Output |
Purpose |
|
Initialize(string artifactFolder, PluginExtraData extra) |
void |
This method is initialized before the execute call is performed in Revit, enabling Clarity to have access to the appropriate Document object and the artifact folder. The accessor object is used in the rare cases where your project must separately download or upload Revit files to the project repository. |
The PlugInExtraData Object is used to pass extra task specific information to the task. This may be enhanced in future releases.
|
Property |
Type |
Default Value |
Description |
|
ProjectFileAccessor |
IDictionary<string, IProjectFileAccessor> |
Input |
A dictionary of names to objects connected to external project data accessors. The accessor object is used in the rare cases where your project must separately download or upload Revit files to the project repository. |
|
CancelToken |
System.Threading.CancellationToken |
None |
A token used in certain situations to flag the killing of the task. |
The PlugIn Object can be filled with specific task settings in the GetPlugInOptions method.
|
Property |
Type |
Default Value |
Description |
|
Capabilities |
String[] |
Needs input |
A list of task types that this class can perform. |
|
Config |
String |
Empty |
An XML formatted document describing the custom parameters required for this task. For more details, see Custom Tasks API: Appendix A. |
|
ConfigHeader |
String |
Empty |
Optional header to show on the task configuration page. Default: null and ignored by the clarity user interface |
|
HasUserSpecificResources |
String |
Empty |
Name of resources required for the task. For example: PDF drivers require registry entries which prevent two PDF tasks running simultaneously with the same driver. |
|
HelpURL |
String |
Empty |
Help URL for the task to launch from the Task page. |
|
Scopes |
String |
Empty |
A comma-delimited list of the task scopes this task can be run with. Options: File, Project, and Server. |
|
SupportsPostAction |
BOOL |
TRUE |
Set to TRUE if the post action commands are available for the task. |
|
PlatformParameters |
String |
Empty |
An XML definition of additional task parameters that are platform-specific, such as Revit tasks having worksets. See teh appendix for the XML format. If you would like to support Revit worksets in your task, return "OpeningOptions.GetOpenWorksetsXML()" |
|
Platform |
String |
Empty |
A comma-separated list of values from the list of supported platforms - currently "REVIT" and "WINDOWS" - Windows is used for tasks that can run without Revit in the Windows Service Task Server. An Empty value will default to "Revit" for now. |
|
Category |
String |
Other |
For the "Add Task" user interface, the tasks are now categorized in groups. This setting allows you to pick your category (or create a new category). |
|
DisplayName |
String |
Empty |
A name for the task that is separate from the Capabilities list. |
|
IsSecurityAware |
BOOL |
FALSE |
A flag to indicate that this task does have Windows security implications (for example, writes to the file system, or may require trusted path review). |
The Task Object is the key object utilized in the Clarity Task API.
Generally, the custom task must look at the inputs of the task, work with the current Revit document, and fill in the outputs as appropriate.
|
Method |
Returns |
Description |
|
GetTaskApi() |
ITaskApi |
Retrieve an interface to be able to create and check on tasks. |
|
AddToLog(string msg, bool visible = true) |
void | Add a message to the Task Log. If visible, then it should be visible to the end user (not just in a log file). |
|
Property |
Type |
Default Value |
Description |
|
TypeName |
String |
Input |
Type of the task (i.e. DWF or Special DWF) |
|
Scope |
Enum |
Input |
|
|
Target |
String |
Input |
|
|
RevitUserId |
Int |
Input |
The requesting user Id number, if manually launched. |
|
Server |
String |
Input |
The originating server of the task. |
|
TargetType |
Enum |
Input |
RevitServer / File |
|
OriginalPath |
String |
Input |
The original path of the target file, if appropriate. |
|
AbsolutePath |
String |
Input |
The Absolute Path of the target file, if appropriate. |
|
TaskParameters |
List of TaskParameter |
Input |
List of keyword/value pairs for the configuration of this task. Includes both standardized as well as custom. |
|
Status |
Enum |
Both |
New, InProgress, Error, Complete |
|
OutputFiles |
List of String |
Output |
Full paths of any files which should be sent back to the central host (if running on a machine which is not the central host). |
| OutputFolderRoot | String | Output | (Optional) If the output files are in multiple folders, specifying what the "root folder" of the output files are will assist in Post Actions being able to potentially re-create the folder structure and preserve the folder hierarchy. |
|
ErrorMessage |
String |
Output |
Error message to display to the administrator in case of an error. |
| ErrorNumber | Integer | Output | Error number to use to help categorize errors. See enumerated type: Clarity.PluginAPI.TaskErrorCodes.ClarityErrorCode |
|
CreateActivity |
Bool |
Output |
Whether an entry should be created in the project’s activity stream. |
|
ActivityMessage |
String |
Output |
Optional message in the activity stream. |
|
ActivityURL |
String |
Output |
Optional URL to link from the activity stream. |
|
ThumbnailURL |
String |
Output |
Optional URL to show a thumbnail of the activity. |
|
ShouldUploadFiles |
BOOL |
Output |
Set to TRUE if output files should be uploaded to the server. |
|
PDFDriverName |
String |
Input |
PDF Driver configured to be used. |
|
ClarityWindowsUserSid |
String |
Input |
The Windows user identifier that is running the task. |
|
CleanUploadFolder |
BOOL |
Output |
If files are being uploaded, should we wipe out the contents of the target folder first. |
|
EnvironmentType |
Enum |
Input |
Revit, Windows, Cloud |
The OpeningOptions Object is useful if your task needs the Revit model to be opened with particular options, in order to get the behavior you want.
In most cases, you can return OpeningOptions.DefaultOpeningOptions(), and it will use the default values.
|
Property |
Type |
Default Value |
Description |
|
Audit |
Bool |
False |
Audit the model during the open process. |
|
DetachModel |
Bool |
True |
Request that the model be opened detached from any central file, so that changes to elements do not result in element borrowing, etc. |
|
DetachDiscardWorksets |
Bool |
False |
If the model is opened detached, should worksets be discarded. |
|
ChangesTheModel |
Bool |
False |
Informs the Task Server that this task may make changes to the model. This will likely cause the task to not run in conjunction with other tasks (because the later tasks would not be running on a "clean" copy of the model). |
|
Standalone |
Bool |
False |
Force the task to run in isolation from other tasks. |
|
WorksetSubsetNames |
List<String> |
(empty) |
A list of workset names that should be opened. |
|
ActivateView |
Bool |
False |
Whether the model should load and be activated within a view (in most cases, it is not loaded this way, in order to make the process faster- but some Revit APIs now require an active view). |