Skip to main content
Skip table of contents

User Command

Change Note

Type

Changes

Compatible Task Editor Module Version
(Release date)

1

NEW

First created. Interface design for ‘User Commands’ function.

v1.0.0

2

NEW

  • ‘gen_command_call’ API

    • Added gen_command_call API for User Command with return value

  • ‘Get / Watch Global / System Variables from Task Editor’ API

    • Add API to get current Global and System variables from Task Editor

v1.4.0

3

REMOVED

  • Remove the componentId in 'req_to_save_commands_def_as_sub_program” API.

    • Changed the DRL of User Command, which is a SubProgram, to call only one for each User Command module package.

    • TIP Therefore, only one DRL per module can be saved as a User Command, so all def functions must be included in one DRL.

v1.4.0

4

NEW

  • ‘gen_command_call’ API

    • Add the "validity" property to activating or inactivating the user command block within the task editor module.

      • Tip: You can deactivate a command if required data for a property is missing.

image-20241101-064114.png

v2.0.5

Overview

Task Editor is a default module included in Dart-Platform and User Command is one of the functions in this module.

1. Interface call relationship diagram

The Interface that User Command type module supports are following below.

Use Case

Description

1

List-up

  • Displays the module list of User Command type which is installed within the User Command category in Dart-Platform.

  • However, only the modules that provide interface Task Editor module requests are displayed.

2

Start a PiP Screen with/without saved data

  • If user selects random menu among the submenus of Use Command, it runs the PiP Screen of the slected User Command module and initializes the UI with the delivered data.

3

Get data from the PiP Screen

  • Delivers the entered value in the PiP Screen of selected User Command module to the Task Editor module.

4

Request save DRL Function Definition for the User Command to the Controller

  • Requests the registration of DRL Function Definition defined in User Command into Sub program in Controller.

  • Uses User Command by loading it via ‘sub_program_run()’ DRL within the Task Editor.

CODE
from DRCF import * // The import statement must be declared for the sub program
 
def pick(j1, j2, j3, ...)
     ...
     movej(posj(j1, j2, j3, …), …)
     ...
5

Generate Function Call of the User Command

  • Delivers the calling code of ‘DRL Function’ to Task Editor according to entered value by the user of each User Command.

CODE
dart_module_xxx_mycommands.pick(0,0,0, ...)

2. Detailed Definition on the Interface and its Example codes

Task Editor module considers defined component ‘com.dart.module.taskeditor.action.USER_COMMAND’ as module component that provides interface for ‘User Command’.

2-1) List-up

  • When entering into Task writing screen of Task Editor module.

  • Purpose : To display User Command module block which is installed in Dart-Platform within the ‘User Commands’ Category.

  • Method : IModulePackageManager & Message

Name

Value

action

  • “com.dart.module.taskeditor.action.USER_COMMAND”

category

  • Context.CATEGORY_PIP_SCREEN (= “dart.message.category.PIP_SCREEN”)

  • Context.CATEGORY_SERVICE (= “dart.message.category.SERVICE”)

Example code
  1. Use Command

CODE
// manifest.json
screens : [
  {
    "name": {Menu name in Task Editor module is used},
    "id": {pip-screen-component-id}
    "messageFilters": [
      {
        "action": "com.dart.module.taskeditor.action.USER_COMMAND",
        "category": "dart.message.category.PIP_SCREEN"
      }
    ]
  }
],

services : [
  {
    "name": {Service component name},
    "id": {service-component-id(should be same as pip-screen-component-id)}
    "messageFilters": [
      {
        "action": "com.dart.module.taskeditor.action.USER_COMMAND",
        "category": "dart.message.category.SERVICE"
      }
    ]
  }
]

  1. Task Editor

CODE
const message = new Message({action:"com.dart.module.taskeditor.action.USER_COMMAND", category: Context.CATEGORY_PIP_SCREEN});
const packageManager = this.moduleContext.getSystemManager(Context.MODULE_PACKAGE_MANAGER) as IModulePackageManager;
const resolveInfos = packageManager.queryModuleScreenInfo(message);
// Compose the sub menu of 'User Command' by using resolveInfos information

