Start, stop, pause, and abort TP programs remotely using different protocols.

## Telnet KCL

Telnet provides the most complete program control through KCL commands:

**C# : TelnetProgramControl**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Telnet;

public class TelnetProgramControl
{
  static void Main()
  {
    FanucRobot robot = new FanucRobot();
    ConnectionParameters parameters = new ConnectionParameters("192.168.0.1");
    parameters.Telnet.Enable = true;
    parameters.Telnet.TelnetKclPassword = "TELNET_PASS";
    robot.Connect(parameters);

    /**/
    // Run a program
    robot.Telnet.Run("MyProgram");

    // Pause (stops at next fine point)
    robot.Telnet.Pause("MyProgram");

    // Hold (decelerates and stops at current position)
    robot.Telnet.Hold("MyProgram");

    // Resume a paused or held program
    robot.Telnet.Continue("MyProgram");

    // Abort a program
    robot.Telnet.Abort("MyProgram", force: true);

    // Abort all running programs
    robot.Telnet.AbortAll(force: true);

    // Reset alarms (same as FAULT RESET button)
    robot.Telnet.Reset();

    // Clear program variables
    robot.Telnet.ClearVars("MyProgram");
    /**/
  }
}
```

**Python : TelnetProgramControl**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot
from underautomation.fanuc.connection_parameters import ConnectionParameters

robot = FanucRobot()
parameters = ConnectionParameters("192.168.0.1")
parameters.telnet.enable = True
parameters.telnet.telnet_kcl_password = "TELNET_PASS"
robot.connect(parameters)

##
# Run a program
robot.telnet.run("MyProgram")

# Pause (stops at next fine point)
robot.telnet.pause("MyProgram")

# Hold (decelerates and stops at current position)
robot.telnet.hold("MyProgram")

# Resume a paused or held program
robot.telnet.continue_("MyProgram")

# Abort a program
robot.telnet.abort("MyProgram", force=True)

# Abort all running programs
robot.telnet.abort_all(force=True)

# Reset alarms (same as FAULT RESET button)
robot.telnet.reset()

# Clear program variables
robot.telnet.clear_vars("MyProgram")
##
```

See also: [Telnet Program control](/fanuc/documentation/telnet-program-control)

## CGTP Web Server

CGTP can run, select, pause, and abort programs, plus manage program properties:

**C# : CgtpPrograms**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Cgtp;

