Modbus Write Task
Learn how to send commands to Modbus TCP devices with Synnax.
For the task lifecycle, see Task Basics.
Task Configuration Reference
Register Types Reference
Holding Register Output (holding_register)
holding_register)Writes to 16-bit read/write registers (Function Code 06/16). Typically used for setpoints, control values, and configuration parameters.
Data Type Sizes:
int8/uint8/int16/uint16: 1 register (2 bytes)int32/uint32/float32: 2 registers (4 bytes)int64/uint64/float64: 4 registers (8 bytes)
Coil Output (coil)
coil)Writes to 1-bit read/write coils (Function Code 05/15). Typically used for binary control signals like relay states and valve positions.
Data Type: Always boolean (0/1)
Important Rules
- Byte/word order -> Ensure swap settings match your server configuration for multi-register data types.
- Read-only registers -> Input Registers and Discrete Inputs cannot be written to.
How-To
Console
Python
TypeScript
Configure and run task
import synnax as sy
from synnax import modbus
client = sy.Synnax()
# Retrieve device
dev = client.devices.retrieve(name="Modbus Server")
# Create command time index
modbus_cmd_time = client.channels.create(
name="modbus_cmd_time",
is_index=True,
data_type=sy.DataType.TIMESTAMP,
retrieve_if_name_exists=True,
)
# Create command channel for coil
coil_cmd = client.channels.create(
name="coil_cmd",
index=modbus_cmd_time.key,
data_type=sy.DataType.UINT8,
retrieve_if_name_exists=True,
)
# Create command channel for holding register
holding_reg_cmd = client.channels.create(
name="holding_reg_cmd",
index=modbus_cmd_time.key,
data_type=sy.DataType.UINT8,
retrieve_if_name_exists=True,
)
# Create and configure task
task = modbus.WriteTask(
name="Modbus Write Task",
device=dev.key,
channels=[
modbus.CoilWriteChannel(
channel=coil_cmd.key,
address=0,
),
modbus.HoldingRegisterWriteChannel(
channel=holding_reg_cmd.key,
address=2,
data_type="uint8",
),
],
)
client.tasks.configure(task)
# Start task and send commands
with task.run():
with client.open_writer(
start=sy.TimeStamp.now(),
channels=["coil_cmd", "holding_reg_cmd"],
) as writer:
# Write commands
writer.write({
"coil_cmd": 1,
"holding_reg_cmd": 100,
}) Edit task configuration
# Retrieve existing task
task = client.tasks.retrieve(name="Modbus Write Task")
task = modbus.WriteTask(internal=task)
# Update task-level configuration
task.config.auto_start = True
# Update coil configuration
task.config.channels[0].address = 10
# Update holding register configuration
task.config.channels[1].address = 20
task.config.channels[1].data_type = "uint16"
# Apply changes
client.tasks.configure(task) Configure and run task
import { Synnax, TimeStamp } from "@synnaxlabs/client";
const client = new Synnax();
// Retrieve device
const [dev] = await client.devices.retrieve({ names: ["Modbus Server"] });
// Create command time index
const modbusCmdTime = await client.channels.create(
{
name: "modbus_cmd_time",
isIndex: true,
dataType: "timestamp",
},
{ retrieveIfNameExists: true },
);
// Create command channel for coil
const coilCmd = await client.channels.create(
{
name: "coil_cmd",
index: modbusCmdTime.key,
dataType: "uint8",
},
{ retrieveIfNameExists: true },
);
// Create command channel for holding register
const holdingRegCmd = await client.channels.create(
{
name: "holding_reg_cmd",
index: modbusCmdTime.key,
dataType: "uint8",
},
{ retrieveIfNameExists: true },
);
// Create and configure task
const task = await client.tasks.create({
name: "Modbus Write Task",
rack: dev.rack,
type: "modbus_write",
config: {
device: dev.key,
channels: [
{
type: "coil",
channel: coilCmd.key,
address: 0,
},
{
type: "holding_register",
channel: holdingRegCmd.key,
address: 2,
dataType: "uint8",
},
],
},
});
// Start task
await task.start();
// Send commands
const writer = await client.openWriter({
start: TimeStamp.now(),
channels: ["coil_cmd", "holding_reg_cmd"],
});
await writer.write({
coil_cmd: 1,
holding_reg_cmd: 100,
});
// Stop task
await task.stop();
await writer.close(); Edit task configuration
import { modbus } from "@synnaxlabs/client";
// Retrieve existing task
const task = await client.tasks.retrieve({ name: "Modbus Write Task" });
// Parse and update configuration
const config = modbus.writeConfigZ.parse(task.config);
// Update task-level configuration
config.autoStart = true;
// Update coil configuration
const coil = config.channels[0] as modbus.CoilWriteChannel;
coil.address = 10;
// Update holding register configuration
const holdingRegister = config.channels[1] as modbus.HoldingRegisterWriteChannel;
holdingRegister.address = 20;
holdingRegister.dataType = "uint16";
// Apply changes
await client.tasks.create({
key: task.key,
rack: task.rack,
name: task.name,
type: task.type,
config,
});