Script Orchestration

Script Orchestration enables modular, reusable automation by allowing scripts to call other scripts, chain them sequentially, run them in parallel, pass data between them, and schedule them for automated execution.

Key Capabilities

CapabilityDescription
Modular ScriptsBreak complex automation into reusable, testable units
Script ChainingExecute scripts sequentially with await
Parallel ExecutionRun multiple scripts simultaneously
Return ValuesPass data from spawned scripts back to the caller
Fire-and-ForgetSpawn background scripts without waiting
SchedulingSchedule scripts to run at specific times via the GUI
Real-time MonitoringTrack running scripts in the Running Scripts dialog

Basic Usage

Sequential Chaining:

JS
// Scripts run one after another await oloClient.core.executeScript('initialize-robot'); await oloClient.core.executeScript('run-patrol'); await oloClient.core.executeScript('return-to-dock'); console.log('Mission complete!');

Parallel Execution:

JS
// Run multiple scripts simultaneously const [result1, result2] = await Promise.all([ oloClient.core.executeScript('monitor-sensors'), oloClient.core.executeScript('check-battery') ]); console.log('Both checks complete:', result1, result2);

Fire-and-Forget (Background Execution):

JS
// Start a long-running script in the background oloClient.core.executeScript('continuous-monitoring').catch(console.error); console.log('Monitoring started, continuing with other work...');

Passing Data Between Scripts

Scripts can return values to their caller using setScriptResult() / set_script_result().

Spawned Script (e.g., "calculate-distance"):

JS
// Perform calculation and return result const distance = await measureDistance(); oloClient.core.setScriptResult({ distance: distance, unit: 'meters', timestamp: Date.now() });

Calling Script:

JS
const result = await oloClient.core.executeScript('calculate-distance'); console.log('Distance:', result.result.distance, result.result.unit); // Output: Distance: 5.2 meters

Real-World Example: Multi-Room Patrol

Main Script ("patrol-all-rooms"):

JS
const rooms = ['kitchen', 'living-room', 'bedroom', 'office']; const results = []; for (const room of rooms) { console.log(`Patrolling ${room}...`); // Each room has its own patrol script const result = await oloClient.core.executeScript(`patrol-${room}`); results.push({ room: room, duration: result.duration, findings: result.result }); } console.log('Patrol complete!'); console.log('Summary:', JSON.stringify(results, null, 2)); // Return aggregate results oloClient.core.setScriptResult({ roomsPatrolled: rooms.length, totalTime: results.reduce((sum, r) => sum + r.duration, 0), findings: results });

Room Script ("patrol-kitchen"):

JS
await oloClient.nav.navigateTo('kitchen-waypoint'); await oloClient.core.abortableDelay(2000); // Pause to observe // Check for anomalies const image = await oloClient.vision.captureImage('/camera/image_raw'); const analysis = await oloClient.vision.analyzeImage(image, 'Are there any items out of place or safety hazards?'); oloClient.core.setScriptResult({ location: 'kitchen', status: 'complete', analysis: analysis });

Running and Scheduling Scripts via GUI

Scripts can be run on-demand or scheduled using the Automation panel:

  1. On the Appliance Card (visible when connected), click the Automation button
  2. Browse your Script Library on the left side
  3. Click a script to see options:
    • Run Now - Execute the script immediately
    • Schedule - Configure automated execution (one-time, daily, weekly, etc.)

The Automation panel shows:

  • Running - All currently executing scripts with stop controls
  • Scheduled - All scheduled scripts with enable/disable toggles
  • Console Output - Real-time output from all running scripts

This provides a convenient way to manage robot automation without writing code.

Best Practices

  1. Keep scripts focused - Each script should do one thing well
  2. Use meaningful names - Script names should clearly describe their purpose
  3. Handle errors gracefully - Wrap critical operations in try/catch
  4. Return useful results - Use setScriptResult() to pass data back to callers
  5. Document dependencies - Note which scripts depend on other scripts
  6. Test independently - Each script should be testable on its own

API Reference

getUserScripts() / get_user_scripts()

Get list of saved scripts for the authenticated user.

Returns: Array of script objects with:

  • id - Unique script identifier
  • name - Script name
  • code - Script source code
  • description - Optional description
  • language - 'javascript' or 'python'
  • created_at - Creation timestamp
  • updated_at - Last update timestamp

Throws:

  • Error if not connected
  • Error if not authenticated
JS
const scripts = await oloClient.core.getUserScripts(); console.log('Available scripts:', scripts.map(s => s.name)); // Find and run a specific script const patrol = scripts.find(s => s.name === 'patrol-route'); if (patrol) { await oloClient.core.executeScript(patrol.name); }

executeScript(scriptName) / execute_script(script_name)

Execute a saved script by name and wait for it to complete.

Parameters:

  • scriptName (string) - Name of the saved script to execute

Returns: Object containing:

  • executionId - Unique ID of the execution
  • duration - Time in milliseconds the script took to run
  • result - (optional) Return value set by the spawned script via setScriptResult()

Throws:

  • Error if not connected
  • Error if script name is not provided
  • Error if script is not found
  • Error if script execution fails or is stopped
  • Error if script doesn't start within 15 seconds
JS
const result = await oloClient.core.executeScript('my-script'); console.log('Completed in', result.duration, 'ms'); console.log('Result:', result.result);

stopScript(executionId) / stop_script(execution_id)

Stop a running script execution.

Parameters:

  • executionId (string) - The execution ID returned from executeScript() or from tracking active executions

Returns: true if the stop message was sent successfully

JS
// Execute a script and get the execution ID const result = await oloClient.core.executeScript('long-running-script'); const executionId = result.executionId; // Later, stop it if needed await oloClient.core.stopScript(executionId);

setScriptResult(value) / set_script_result(value)

Set a return value that will be passed back to the calling script.

Parameters:

  • value - Any JSON-serializable value to return
JS
// In the spawned script: oloClient.core.setScriptResult({ success: true, data: { distance: 5.2, unit: 'meters' } });

Console Logs:

When executeScript is called, you will see:

  • [OLOClient] Spawning script: 'script-name' - When the request is sent
  • [OLOClient] Script 'script-name' started (ID: xxx) - When execution begins
  • [OLOClient] Script 'script-name' completed (ID: xxx) - When execution finishes