跳到主要内容

SDK 集成概述

Darra SDK 是用于与 Darra PLC 运行时通信的编程接口集合,支持多种编程语言,适用于上位机监控、数据采集、MES/ERP 集成等场景。

SDK 概述

Darra SDK 基于 DarraLink 协议(TCP 端口 18821)与 PLC 运行时通信,提供变量读写、DB 块访问、报警订阅、趋势数据查询等功能。

支持的编程语言

语言包管理器包名平台
C#NuGetDarra.PLC.SDKWindows, Linux
C++CMake / vcpkgdarra-plc-sdkWindows, Linux
Pythonpipdarra-plcWindows, Linux
JavaMavencom.darra:plc-sdk跨平台 (JVM)
Rustcargodarra-plcWindows, Linux

核心能力

  • 变量读写: 读取/写入 PLC 变量(支持所有 IEC 数据类型)
  • DB 块访问: 读写全局 DB 块数据
  • 订阅通知: 订阅变量变化,实时推送
  • 报警管理: 读取报警列表、确认报警
  • 趋势数据: 查询历史趋势数据
  • 系统监控: 获取 PLC 状态、诊断信息

安装 SDK

C# (NuGet)

# Package Manager
Install-Package Darra.PLC.SDK

# .NET CLI
dotnet add package Darra.PLC.SDK

Python (pip)

pip install darra-plc

Rust (cargo)

cargo add darra-plc

Java (Maven)

<dependency>
<groupId>com.darra</groupId>
<artifactId>plc-sdk</artifactId>
<version>1.0.0</version>
</dependency>