public class CgtpPrograms
{
  public static void Main()
  {
    FanucRobot robot = new FanucRobot();

    ConnectionParameters parameters = new ConnectionParameters("192.168.0.1");
    parameters.Cgtp.Enable = true;

    robot.Connect(parameters);

    /**/
    // Run a program
    robot.Cgtp.RunProgram("MY_PROGRAM");

    // Run from a specific line
    robot.Cgtp.RunProgram("MY_PROGRAM", lineNum: 10);

    // Select a program
    robot.Cgtp.SelectProgram("MY_PROGRAM");

    // Abort a task
    robot.Cgtp.AbortTask("MY_PROGRAM");

    // Pause all programs
    robot.Cgtp.PauseAllPrograms();

    // Create a program
    robot.Cgtp.CreateProgram(
        progName: "NEW_PROG",
        owner: "UnderAutomation",
        comment: "Created via CGTP",
        subType: CgtpProgramSubType.Job
    );

    // Delete a program
    robot.Cgtp.DeleteProgram("OLD_PROG");

    // Rename a program
    robot.Cgtp.RenameProgram("OLD_NAME", "NEW_NAME");

    // List all TP programs
    string[] programs = robot.Cgtp.ListTpPrograms();

    // Edit source code (firmware V9.10+)
    robot.Cgtp.InsertSourceLine("MY_PROGRAM", "L P[5] 100mm/sec FINE", 3);
    robot.Cgtp.ReplaceSourceLine("MY_PROGRAM", "J P[1] 50% FINE", 5);
    robot.Cgtp.DeleteSourceLines("MY_PROGRAM", 4, 2);

    // Read program properties
    string comment = robot.Cgtp.GetProgramComment("MY_PROGRAM");
    string owner = robot.Cgtp.GetProgramOwner("MY_PROGRAM");
    bool ignorePause = robot.Cgtp.GetProgramIgnorePause("MY_PROGRAM");

    // Write program properties
    robot.Cgtp.SetProgramComment("MY_PROGRAM", "Updated comment");
    robot.Cgtp.SetProgramSubType("MY_PROGRAM", CgtpProgramSubType.Macro);
    /**/
  }
}
```

**Python : CgtpPrograms**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot
from underautomation.fanuc.connection_parameters import ConnectionParameters
from underautomation.fanuc.cgtp.cgtp_program_sub_type import CgtpProgramSubType

# Create a robot instance
robot = FanucRobot()

# Configure connection parameters
parameters = ConnectionParameters("192.168.0.1")
parameters.cgtp.enable = True

# Connect to the robot
robot.connect(parameters)

##
# Run a program
robot.cgtp.run_program("MY_PROGRAM")

# Run from a specific line
robot.cgtp.run_program("MY_PROGRAM", line_num=10)

# Select a program
robot.cgtp.select_program("MY_PROGRAM")

# Abort a task
robot.cgtp.abort_task("MY_PROGRAM")

# Pause all programs
robot.cgtp.pause_all_programs()

# Create a program
robot.cgtp.create_program(
    prog_name="NEW_PROG",
    owner="UnderAutomation",
    comment="Created via CGTP",
    sub_type=CgtpProgramSubType.JOB
)

# Delete a program
robot.cgtp.delete_program("OLD_PROG")

# Rename a program
robot.cgtp.rename_program("OLD_NAME", "NEW_NAME")

# List all TP programs
programs = robot.cgtp.list_tp_programs()

# Edit source code (firmware V9.10+)
robot.cgtp.insert_source_line("MY_PROGRAM", "L P[5] 100mm/sec FINE", 3)
robot.cgtp.replace_source_line("MY_PROGRAM", "J P[1] 50% FINE", 5)
robot.cgtp.delete_source_lines("MY_PROGRAM", 4, 2)

# Read program properties
comment = robot.cgtp.get_program_comment("MY_PROGRAM")
owner = robot.cgtp.get_program_owner("MY_PROGRAM")
ignore_pause = robot.cgtp.get_program_ignore_pause("MY_PROGRAM")

# Write program properties
robot.cgtp.set_program_comment("MY_PROGRAM", "Updated comment")
robot.cgtp.set_program_sub_type("MY_PROGRAM", CgtpProgramSubType.MACRO)
##
```

See also: [CGTP Program management](/fanuc/documentation/cgtp-programs)

## RMI

RMI sends TP-equivalent motion instructions directly, without selecting a program:

**C# : RunProgramRemotelyRmi**
```csharp
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Rmi.Data;

public class RunProgramRemotelyRmi
{
    static void Main()
    {
        FanucRobot robot = new FanucRobot();
        robot.Connect("192.168.0.1");

        /**/
        // Initialize the RMI_MOVE program
        robot.Rmi.Initialize();

        // Send motion commands with sequence IDs
        Frame target = new Frame { X = 500, Y = 200, Z = 300, W = 0, P = 90, R = 0 };
        MotionConfiguration config = new MotionConfiguration { UToolNumber = 1, UFrameNumber = 0 };
        robot.Rmi.LinearMotion(sequenceId: 1, config: config, position: target,
            speedType: SpeedType.MmSec, speed: 100, termType: TerminationType.Fine, termValue: 0,
            acc: null, offsetPr: null, visionPr: null, wristJoint: false, mrot: false,
            lcbType: null, lcbValue: null, portType: null, portNumber: null, portValue: null);

        // Pause / Continue / Abort
        robot.Rmi.Pause();
        robot.Rmi.Continue();
        robot.Rmi.Abort();
        /**/
    }
}
```

**Python : RunProgramRemotelyRmi**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot

robot = FanucRobot()
robot.connect("192.168.0.1")

##
# Initialize the RMI_MOVE program
robot.rmi.initialize()

# Send motion commands with sequence IDs
robot.rmi.linear_motion(
    sequence_id=1,
    utool_number=1, uframe_number=0,
    x=500, y=200, z=300, w=0, p=90, r=0,
    speed_type="MmSec", speed=100,
    term_type="Fine", term_value=0
)