2-2) Start a PiP Screen with/without saved data

  • When selecting ‘User Command’ block which is added within the task of Task Editor module

  • Purpose: To displaying the PRoperty of selected User Command (PiP Screen) and initialize data.

  • Method : IModuleScreenManager & Message

Sort

Value

action

  • “com.dart.module.taskeditor.action.USER_COMMAND”

category

  • Context.CATEGORY_PIP_SCREEN (= “dart.message.category.PIP_SCREEN”)

componentId

  • Component ID information of target PIP Screen

data

key

type

notice

savedData

Record<string, any> | undefined

  • It is a data delivered from User Command module via ‘2-3’ interface.

  • It is composed of key-value pair object which is defined in each User Command.

savedVersion

string

  • Version information of User Command module used at the time of saving data.

Example code
  1. User Command

CODE
class PipScreenForTaskEditor extends ModuleScreen { 
  componentDidMount() {
    // 1. At PiPScreen mount point, when saveData exists in message, UI initialization proceeds
    if (this.message && this.message.data.hasOwnProperty("savedData")) {
      const version = this.message.data["savedVersion"];
      const data = this.message.data["savedData"];
    }
  }
}

2. Task Editor

CODE
readonly handleOnClickMenu = (packageName: string) => { // packageName of User Command module that User selected
  // 1. Initialization of message obejct for PiPScreen execution of selected User Command module
  const message = new Message({action:"com.dart.module.taskeditor.action.USER_COMMAND", category: Context.CATEGORY_PIP_SCREEN, packageName});

  // 2. When loading the saved data to the screen, add data to message.data
  // const { data, version } = db.query(...);
  // message.data = { savedVersion: version, savedData: data};

  // 3. Request for execution and binding of PiPScreen
  const screenManager = this.moduleContext.getSystemManager(Context.MODULE_SCREEN_MANAGER) as IModuleScreenManager;
  screenManager.bindPipModuleScreen(message, this.refCotnainer.current, this.binder)
    .then(result => {
      if (!result) {
        // Exception handling is required on binding failure
      }
  });
}

private channel: IModuleChannel | null = null;
// 4. binder Initializaion
readonly binder: IModuleComponentBinder = {
  onBound: (packageName: string, componentId: string, channel: IModuleChannel) => {
    // Check whether the channel of binded User Command module component provides the event this Task Editor module needs
    if (!channel.containsOnAnotherSide(["get_current_data"]) {
      // Exception handling is needed on required event absence
    }
  }
}

2-3) Get data from PiP Screen

  • When saving the task of Task Editor module

  • Purpose: To transmit and receive data in order to save the user’s entered value within Property (PiP Screen) of User command module into Task Editor DB.

  • Method: ModuleScreen & IModuleChannel

Sort

Value

eventName

arguments

notice

send

(request)

get_current_data

-

  • Request event for the currently entered value on PiP Screen of User Command module.

receive

(response)

get_current_data

Record<string, any> | undefined

  • Delivers the entered values by current user on PiP Screen to key-value pair object.

Example code
  1. User Command

CODE
class PipScreenForTaskEditor extends ModuleScreen {
  onBind(message: Message, channel: IModuleChannel): boolean {
      ...
      // 1. Event Registration for receiving "get_current_data" event from Task Editor module
      channel.receive("get_current_data", () => {
          const data: Record<string, any> = {};

          // 2. Add data entered in PiPScreen to data object
          // data["..."] = ...;

          // 3. Deliver it to Task Editor module
          channel.send("get_current_data", data);
      });
      ...
      return true;
  }
}

2. Task Editor

CODE
getDataFromUserCommand = (channel: IModuleChannel, resolveInfo: IModuleResolveInfo) => {
  // 1. Event registration for receiving "get_current_data" response event from User Command
  channel.receive("get_current_data", (data?: Record<string, any>) => {
    if (data) {
      // 3-1. Version information of User Command module
      const version = resolveInfo.packageInfo.version;
      const packageName = resolveInfo.packageInfo.packageName;

      // 3-2. Save data and version information delivered from User Command module
      const db.insert/update(packageName, version, data);
    }
  });

  // 2. "get_current_data" event request to User Command module
  channel.send("get_current_data");
}

