This article shows how to follow the state of a Yaskawa Motoman controller from a PC, in C# or Python. It gives a complete program that reads the mode, the servo, the hold, the alarm and the job every 200 ms, and prints each change.

## Prerequisites

- The SDK is connected to the controller: see [Connect to your robot](/yaskawa/documentation/connect).
- Nothing else: all these reads work in any mode.

## What to read

| Information                        | Method                              |
| ---------------------------------- | ----------------------------------- |
| Mode, servo, running, hold, alarm  | `GetStatusInformation()`            |
| Name and line of the executing job | `GetExecutingJobInformation()`      |
| Code and text of the alarm         | `GetAlarm(RobotRecentAlarm.Latest)` |
| Position of the robot              | `GetRobotCartesianPosition()`       |
| Variables written by the job       | `ReadInteger`, `ReadByte`...        |

The SDK has no event: it reads when you call it. A monitor is a loop that reads, compares with the last value, and reacts to the changes.

## Example

**C# : HowToMonitorState**
```csharp
using UnderAutomation.Yaskawa;
using UnderAutomation.Yaskawa.HighSpeedEServer;

public class HowToMonitorState
{
    static void Main()
    {
        /**/
        var robot = new YaskawaRobot();
        robot.Connect("192.168.0.1");

        string last = null;

        // Poll every 200 ms for 1 minute and print each change
        for (int i = 0; i < 300; i++)
        {
            RobotStatusData status = robot.HighSpeedEServer.GetStatusInformation();
            RobotJobData job = robot.HighSpeedEServer.GetExecutingJobInformation();

            string mode = status.Play ? "PLAY" : status.Teach ? "TEACH" : "?";
            string state = $"{mode} servo={(status.ServoOn ? "on" : "off")} running={status.Running} " +
                           $"hold={status.InHoldStatusPendant || status.InHoldStatusExternally || status.InHoldStatusByCommand} " +
                           $"alarm={status.Alarming} job={job.Name}";

            if (state != last)
            {
                Console.WriteLine($"{DateTime.Now:HH:mm:ss} {state}");

                if (status.Alarming)
                {
                    RobotAlarmData alarm = robot.HighSpeedEServer.GetAlarm(RobotRecentAlarm.Latest);
                    Console.WriteLine($"  alarm {alarm.Code}: {alarm.Text}");
                }

                last = state;
            }

            Thread.Sleep(200);
        }

        robot.Disconnect();
        /**/
    }
}
```

**Python : HowToMonitorState**
```python
import time
from datetime import datetime
from underautomation.yaskawa.yaskawa_robot import YaskawaRobot
from underautomation.yaskawa.connect_parameters import ConnectParameters
from underautomation.yaskawa.high_speed_e_server.robot_recent_alarm import RobotRecentAlarm

##
robot = YaskawaRobot()
robot.connect(ConnectParameters("192.168.0.1"))
hses = robot.high_speed_e_server

last = None

# Poll every 200 ms for 1 minute and print each change
for _ in range(300):
    status = hses.get_status_information()
    job = hses.get_executing_job_information()

    mode = "PLAY" if status.play else "TEACH" if status.teach else "?"
    hold = status.in_hold_status_pendant or status.in_hold_status_externally or status.in_hold_status_by_command
    state = (f"{mode} servo={'on' if status.servo_on else 'off'} running={status.running} "
             f"hold={hold} alarm={status.alarming} job={job.name}")

    if state != last:
        print(f"{datetime.now():%H:%M:%S} {state}")

        if status.alarming:
            alarm = hses.get_alarm(RobotRecentAlarm.Latest)
            print(f"  alarm {alarm.code}: {alarm.text}")

        last = state

    time.sleep(0.2)

robot.disconnect()
##
```

The program builds a line of text from the status and the job, and prints it only when it changes. When an alarm is active, it also prints the latest alarm.

## Polling period

Each read is one request. Two reads every 200 ms is 10 requests per second. Choose the period from what you need to see: 100 ms to 500 ms for a supervision screen, a few seconds for a log.

Run the loop in its own thread, so that the user interface stays responsive. One `YaskawaRobot` can be used by several threads: the SDK sends one request at a time.

## Troubleshooting

- **A `SocketException` from time to time:** a request did not get its answer before `DataTimeoutMilliseconds`. Catch it in the loop, count the failures, and report a lost connection after several failures in a row.
- **The job name is empty:** no job is selected.

## What to read next

- [Status and servo](/yaskawa/documentation/hses-status): all the flags of the status.
- [Read and reset alarms](/yaskawa/documentation/how-to-read-reset-alarms).