# Pause / Continue / Abort
robot.rmi.pause()
robot.rmi.continue_motion()
robot.rmi.abort()
##
```

See also: [RMI overview](/fanuc/documentation/rmi)

## SNPX (indirect)


### Selecting the Target Program

Set the program name using the `$SHELL_WRK.$CUST_NAME` system variable. **Do not include the `.TP` extension**:


### Starting the Program

#### Enable Remote Control

To allow external control, the system variable `$RMT_MASTER` must be set to `0`.

### Option 1: System Variable Start (Production Start Method = OTHER)

When **Production Start Method** is set to **OTHER**, trigger the start by setting `$SHELL_WRK.$CUST_START` to `1`:

The controller automatically clears this bit once it acknowledges the command.

### Option 2: UOP Cycle Start (Production Start Method = UOP)

This method uses UI (User Input) signals, providing additional control capabilities.

#### Step 1: Configure UI-to-Flag Mapping

Navigate to: **MENU → I/O → UOP → select UI → CONFIG**

Link UI signals to Flags (Rack 34, Slot 1):

| Configuration | Result |
|---------------|--------|
| UI[1-8] → Rack 34, Slot 1, Start 1 | UI[1]=F[1], UI[2]=F[2], ... UI[8]=F[8] |
| UI[1-8] → Rack 34, Slot 1, Start 4 | UI[1]=F[4], UI[2]=F[5], ... UI[8]=F[11] |
| UI[6-6] → Rack 34, Slot 1, Start 9 | UI[6]=F[9] |

> The mapping is **bidirectional**: read UI state from flags, or write to flags to change UI state.

**Cold start** the controller after configuration.

#### Step 2: Pulse the Cycle Start Flag

To start the program, pulse the corresponding flag to UI[6:Cycle Start]

## Controlling Program Execution via UOP

The UOP interface provides comprehensive control through UI signals:

| UI Signal | Name | Function | Code Example |
|-----------|------|----------|--------------|
| UI[2] | Hold | Pause program execution | `robot.Snpx.Flags.Write(2, false);` |
| UI[4] | Cycle Stop | Stop the current cycle | `robot.Snpx.Flags.Write(4, false);` |
| UI[5] | Fault Reset | Clear active alarms | `robot.Snpx.Flags.Write(5, true);` |
| UI[6] | Cycle Start | Start/resume program | `robot.Snpx.Flags.Write(6, true);` |
| UI[18] | Prod Start | Alternative production start | `robot.Snpx.Flags.Write(18, true);` |

> **Note:** You can also configure **RSR**, **PNS**, or **STYLE** as the Production Start Method and use UI[9-16] bound to flags to start associated programs. Refer to FANUC manuals for specific bit patterns.


**C# : RunProgramRemotelySnpx**
```csharp
using UnderAutomation.Fanuc;

public class RunProgramRemotelySnpx
{
    static void Main()
    {
        FanucRobot robot = new FanucRobot();
        robot.Connect("192.168.0.1");

        /**/
        // Clear any existing alarms
        robot.Snpx.ClearAlarms();

        // Enable remote control
        robot.Snpx.IntegerSystemVariables.Write("$RMT_MASTER", 1);

        // Select the program to run
        string programName = "MY_PROGRAM";
        robot.Snpx.StringSystemVariables.Write("$SHELL_WRK.$CUST_NAME", programName);
        Console.WriteLine($"Selected program: {programName}");

        // Start the program (using system variable method)
        Console.WriteLine("Starting program...");
        robot.Snpx.IntegerSystemVariables.Write("$SHELL_WRK.$CUST_START", 1); // or you can set the flag for UOP cycle start if that's your configured method
        /**/
    }
}
```

**Python : RunProgramRemotelySnpx**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot

robot = FanucRobot()
robot.connect("192.168.0.1")

##
# Clear any existing alarms
robot.snpx.clear_alarms()

# Enable remote control
robot.snpx.integer_system_variables.write("$RMT_MASTER", 1)

# Select the program to run
programName = "MY_PROGRAM"
robot.snpx.string_system_variables.write("$SHELL_WRK.$CUST_NAME", programName)
print(f"Selected program: {programName}")

# Start the program (using system variable method)
print("Starting program...")
robot.snpx.integer_system_variables.write("$SHELL_WRK.$CUST_START", 1) # or you can set the flag for UOP cycle start if that's your configured method
##
```

## Protocol comparison

| Feature | Telnet | CGTP | RMI | SNPX |
|---------|--------|------|-----|------|
| **Run program** | Yes | Yes (V9.30+) | Via motion commands | Indirect (variables) |
| **Pause** | Yes (Hold) | Yes | Yes | No |
| **Continue** | Yes | No | Yes | No |
| **Abort** | Yes | Yes | Yes | No |
| **Select/Deselect** | Yes | Yes | N/A | No |
| **Create/Delete** | No | Yes | No | No |