信捷 - Snet Docs

XinJE 协议驱动

包: Snet.XinJE | 类: XinJEOperate | 类型数量: 4

通过 Modbus TCP 和 Xinje 专用协议提供与信捷 PLC(XC/XD/XL 系列)的连接。

安装

dotnet add package Snet.XinJE

快速入门

using Snet.XinJE;

var op = await XinJEOperate.InstanceAsync(new XinJEData.Basics
{
    IpAddress = "192.168.1.100",
    Port = 502
});

var address = new Address(new List<AddressDetails>
{
    new("读数", "D100", DataType.Int16),
    new("读数2", "D102", DataType.Int16)
});
var result = await op.ReadAsync(address);
if (result.Status)
{
    var data = result.GetSource<ConcurrentDictionary<string, AddressValue>>();
    foreach (var kv in data)
        Console.WriteLine($"{kv.Key} = {kv.Value.ResultValue}");
}
else
{
    Console.WriteLine($"读取失败: {result.Message}");
}

// 订阅之前 绑定数据事件
op.OnDataEventAsync += async (sender, e) =>
{
    if (e.Status)
    {
        var data = e.GetSource<ConcurrentDictionary<string, AddressValue>>();
        foreach (var kv in data)
            Console.WriteLine($"{kv.Key} = {kv.Value.ResultValue}");
    }
    else
    {
        Console.WriteLine($"{e.Message}");
    }
};

var subAddr = new Address(new List<AddressDetails>
{
    new("读数", "D100", DataType.Int16)
});
await op.SubscribeAsync(subAddr);

// 后续:取消订阅
// await op.UnSubscribeAsync(subAddr);

await op.DisposeAsync();

配置参数

参数 类型 默认值 说明
IpAddress string 127.0.0.1 PLC IP 地址
Port int 6688 通信端口
ConnectTimeOut int 1000 连接超时(毫秒)
ReceiveTimeOut int 1000 接收超时(毫秒)
ProtocolType enum XinJETcpNet 协议类型(默认 XinJETcpNet)

支持类型

适用于 XC/XD/XL 系列的信捷协议,支持 D/M/X/Y/T/C/S/HD 寄存器。

地址格式

区域 地址格式 示例
X / Y (位, 八进制) X{n} / Y{n} X17 (= 15), Y2
M/S/SM/ET/SEM/HM/HS/HT/HC/HSC/T/C (位) {类型}{编号} M10, S5, SEM0, T0, C0
D/T/C/SD/TD/CD/HD/FD/ID/QD/HSCD/HSD/HTD/HCD/SFD/FS/ETD (字) {类型}{编号} D100, T50, SD10, FD5, FS10
注意

X/Y 为八进制(按 8 进制解析);位读每次最多 1920 位、字读 120 字;Bool 与 Word 必须分开组批。位类型 SEM 映射偏移 49280、字类型 FS 映射偏移 62656;T/C 可位读(线圈),其当前值为 TD/CD;未知区与含尾随垃圾的地址(如 X10.5)不组包。自 26.250.1 起 XinJEInternalNet 的点号 Bool 地址(D100.5)经字路径读取(SnetHelper.ReadBool,16 位/字、按字反转)。

支持的数据类型

所有读取按 AddressDetails.DataType 分发 — 别名(Short = Int16Float = SingleInt = Int32 等)共用同一分支。

数据类型 支持 说明
Bool 位读取 — 线圈 / 字内位
Int16 / Short, UInt16 / Ushort 16 位整数
Int32 / Int, UInt32 / Uint 32 位整数
Int64 / Long, UInt64 / Ulong 64 位整数
Float / Single, Double 32 / 64 位浮点
String / Char length + 编码读取
ByteArray + 全部 10 种 *Array length 的数组读取
Byte ReadAsync 中有 case 但无底层读取 — "不支持该类型读取"
注意

NoneDateDateTimeTimeReadAsync 中没有分支 — 不支持。

地址自动组包与解包

每个数采驱动都实现 IPacker,因此 XinJEOperate 可直接将分散地址合并为最小批量读取,并直接解包结果——无需装配处理器(见 IPacker 接口):

// 组包:将分散地址合并为最少的批量读取
var packed = await op.PackerAsync(address, "XinJETcpNet");
if (!packed.Status) return;                                  // 组包失败
var packedAddr = packed.GetSource<Address>();

// 一次往返读取组包后的批次
var result = await op.ReadAsync(packedAddr);
if (!result.Status) return;                                  // 读取失败
var data = result.GetSource<ConcurrentDictionary<string, AddressValue>>();

// 解包:将每个批次的原始字节解析回各地址的值
var unpacked = await op.UnPackerAsync(data);
if (!unpacked.Status) return;                                // 解包失败
var values = unpacked.GetSource<List<ConcurrentDictionary<string, AddressValue>>>();
foreach (var dict in values)
    foreach (var v in dict)
        Console.WriteLine($"{v.Key} = {v.Value.ResultValue}");

信捷协议单次读取最多组包 240 字节(MaxReadLength)。引擎细节:地址自动组包

Bool(所有区域)自 26.235.x 起全部降级——XinJETcpNet 是 ModbusTcpNet 子类,位区读取走 Modbus FC1 线圈读(length=线圈数),与组包批长度差 8 倍;仅 XinJEInternalNet(cmd32 字读)路径正确,packer 无法区分驱动路径。字读取正常组包。

订阅

先绑定数据事件,再通过 SubscribeAsync 添加地址;数据通过 OnDataEventAsync 到达:

op.OnDataEventAsync += async (sender, e) =>
{
    if (e.Status)
    {
        var data = e.GetSource<ConcurrentDictionary<string, AddressValue>>();
        foreach (var kv in data)
            Console.WriteLine($"{kv.Key} = {kv.Value.ResultValue}");
    }
    else
    {
        Console.WriteLine($"订阅错误: {e.Message}");
    }
};

var subAddr = new Address(new List<AddressDetails>
{
    new("读数", "D100", DataType.Int16)
});
await op.SubscribeAsync(subAddr);

// 后续:停止监视
// await op.UnSubscribeAsync(subAddr);

支持操作

操作 方法
连接 OnAsync()
断开 OffAsync()
读取 ReadAsync(address)
写入 WriteAsync(values)
订阅 SubscribeAsync(address)
组包 / 解包 PackerAsync(address, protocolTypeKey) / UnPackerAsync(data)

参见