Read and write system variables, set output ports, simulate and unsimulate input ports using Telnet KCL.

## Read and write variables

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

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

        /**/
        // Read a variable
        GetVariableResult result = robot.Telnet.GetVariable("$RMT_MASTER");
        string value = result.RawValue;

        // Write a variable
        robot.Telnet.SetVariable("$RMT_MASTER", 1);
        robot.Telnet.SetVariable("$MCR.$GENOVERRIDE", 50);
        robot.Telnet.SetVariable("$[MY_PROG]my_var", "hello");

        // Get current pose
        GetCurrentPoseResult pose = robot.Telnet.GetCurrentPose();
        /**/
    }
}
```

**Python : TelnetVariablesIoRead**
```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)

##
# Read a variable
result = robot.telnet.get_variable("$RMT_MASTER")
value = result.value

# Write a variable
robot.telnet.set_variable("$RMT_MASTER", 1)
robot.telnet.set_variable("$MCR.$GENOVERRIDE", 50)
robot.telnet.set_variable("$[MY_PROG]my_var", "hello")

# Get current pose
pose = robot.telnet.get_current_pose()
##
```

You can read any system variable, program variable, or user-defined variable by name. The value must match the declared data type. Use brackets (`[]`) after the variable name to specify an array element.

## Set and simulate I/O ports

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

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

        /**/
        // Set an output port (DOUT port 2 = OFF)
        robot.Telnet.SetPort(KCLPorts.DOUT, 2, 0);

        // Set an output port (DOUT port 5 = ON)
        robot.Telnet.SetPort(KCLPorts.DOUT, 5, 1);

        // Simulate an input port (DIN port 3 = ON)
        robot.Telnet.Simulate(KCLPorts.DIN, 3, 1);

        // Stop simulating DIN port 3
        robot.Telnet.Unsimulate(KCLPorts.DIN, 3);

        // Stop simulating all ports
        robot.Telnet.UnsimulateAll();
        /**/
    }
}
```

**Python : TelnetVariablesIoPorts**
```python
from underautomation.fanuc.fanuc_robot import FanucRobot
from underautomation.fanuc.connection_parameters import ConnectionParameters
from underautomation.fanuc.telnet.kcl_ports import KCLPorts

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

##
# Set an output port (DOUT port 2 = OFF)
robot.telnet.set_port(KCLPorts.DOUT, 2, 0)

# Set an output port (DOUT port 5 = ON)
robot.telnet.set_port(KCLPorts.DOUT, 5, 1)

# Simulate an input port (DIN port 3 = ON)
robot.telnet.simulate(KCLPorts.DIN, 3, 1)

# Stop simulating DIN port 3
robot.telnet.unsimulate(KCLPorts.DIN, 3)

# Stop simulating all ports
robot.telnet.unsimulate_all()
##
```

## Available port types

The `KCLPorts` enum defines the available port types:

| Port | Description |
|------|-------------|
| `DIN` / `DOUT` | Digital Input / Output |
| `GIN` / `GOUT` | Group Input / Output |
| `AIN` / `AOUT` | Analog Input / Output |
| `OPIN` / `OPOUT` | Operator Panel Input / Output |
| `RDI` / `RDO` | Robot Digital Input / Output |
| `WDI` / `WDO` | Weld Digital Input / Output |
| `PLCIN` / `PLCOUT` | PLC Input / Output |
| `FLAG` | Flag register |

## Complete example

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

public class TelnetVariablesIo
{
  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);

    /**/
    // Read a system variable
    GetVariableResult result = robot.Telnet.GetVariable("$RMT_MASTER");
    string value = result.RawValue;

    // Write system variables
    robot.Telnet.SetVariable("$RMT_MASTER", 1);
    robot.Telnet.SetVariable("$MCR.$GENOVERRIDE", 50);

    // Get current TCP pose
    GetCurrentPoseResult pose = robot.Telnet.GetCurrentPose();

    // Set an output port
    robot.Telnet.SetPort(KCLPorts.DOUT, 2, 0);
    robot.Telnet.SetPort(KCLPorts.DOUT, 5, 1);

    // Simulate an input port
    robot.Telnet.Simulate(KCLPorts.DIN, 3, 1);

    // Stop simulating a port
    robot.Telnet.Unsimulate(KCLPorts.DIN, 3);

    // Stop simulating all ports
    robot.Telnet.UnsimulateAll();
    /**/
  }
}
```

**Python : TelnetVariablesIo**
```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)

##
# Read a system variable
result = robot.telnet.get_variable("$RMT_MASTER")
value = result.value

# Write system variables
robot.telnet.set_variable("$RMT_MASTER", 1)
robot.telnet.set_variable("$MCR.$GENOVERRIDE", 50)

# Get current TCP pose
pose = robot.telnet.get_current_pose()

# Set an output port
robot.telnet.set_port("DOUT", 2, 0)
robot.telnet.set_port("DOUT", 5, 1)

# Simulate an input port
robot.telnet.simulate("DIN", 3, 1)

# Stop simulating a port
robot.telnet.unsimulate("DIN", 3)

# Stop simulating all ports
robot.telnet.unsimulate_all()
##
```

## API reference

**Members of Common.Kcl.GetVariableResult**
```csharp
public class GetVariableResult : Result {
    public GetVariableResult()

    // Indicates that responses have been completed and received
    protected override void EndReceive()

    // During implementation, return true if it is assumed that the frame has finished being received.
    protected override bool FromResult(string data)

    // Returns a structured object which represents the variable (not supported with Telnet)
    public GenericVariable ParseResult()

    // Gets the raw value of the variable as a string.
    public string RawValue { get; }

    // Controls whether the result should be finalized when an empty answer is received (i.e. a frame consisting only of VT100 escape sequences and whitespace).
    // Override and return false until meaningful data has been accumulated, to prevent premature finalization caused by intermediate display-update frames.
    // Default is true (backward compatible: finalize immediately on empty answer).
    protected override bool ShouldCompleteOnEmptyAnswer()

    public override string ToString()
}
```

**Members of Common.Kcl.SetVariableResult**
```csharp
public class SetVariableResult : SetValueResult {
    public SetVariableResult()

    // During implementation, return true if it is assumed that the frame has finished being received.
    protected override bool FromResult(string data)

    // Controls whether the result should be finalized when an empty answer is received (i.e. a frame consisting only of VT100 escape sequences and whitespace).
    // Override and return false until meaningful data has been accumulated, to prevent premature finalization caused by intermediate display-update frames.
    // Default is true (backward compatible: finalize immediately on empty answer).
    protected override bool ShouldCompleteOnEmptyAnswer()
}
```

**Members of Common.Kcl.SetPortResult**
```csharp
public class SetPortResult : SetValueResult {
    public SetPortResult()

    // During implementation, return true if it is assumed that the frame has finished being received.
    protected override bool FromResult(string data)
}
```

**Members of Common.Kcl.SimulateResult**
```csharp
public class SimulateResult : BaseResult {
    public SimulateResult()
}
```

**Members of Common.Kcl.KCLPorts**
```csharp
public enum KCLPorts {
    // Analog Input port.
    AIN = 7

    // Analog Output port.
    AOUT = 8

    // Digital Input port.
    DIN = 0

    // Digital Output port.
    DOUT = 1

    // General Input port.
    GIN = 9

    // General Output port.
    GOUT = 10

    // Operator Panel Output port.
    OPOUT = 3

    // Robot Digital Output port.
    RDO = 2

    // Teach Pendant Output port.
    TPOUT = 4

    // Weld Digital Input port.
    WDI = 5

    // Weld Digital Output port.
    WDO = 6
}
```