SDK 集成概述
Darra SDK 是用于与 Darra PLC 运行时通信的编程接口集合,支持多种编程语言,适用于上位机监控、数据采集、MES/ERP 集成等场景。
SDK 概述
Darra SDK 基于 DarraLink 协议(TCP 端口 18821)与 PLC 运行时通信,提供变量读写、DB 块访问、报警订阅、趋势数据查询等功能。
支持的编程语言
| 语言 | 包管理器 | 包名 | 平台 |
|---|---|---|---|
| C# | NuGet | Darra.PLC.SDK | Windows, Linux |
| C++ | CMake / vcpkg | darra-plc-sdk | Windows, Linux |
| Python | pip | darra-plc | Windows, Linux |
| Java | Maven | com.darra:plc-sdk | 跨平台 (JVM) |
| Rust | cargo | darra-plc | Windows, 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 API | HTTP 方式访问 PLC 变量 |
| OPC UA | OPC UA 服务器集成 |
相关文档
- 通过 SDK 读写 DB 块 — DB 块访问详解
- HTTP REST API — HTTP API 参考
- OPC UA — OPC UA 集成
- DB 块访问 — PLC DB 块概念