2-4) Request to save Commands Definition as sub program / Generate Command Call through ModuleService

  • When generating DRL syntax for task execution in Task Editor module

  • Purpose : To transmit and receive the DRL syntax information on User Command used in Task.

  • Method : ModuleService & IModuleChannel

Sort

Value

eventName

arguments

notice

send

(request)

req_to_save_commands_def_as_sub_program

{

programName: string

}

  • Request event to save the Command Function Definition defined in the User Command as a sub program in the Controller

  • Only one request per User Command module package used within the task

receive

(response)

req_to_save_commands_def_as_sub_program

boolean

  • Receiving event of delivering the Command Function Definition saving result on Controller.

send

(request)

gen_command_call

TYPESCRIPT
{
  componentId:string,
  data: Record<string, any>
}

  • Request event of Command Function Call command generation based on the entered value by user on User Command.

receive

(response)

gen_command_call

string

  • Receiving event of delivering Command Function Call.

  • Received event for Command Function Call with return value

e.g. default return value

CODE
{
   command: "pick(10,20,30,…)',
   variableName: "global_pos"
}

e.g. When the data is invalid and the DRL cannot be generated, the value should be provided as shown below.

CODE
{
   validity: false
}

An example DRL that is generated is as follows:

CODE
{variableName} = {subProgramInstance}.{command}

TYPESCRIPT
{
  command: string,
  variableName: string,
  validity: boolean (default true)
}
Example code
  1. User Command

CODE
class ServiceForTaskEditor extends ModuleService {
  onBind(message: Message, channel: IModuleChannel): boolean {
      ...
      // 1-1. Event registration for receiving "req_to_save_commands_def_as_sub_program" event from Task Editor module
      channel.receive("req_to_save_commands_def_as_sub_program", ({programName: string}) => {
          // 1-2. Generate Commands Definition for User Command execution
          const program = `
          from DRCF import *
          def pick(j1, j2, j3, ...):
              movej(posj(j1, j2, j3, ...), ...)
              ...
          
          def releaes(j1, j2, j3, ...):
              movej(posj(j1, j2, j3, ...), ...)
              ...
          `;

          const programManager = this.moduleContext.getSystemManager(Context.PROGRAM_MANAGER) as IProgramManager;
          programManager.saveSubProgram(PROGRAM_SAVE_MODE.SAVE, programName, program)
            .then(result => {
                // 1-3. Delivers the information on sub program saving result to Task Editor
                channel.send("req_to_save_commands_def_as_sub_program", result);
            });
      });

      // 2-1. Event registration for receiving "gen_command_call" event from Task Editor module
      channel.receive("gen_command_call", ({componentId: string, data: Record<string, any>}) => {
          // 2-2. About the appropriate Command for 'componentId', generates Command Function Call create command based on the data (user input) (The function must be existing on Command Definition registered at 1.2)
          const result = "..."; // i.e.) pick(10,20,30, ...);
          
          // // i.e) result sample with return variable 
          // // global_pos = pick(10,20,30,…)
          // const result = {
          //        command: "pick(10,20,30,…)',
          //        variableName: "global_pos"
          //      }
          
          // // i.e) result sample when it fail to generate DRL code. 
          // const result = {
          //        validity: false
          //      }
          
          // 2-3. Deliver result (string)
          channel.send("gen_command_call", result);
      });
      ...
      return true;
  }
}

  1. Task Editor