快速开始 (C#)

建立连接

using Darra.PLC.SDK;

// 创建 PLC 连接
var connection = new PlcConnection("192.168.1.100", 18821);

// 连接到 PLC 运行时
await connection.ConnectAsync();

Console.WriteLine("已连接到 PLC 运行时");

读取变量

// 读取 BOOL 类型
bool isRunning = await connection.ReadBoolAsync("DB_Status.bMotorRunning");

// 读取 REAL 类型
float temperature = await connection.ReadFloatAsync("DB_ProcessParam.rActTemp");

// 读取 INT 类型
short count = await connection.ReadIntAsync("DB_ProcessParam.iPartCount");

// 读取字符串
string recipeName = await connection.ReadStringAsync("DB_ProcessParam.sRecipeName");

Console.WriteLine($"温度: {temperature}°C, 计数: {count}");

写入变量

// 写入 BOOL
await connection.WriteBoolAsync("DB_Control.bStartMotor", true);

// 写入 REAL
await connection.WriteFloatAsync("DB_ProcessParam.rSetTemp", 150.0f);

// 写入 INT
await connection.WriteIntAsync("DB_ProcessParam.iErrorCode", 0);

Console.WriteLine("变量写入成功");

订阅变量变化

// 订阅变量变化通知
connection.Subscribe("DB_ProcessParam.rActTemp", (name, value) =>
{
Console.WriteLine($"温度已更新: {value}°C");
});

connection.Subscribe("DB_Alarm.bActiveAlarm", (name, value) =>
{
if ((bool)value)
{
Console.WriteLine("报警已触发!");
}
});

// 订阅保持活跃
await Task.Delay(60000); // 保持订阅 60 秒

完整示例: 温度监控

using Darra.PLC.SDK;

class TemperatureMonitor
{
private readonly PlcConnection _connection;

public TemperatureMonitor(string ip, int port)
{
_connection = new PlcConnection(ip, port);
}

public async Task RunAsync()
{
// 连接
await _connection.ConnectAsync();
Console.WriteLine("已连接到 PLC");

// 订阅温度变化
_connection.Subscribe("DB_ProcessParam.rActTemp", OnTemperatureChanged);
_connection.Subscribe("DB_Alarm.bActiveAlarm", OnAlarmChanged);

Console.WriteLine("温度监控已启动,按 Ctrl+C 退出");

// 保持运行
await Task.Delay(-1);
}

private void OnTemperatureChanged(string variableName, object value)
{
float temp = Convert.ToSingle(value);
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 当前温度: {temp:F1}°C");

if (temp > 150.0f)
{
Console.WriteLine("警告: 温度超限!");
}
}

private void OnAlarmChanged(string variableName, object value)
{
bool isAlarm = Convert.ToBoolean(value);
Console.WriteLine(isAlarm ? "报警激活!" : "报警已恢复");
}
}

异步批量操作

// 批量读取
var batchResult = await connection.ReadBatchAsync(
("DB_ProcessParam.rSetTemp", typeof(float)),
("DB_ProcessParam.rActTemp", typeof(float)),
("DB_Status.bMotorRunning", typeof(bool)),
("DB_ProcessParam.iPartCount", typeof(short))
);

foreach (var (name, value) in batchResult)
{
Console.WriteLine($"{name} = {value}");
}

// 批量写入
await connection.WriteBatchAsync(
("DB_Control.bStartMotor", true),
("DB_Control.bStopMotor", false),
("DB_ProcessParam.rSetTemp", 120.0f)
);

异步调用模式

SDK 提供三种异步调用模式,适应不同场景需求。

Async/Await 模式

适用于大多数上位机应用,异步等待结果返回:

// 异步读取 — 等待结果
float temperature = await connection.ReadFloatAsync("DB_ProcessParam.rActTemp");
Console.WriteLine($"温度: {temperature}");

// 异步写入 — 等待确认
await connection.WriteFloatAsync("DB_ProcessParam.rSetTemp", 150.0f);

回调模式

适用于需要持续处理推送数据的场景:

// 订阅回调 — 每次变量变化时触发
connection.Subscribe("DB_ProcessParam.rActTemp", (name, value) =>
{
float temp = Convert.ToSingle(value);
UpdateDisplay(temp);
});

// 一次性读取回调
connection.ReadFloatAsync("DB_ProcessParam.rActTemp")
.ContinueWith(task =>
{
if (task.IsCompletedSuccessfully)
{
Console.WriteLine($"读取完成: {task.Result}");
}
});

事件驱动模式

适用于需要精确控制订阅生命周期的应用:

// 订阅事件
connection.OnVariableChanged += (sender, args) =>
{
Console.WriteLine($"变量 {args.VariableName} 已变更为 {args.Value}");
};

connection.OnConnectionStateChanged += (sender, args) =>
{
Console.WriteLine($"连接状态: {args.NewState}");
};

// 订阅多个变量
connection.SubscribeRange(new[]
{
"DB_ProcessParam.rActTemp",
"DB_ProcessParam.rActPressure",
"DB_Status.bMotorRunning"
});

三种模式对比

模式适用场景特点
Async/Await标准的读写操作简单直接,等待结果
回调模式订阅推送、并行操作不阻塞主线程
事件驱动复杂应用、多订阅管理可集中处理所有事件

错误处理与重连

连接异常处理

try
{
await connection.ConnectAsync();
float temp = await connection.ReadFloatAsync("DB_ProcessParam.rActTemp");
Console.WriteLine($"温度: {temp}");
}
catch (PlcConnectionException ex)
{
Console.WriteLine($"连接失败: {ex.Message}");
// 重试逻辑
await Task.Delay(5000);
await connection.ConnectAsync();
}
catch (PlcVariableNotFoundException ex)
{
Console.WriteLine($"变量不存在: {ex.VariableName}");
}
catch (PlcTimeoutException ex)
{
Console.WriteLine($"读取超时: {ex.Message}");
}
finally
{
await connection.DisconnectAsync();
}

自动重连策略

SDK 内置自动重连机制,可通过配置参数控制:

var connection = new PlcConnection("192.168.1.100", 18821)
{
// 自动重连配置
AutoReconnect = true,
ReconnectIntervalMs = 3000,
MaxReconnectAttempts = 10,

// 超时配置
ConnectTimeoutMs = 5000,
ReadTimeoutMs = 3000,
WriteTimeoutMs = 3000,

// 心跳配置
KeepAliveIntervalMs = 10000,
KeepAliveTimeoutMs = 3000
};

重连回调

// 注册连接状态变化回调
connection.OnConnectionStateChanged += (sender, args) =>
{
switch (args.NewState)
{
case ConnectionState.Connected:
Console.WriteLine("已连接到 PLC 运行时");
// 重新订阅变量
RestoreSubscriptions();
break;

case ConnectionState.Disconnected:
Console.WriteLine("连接断开,自动重连中...");
break;

case ConnectionState.Reconnecting:
Console.WriteLine($"第 {args.ReconnectAttempt} 次重连...");
break;

case ConnectionState.ReconnectFailed:
Console.WriteLine($"重连失败: {args.ErrorMessage}");
// 通知管理员
NotifyAdmin(args.ErrorMessage);
break;
}
};

完整的状态管理示例

using Darra.PLC.SDK;

class RobustPlcClient : IDisposable
{
private readonly PlcConnection _connection;
private readonly List<string> _subscriptions = new();
private bool _disposed;

public RobustPlcClient(string ip, int port)
{
_connection = new PlcConnection(ip, port)
{
AutoReconnect = true,
ReconnectIntervalMs = 5000,
MaxReconnectAttempts = 0 // 无限重连
};

_connection.OnConnectionStateChanged += HandleStateChange;
}

public async Task ConnectAsync()
{
await _connection.ConnectAsync();
}

public void Subscribe(string variableName, Action<string, object> handler)
{
_connection.Subscribe(variableName, handler);
_subscriptions.Add(variableName);
}

private async void HandleStateChange(object sender, ConnectionStateEventArgs args)
{
switch (args.NewState)
{
case ConnectionState.Connected:
Console.WriteLine("已连接");
// 连接恢复后重新订阅
break;

case ConnectionState.Disconnected:
Console.WriteLine("连接断开");
break;

case ConnectionState.Reconnecting:
Console.WriteLine($"正在重连 ({args.ReconnectAttempt})...");
break;

case ConnectionState.ReconnectFailed:
Console.WriteLine($"重连失败: {args.ErrorMessage}");
break;
}
}

public void Dispose()
{
if (_disposed) return;
_connection?.Dispose();
_disposed = true;
}
}

SDK 参考

章节内容
通过 SDK 读写 DB 块DB 块详细读写操作
HTTP REST APIHTTP 方式访问 PLC 变量
OPC UAOPC UA 服务器集成

相关文档