# LabJack write task

> Learn how to send commands to LabJack devices with Synnax.

This task follows the standard [task lifecycle](https://docs.synnaxlabs.com/reference/driver/task-basics#task-lifecycle).

## Task configuration reference

| Parameter    | Type   | Required | Default | Description                                   |
| ------------ | ------ | -------- | ------- | --------------------------------------------- |
| `device`     | string | Yes      | -       | Key of the LabJack device                     |
| `state_rate` | number | No       | `10`    | Rate (Hz) at which state channels are updated |
| `channels`   | array  | Yes      | -       | List of output channel configurations         |

## Channel types reference

Analog output ([`analog`](https://support.labjack.com/docs/15-0-dac-t-series-datasheet))

Writes analog voltage to a specified output terminal (DAC).

| Parameter       | Type   | Required | Default | Description                          |
| --------------- | ------ | -------- | ------- | ------------------------------------ |
| `cmd_channel`   | number | Yes      | -       | Synnax command channel key           |
| `state_channel` | number | Yes      | -       | Synnax state channel key             |
| `port`          | string | No       | `DAC0`  | Port location (e.g., `DAC0`, `DAC1`) |

Digital output ([`digital`](https://support.labjack.com/docs/13-0-digital-i-o-t-series-datasheet))

Writes digital state (0 or 1) to a specified digital I/O line.

| Parameter       | Type   | Required | Default | Description                          |
| --------------- | ------ | -------- | ------- | ------------------------------------ |
| `cmd_channel`   | number | Yes      | -       | Synnax command channel key           |
| `state_channel` | number | Yes      | -       | Synnax state channel key             |
| `port`          | string | No       | `DIO4`  | Port location (e.g., `DIO4`, `FIO5`) |

## How-to

When you create channels with a client library, give each command channel its own index channel. A writer that holds several commands on one index must write all of them in every frame.

**Console**

[](https://synnax.nyc3.cdn.digitaloceanspaces.com/docs/device-drivers/labjack/write-task/lj-write-dark.mp4#t=0.001)

**Python**

Configure and run task

```python
import synnax as sy
from synnax import labjack

client = sy.Synnax()

# Retrieve device
dev = client.devices.retrieve(name="my_labjack")

# Create command channels, each with its own index
ao_0_cmd_time = client.channels.create(
    name="ao_0_cmd_time",
    is_index=True,
    data_type=sy.DataType.TIMESTAMP,
    retrieve_if_name_exists=True,
)
ao_0_cmd = client.channels.create(
    name="ao_0_cmd",
    index=ao_0_cmd_time.key,
    data_type=sy.DataType.FLOAT32,
    retrieve_if_name_exists=True,
)
do_4_cmd_time = client.channels.create(
    name="do_4_cmd_time",
    is_index=True,
    data_type=sy.DataType.TIMESTAMP,
    retrieve_if_name_exists=True,
)
do_4_cmd = client.channels.create(
    name="do_4_cmd",
    index=do_4_cmd_time.key,
    data_type=sy.DataType.UINT8,
    retrieve_if_name_exists=True,
)

# Create state time index
state_time = client.channels.create(
    name="lj_state_time",
    is_index=True,
    data_type=sy.DataType.TIMESTAMP,
    retrieve_if_name_exists=True,
)

# Create state channels
ao_0_state = client.channels.create(
    name="ao_0_state",
    index=state_time.key,
    data_type=sy.DataType.FLOAT32,
    retrieve_if_name_exists=True,
)
do_4_state = client.channels.create(
    name="do_4_state",
    index=state_time.key,
    data_type=sy.DataType.UINT8,
    retrieve_if_name_exists=True,
)

# Create and configure task
task = labjack.WriteTask(
    name="LabJack Write Task",
    device=dev.key,
    state_rate=sy.Rate.HZ * 20,
    channels=[
        labjack.AnalogWriteChannel(
            cmd_channel=ao_0_cmd.key,
            state_channel=ao_0_state.key,
            port="DAC0",
        ),
        labjack.DigitalWriteChannel(
            cmd_channel=do_4_cmd.key,
            state_channel=do_4_state.key,
            port="DIO4",
        ),
    ],
)

client.tasks.configure(task)

# Start task and write commands
with task.run():
    with client.open_writer(
        start=sy.TimeStamp.now(),
        channels=["ao_0_cmd", "do_4_cmd"],
    ) as writer:
        # Set analog output to 2.5V and digital output high
        writer.write({
            "ao_0_cmd": 2.5,
            "do_4_cmd": 1,
        })

        # Read back states
        with client.open_streamer(["ao_0_state", "do_4_state"]) as streamer:
            frame = streamer.read()
            print(f"Analog State: {frame['ao_0_state'][-1]} V")
            print(f"Digital State: {frame['do_4_state'][-1]}")
```

Edit task configuration

```python
# Retrieve existing task
task = client.tasks.retrieve(name="LabJack Write Task")
task = labjack.WriteTask(internal=task)

# Update task-level configuration
task.config.auto_start = True
task.config.state_rate = int(sy.Rate.HZ * 50)

# Update analog output configuration
task.config.channels[0].port = "DAC1"

# Update digital output configuration
task.config.channels[1].port = "DIO5"

# Apply changes
client.tasks.configure(task)
```

**TypeScript**

Configure and run task

```typescript
import { Synnax, TimeStamp, Rate } from "@synnaxlabs/client";

const client = new Synnax();

// Retrieve device
const [dev] = await client.devices.retrieve({ names: ["my_labjack"] });

// Create command channels, each with its own index
const ao0CmdTime = await client.channels.create(
  {
    name: "ao_0_cmd_time",
    isIndex: true,
    dataType: "timestamp",
  },
  { retrieveIfNameExists: true },
);
const ao0Cmd = await client.channels.create(
  {
    name: "ao_0_cmd",
    index: ao0CmdTime.key,
    dataType: "float32",
  },
  { retrieveIfNameExists: true },
);

const do4CmdTime = await client.channels.create(
  {
    name: "do_4_cmd_time",
    isIndex: true,
    dataType: "timestamp",
  },
  { retrieveIfNameExists: true },
);
const do4Cmd = await client.channels.create(
  {
    name: "do_4_cmd",
    index: do4CmdTime.key,
    dataType: "uint8",
  },
  { retrieveIfNameExists: true },
);

// Create state time index
const stateTime = await client.channels.create(
  {
    name: "lj_state_time",
    isIndex: true,
    dataType: "timestamp",
  },
  { retrieveIfNameExists: true },
);

// Create state channels
const ao0State = await client.channels.create(
  {
    name: "ao_0_state",
    index: stateTime.key,
    dataType: "float32",
  },
  { retrieveIfNameExists: true },
);

const do4State = await client.channels.create(
  {
    name: "do_4_state",
    index: stateTime.key,
    dataType: "uint8",
  },
  { retrieveIfNameExists: true },
);

// Create and configure task
const task = await client.tasks.create({
  name: "LabJack Write Task",
  rack: dev.rack,
  type: "labjack_write",
  config: {
    device: dev.key,
    stateRate: 20,
    channels: [
      {
        type: "analog",
        cmdChannel: ao0Cmd.key,
        stateChannel: ao0State.key,
        port: "DAC0",
      },
      {
        type: "digital",
        cmdChannel: do4Cmd.key,
        stateChannel: do4State.key,
        port: "DIO4",
      },
    ],
  },
});

// Start task
await task.start();

// Write commands
const writer = await client.openWriter({
  start: TimeStamp.now(),
  channels: ["ao_0_cmd", "do_4_cmd"],
});

// Set analog output to 2.5V and digital output high
await writer.write({
  ao_0_cmd: 2.5,
  do_4_cmd: 1,
});

// Read states
const streamer = await client.openStreamer(["ao_0_state", "do_4_state"]);
const frame = await streamer.read();
const aoState = frame.get("ao_0_state").at(-1);
const doState = frame.get("do_4_state").at(-1);
console.log(`Analog State: ${aoState} V`);
console.log(`Digital State: ${doState}`);

// Stop task
await task.stop();
await writer.close();
await streamer.close();
```

Edit task configuration

```typescript
import { labjack } from "@synnaxlabs/client";

// Retrieve existing task
const task = await client.tasks.retrieve({ name: "LabJack Write Task" });

// Parse and update configuration
const config = labjack.writeConfigZ.parse(task.config);

// Update task-level configuration
config.autoStart = true;
config.stateRate = 50;

// Update analog output configuration
const analog = config.channels[0] as labjack.AnalogWriteChannel;
analog.port = "DAC1";

// Update digital output configuration
const digital = config.channels[1] as labjack.DigitalWriteChannel;
digital.port = "DIO5";

// Apply changes
await client.tasks.create({
  key: task.key,
  rack: task.rack,
  name: task.name,
  type: task.type,
  config,
});
```