CODE
private bindToUserCommandService = (packageName: string) => {
  // 1. Define Message to bind with Service Component of target User Command module
  const message = new Message({action:"com.dart.module.taskeditor.action.USER_COMMAND", category: Context.CATEGORY_SERVICE, packageName });
 
  // 2. Binding request via IModuleServiceManager
  const serviceManager = this.moduleContext.getSystemManager(Context.MODULE_SERVICE_MANAGER);
  serviceManager.bindModuleService(message, this.binder)
    .then(result => {
      if (!result) {
        // Exception handling is required on binding failure
      } else if (!channel.containsOnAnotherSide(["req_to_save_commands_def_as_sub_program", "gen_command_call"]) {
        // Exception handling is needed on event absence Task Editor module requires
      } else {
        // do something
      }
  });
}

private channel: IModuleChannel | null = null;
private binder: IModuleComponentBinder = {
   onBound: (packageName: string, componentId: string, channel: IModuleChannel) => {
      this.channel = channel
  },
  onUnbound(packageName: string, componentId: string): void {
      this.channel = null;
  }
}

// When running task, request to register the function definition file on User Commands which are used in the Task, as Sub Program directly to the Controller with User Command module
private reqToSaveCommandDefAsSubProgram = (channel: IModuleComponentBinder, commandModulePackageName: string, componentId: string) => {
  // 3. Event register for receiving "gen_drl_function_definition" response from User Command module
  const subProgramName = `${commandModulePackageName.replaceAll(".", "_")}_commands`;
  channel.receive("req_to_save_commands_def_as_sub_program", (result: boolean) => {
    if (result) {
       // 5-1. If User Commands successes to save sub program, add DRL command that loads the sub program from the top of the task of Task Editor
       // i.e.) Statements such as "xxxCommands = sub_program_run("subProgramName"")" must be added on the top of the DRL program data
    } else {
       // 5-2. Handling exceptions that prevent DRL execution due to the User Command issue
    }
  });
  
  // 4. "req_to_save_dommands_def_as_sub_program" event request to User Command module
  channel.send("req_to_save_commands_def_as_sub_program", {programName: subProgramName});
}

// When running task, adding Function Call statement is needed for operation of each User Command (Required for each User Command added within the task)
private generateDrlFunctionCall = (channel: IModuleComponentBinder, componentId: string, data: Record<string, any>) => {

  // 6. Event registration for receiving "gen_command_call" response from User Command module
  channel.receive("gen_command_call", (cmdCallFunc: string | null) => {
    if (cmdCallFunc) {
      // 8. Add call syntax by combining cmdCallFunc value delivered from User Command module and variable value loaded Command program of 5-1
      // i.e.) Assuming cmdCallFunc is 'pick(10, 20, 30, ...)', DRL syntax xxxCommands.pick(10, 20, 30, ...) must be added
    } else {
      5-2. Handling exception occurred by Command Call Function generation failure of User Command
    }
  });

  // 7. "gen_command_call" event request to User Command module
  channel.send("gen_drl_function_call", {componentId: componentId, data: data});
}

2-5) Get / Watch Global / System Variables from Task Editor

  • When selecting the ‘User Command’ block added within the task of the Task Editor module

  • Purpose: Provide variables to store result values in the Property (PiP Screen) of the selected User Command

  • Method: IModuleScreenManager & Message

  • This API is the API that the Task Editor module must provide for the User Command module.

Sort

Value

eventName

arguments

notice

send

(request)

get_variables

-

  • In the User Command module, an event requests a list of Global and System variables declared in the currently open Task Editor file.

receive

(response)

get_variables

{

name: string

division: 0|1

type: 0|1|2|3|4|5|6|7

}[]

  • An event that provides a list of variables declared in the currently open Task Editor file.

CODE
division
- 0: system
- 1: global

type
- bool:0, int:1, float:2, string:3:, posj:4, posx:5, list:6, unknown:7

send

(request)

changed_variables

{

name: string

division: 0|1

type: 0|1|2|3|4|5|6|7

}[]

  • Notification event when the list of Global and System variables declared in the file of the currently open Task Editor has changed.

receive

(response)

changed_variables

{

name: string

division: 0|1

type: 0|1|2|3|4|5|6|7

}[]

  • In the User Command module, an event to receive notification of changes to the Global and System variable list from the Task Editor.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.