# Run programs

> Once you've declared and tested your robot programs, you can provide them to operators. The Program Operator (Beta) application runs and monitors robot programs safely, without code editing.

Use the Program Operator to deploy robot programs for operators. It provides:

- No-code operation: Start, stop, and configure programs without programming
- Hardware validation: Validates correct robot hardware is connected before execution
- Parameter configuration: Adjust program behavior through form interface

## Features

> **Info:** The Program Operator is in beta and carries a beta badge in the app store.
> The underlying programs API is experimental and may change.

The Program Operator offers the following features:

1. Start and stop programs
2. Configure parameters
3. Monitoring including cycle time tracking and countdown timers
4. View logs and history
5. Hardware validation before execution

Video: [/video/programming/program\_operator\_overview.webm](/video/programming/program_operator_overview.webm)

## Usage

### Step 1: Installation

Install the Program Operator via the Wandelbots NOVA [app store](/nova/latest/architecture#app-store).

### Step 2: Register a program

To make a Python program available in the Program Operator, you need to register it using [Novax](https://github.com/wandelbotsgmbh/wandelbots-nova?tab=readme-ov-file#novax).

`Novax` handles the lifecycle of programs, exposing them through the NOVA API and making them available to the Program Operator.

![Program Operator main view](/assets/nova/programming/program_operator_overview.webp)

1. Open Visual Studio Code from the NOVA home screen.
2. Create or open a Python file containing your robot program decorated with `@nova.program`,
   e.g., `start_here.py`.
3. Open the registration script named `register_programs.py`.
4. Import your program module and pass your FastAPI app to `Novax`.\
   → Every imported `@nova.program` registers automatically.
5. Run the registration script to make your program discoverable.

```python
from fastapi import FastAPI
from novax import Novax

# Importing the module registers its @nova.program functions
import your_nova_app.start_here  # noqa: F401

# Create FastAPI app
app = FastAPI(
    title="your_nova_app",
    version="0.1.0",
    description="An app that serves your robot programs",
)

# Include the programs API endpoints and register
# every imported @nova.program
novax = Novax(app)

# Run the app, e.g., with uvicorn
```

Novax also scans a `programs` directory by default. Drop a `.py` file with a
`@nova.program` into it and the program is picked up without a manual import.

→ If the registration is successful, the VS Code terminal indicates that the program was successfully registered.

### Step 3: Execute a program

1. Select the desired program from the list.
2. Click `Start` to begin execution.\\
   > **Info:** During the first run, the Program Operator will measure the cycle time. Monitor the execution progress and countdown timer.
3. Click `Stop` to pause the program.

![Program Operator execution view](/assets/nova/programming/program_operator_execution.webp)

## Program availability

Programs registered through Visual Studio Code can deregister when you close VS Code or
restart the Wandelbots NOVA instance.
To guarantee their availability in the Program Operator, deploy your programs as a persistent app.
Learn how in [deploy an app](/developer/custom-apps/deploy-app).

## Cycle definition and metrics

Cycles are not automatically determined by the Program Operator.
Explicitly define cycle boundaries in your program code using `novax_cycle`.

To enable cycle time tracking, you must instrument your program to define what constitutes a `cycle`.
A cycle typically represents one complete iteration of your robot workflow, e.g.,
picking and placing one workpiece.

### Step 1: Define a cycle

To make a Python program available in the Program Operator, you need to register it using [Novax](https://github.com/wandelbotsgmbh/wandelbots-nova?tab=readme-ov-file#novax).

`Novax` handles the lifecycle of programs, exposing them through the NOVA API and making them available to the Program Operator.

The `novax_cycle` function requires:

- `cell`: The NOVA cell instance from `nova.cell()`
- `app`: The name of the app that registered the program
- `program`: The program ID (must match the `id` in your `@nova.program` decorator)

```python
from nova.events import novax_cycle

@nova.program(
    id="example_program",
    name="Example Robot Program",
    # ... other configuration
)
async def start():
    async with Nova() as nova:
        cell = nova.cell()
        controller = await cell.controller("robot-name")

        # Define the cycle - this tells Program Operator what to measure
        cycle = novax_cycle(cell=cell, app="your_nova_app", program="example_program")

        async with controller[0] as motion_group:
            # Your robot setup code here

            # Mark the start of the cycle
            await cycle.start()

            # Your robot movements that constitute one cycle
            await motion_group.plan_and_execute(actions, tcp)

            # Mark the end of the cycle
            await cycle.finish()
```

### Step 2: Cycle time measurement

Once a cycle is defined, a Program Operator measures time between `cycle.start()` and `cycle.finish()` for each execution.
The baseline is updated with the latest measurement to provide:

- Countdown timers: Showing the expected completion time based on the most recent cycle
- Performance monitoring: To detect deviations from the current baseline
- Production metrics: For tracking efficiency

### Using configurable function parameters

1. Navigate to the `Parameters` tab in the Program Operator.
2. Enter the desired values for each parameter.
3. Start the program.\
   → The custom configuration will be applied.
   → If parameters affect the execution speed, the cycle time will be re-measured.

> **Note:** If the `Parameters` tab does not appear, ensure your program function includes configurable parameters.
> Refer to the [writing programs guide](/developer/declare-program#configurable-function-parameters) for details on defining parameters.

## Next steps

Refine your program with advanced configuration options in the [declare a program documentation](/developer/declare-program).

## Troubleshooting

### `Robot disconnected` → Configure the required robot

The Program Operator performs a check to ensure the robot required by your program
is configured in the cell before allowing program execution.

If you see a `Robot disconnected` error after registration:

1. Open the **Setup** application from the NOVA home screen.
2. Add the robot required by your program to the cell.
3. Ensure the robot **name** and **model** match exactly what the program expects.
4. For virtual robots, select "Virtual" as the robot type, then choose the correct manufacturer and model.

Once the robot is configured and shows `connected` in Setup, return to the Program Operator.
The program status will show `ready` and is ready for execution.

### Cell errors when using the Program Operator

Use the `Restart cell` button to stop and restart all NOVA robot services.

If you loose connection to the Wandelbots NOVA instance during the restart, the cell might not restart automatically.
In this case, use [Cell > Operating State](https://portal.wandelbots.io/docs/api/v2/ui/#/operations/setCellStatus) to restart the cell manually.
The restart can take up to a couple of minutes.
