Java API 参考
Darra PnSlave Java SDK(Maven 包 com.darra.pnet)。单一入口仍是 PnetService(本波不改标识符)。配置由 GUI / Service 完成,SDK 只负责【使用】——连接、启停、写 I、读 Q。
实时主路径:connect() 无主机 → start() 映射 \Device\DarraRT_Pnet_GlobalIO → write / read / pdo() → stop() 解除映射。不打开 \\.\DarraRT_Pnet,不加载 DarraPnet.dll,无用户周期(不要 tick(),不要自己循环把 Q 抄回 I)。
HTTP 备用(非主力):connect("127.0.0.1") 探测本地服务;仅当 Section 打不开时,start() / IO 才走 18840。不要把 HTTP 写成默认集成方式。
运行前提:Pnet Service 已启动,驱动已创建 \Device\DarraRT_Pnet_GlobalIO。
import com.darra.pnet.PDO;
import com.darra.pnet.service.PnetService;
概览
| 类 | 包 | 职责 |
|---|---|---|
PnetService | com.darra.pnet.service | 单一入口:无主机连接 / 启停 / 写 I / 读 Q / 地址化 |
PDO | com.darra.pnet | ETH 式过程数据:in() 读 Q,out() 写 I |
PnetServiceException | com.darra.pnet.service | 服务模式异常(Q 区只读、未连接、越界等) |
连接与生命周期
try (PnetService svc = new PnetService()) {
svc.connect(); // 主路径:无主机,不探测 HTTP
// svc.connect("127.0.0.1"); // 备用:显式回环才走 HTTP
svc.start(); // 映射 GlobalIO;已映射不 POST /api/start
// ... 写 I / 读 Q ...
svc.stop(); // 解除映射;主站在连不撕 AR
}
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
PnetService() | PnetService | 设备 | 构造 | 未连接会话(AutoCloseable) |
connect() | void | 设备 | 写 | 主路径。不填主机、不探测 HTTP;start() 再映射 GlobalIO |
connect(String host) | void | 设备 | 写 | 空 / null = 主路径;"127.0.0.1" = HTTP 备用 |
connect(host, port, apiKey) | void | 设备 | 写 | HTTP 备用完整形。只应填本机回环;局域网地址必失败。实时 IO 请用无参 connect() |
DEFAULT_PORT | int | 设备 | 只读 | 备用 HTTP 固定端口 18840(不可配置) |
start() | void | 设备 | 写 | 映射 \Device\DarraRT_Pnet_GlobalIO。已映射则幂等返回;Section 打不开才备用 HTTP |
stop() | void | 设备 | 写 | 解除映射、清本地启动态。主站在连不 POST /api/stop、不撕 AR。停止路径不抛 |
close() | void | 设备 | 写 | 释放会话(不向服务发 stop)。空会话 / 重复调用安全 |
isConnected() / isStarted() | boolean | 设备 | 只读 | 会话是否已 connect / 本地是否已 start |
host() / port() | String / int | 设备 | 只读 | 备用 HTTP 主机 / 端口(主路径仍记本机回环,但不发探测) |
生命周期:new → connect() → start() → 写 I / 读 Q → stop() → close()。无用户周期。
过程数据(写 I / 读 Q)
方向以控制器视角:
- I 区(设备 → 控制器,PPM / OutputArea):SDK 写。
write允许短写,再置OutputDirty。 - Q 区(控制器 → 设备,CPM / InputArea):SDK 读。写 Q 抛
PnetServiceException。
测法:写 I,再读 Q。不要自己跑周期,不要把 Q 抄回 I。
前 4 字节由主站同步:read() 得到的 Q 区前 4 字节是主站回写,从站不要改、不要抄回 I。测连通看这 4 字节是否随主站变化即可。
svc.write(new byte[]{0x01, 0x02, 0x03, 0x04}); // 写 I(允许短写)
byte[] q = svc.read(); // 读 Q
if (q.length >= 4) {
// q[0..3] = 主站同步,不要抄回 I
}
svc.setByte(4, 0x11); // 按偏移写 I
byte b = svc.getByte(0); // 按偏移读 Q
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
write(byte[] data) | void | IO | 写 | 写 I 区前缀(设备 → 控制器)。空数组不写;超长 / 未启动抛异常 |
read() | byte[] | IO | 只读 | 读 Q 区副本(控制器 → 设备)。空数组 = 尚无过程数据 |
setByte(offset, v) | void | IO | 写 | 按绝对地址写 I 区单字节 |
getByte(offset) | byte | IO | 只读 | 按绝对地址读 Q 区单字节 |
getIo() | byte[][] | IO | 只读 | 过程映像快照:[0] = I 区,[1] = Q 区 |
writeArea(area, offset, data) | void | IO | 写 | 整区部分覆盖写。仅 INPUT / MEMORY;OUTPUT(Q)只读抛异常 |
readArea(area, offset, length) | byte[] | IO | 只读 | 整区按偏移读取 |
PDO(pdo().in() / pdo().out())
学 ETH Slave.PDO():in() 只读 Q,out() 可写 I。与 read() / write() 同区。无 live 指针,每次读写新拷。Java 无索引器:in().get(i) ≡ C# In[i]。
PDO pdo = svc.pdo();
byte q0 = pdo.in().get(0).getContent(); // 读 Q[0]
pdo.out().get(0).setContent((byte) 0x11); // 写 I[0]
short w = pdo.in().get(2).asInt16(); // 大端字
pdo.out().get(2).asInt16((short) -2);
byte[] q = new byte[16];
pdo.copyInputsTo(q); // 整段拷 Q
pdo.copyToOutputs(new byte[]{0x01, 0x02}); // 短写 I
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
pdo() / getPdo() | PDO | PDO | 只读 | 同一会话上的 PDO 单例(懒初始化) |
in() | PdoArrayInstance | PDO | 只读 | 输入数组:读 Q(控制器 → 设备)。写抛 UnsupportedOperationException |
out() | PdoArrayInstance | PDO | 写 | 输出数组:写 I(设备 → 控制器) |
in().get(offset) / out().get(offset) | PdoDataItem | PDO | 只读 / 写 | 按字节偏移取项。偏移即过程映像地址 |
getContent() / setContent(byte) | byte / void | PDO | 只读 / 写 | 单字节。setContent 仅 out() |
asInt16() / asInt32() / asFloat() | 数值 | PDO | 读写 | 大端(PROFINET 网络序)。写仅 out() |
getBit(bit) / setBit(bit, value) | boolean / void | PDO | 读写 | 本字节第 0–7 位。写仅 out() |
copyInputsTo(dest) | int | PDO | 只读 | 整段拷 Q 到调用方缓冲(允许短拷) |
copyToOutputs(src) | int | PDO | 写 | 整段 / 短写 I |
readStruct / writeStruct | 结构 / void | PDO | 只读 / 写 | packed 大端结构 ↔ Q / I(PdoStruct 或 byte[]) |
地址化读写
西门子 / HSL 式地址,解析与 C# PnetAddress.Parse 对齐。字 / 双字大端,偏移即字节偏移,不强制 2 / 4 对齐(IW3 合法)。单一线性过程区,DB 仅槽位 1 有效(DB2 及以上抛 PnetServiceException)。
| 区域 | 地址格式 | 方向 | 写 |
|---|---|---|---|
| I 区 | I0.0 / IB0 / IW2 / ID4 | 设备 → 控制器 | 允许 |
| Q 区 | Q0.0 / QB0 / QW2 / QD4 | 控制器 → 设备 | 只读,写抛 PnetServiceException |
| M 区 | M0.0 / MB0 / MW100 / MD0 | 映射 I 面 | 允许 |
| DB 区 | DB1.DBX0.0 / DB1.DBB2 / DB1.DBW0 / DB1.DBD4 | 槽位 1 | 写走 I 面;仅 DB1 |
svc.writeBool("I0.0", true); // 写输入位
svc.writeInt16("IW2", (short) 0x1234); // 写输入字(大端)
boolean start = svc.readBool("Q0.0"); // 读输出位
short cmd = svc.readInt16("QW2"); // 读输出字
// svc.writeBool("Q0.0", true); // 抛 PnetServiceException:Q 区只读
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
readBool(address) | boolean | IO | 只读 | 位:I0.0 / Q0.0 / M1.6 / DB1.DBX0.0 |
writeBool(address, value) | void | IO | 写 | 写位(I / M / DB)。Q 区只读,抛 PnetServiceException |
readInt16(address) | short | IO | 只读 | 字:IW2 / QW2 / MW0 / DB1.DBW0,大端 |
writeInt16(address, value) | void | IO | 写 | 写字(I / M / DB)。Q 区只读抛异常 |
readInt32(address) | int | IO | 只读 | 双字:ID4 / QD4 / MD0 / DB1.DBD4,大端 |
writeInt32(address, value) | void | IO | 写 | 写双字(I / M / DB)。Q 区只读抛异常 |
parseAddress(text) | Address | IO | 静态 | 解析地址。非法格式 / 位号越界抛异常 |
状态
主路径状态来自共享内存头字段(Connected / State / LastError),不假绿。HTTP 备用才 GET /api/status。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
status() / getState() | PnetState | 设备 | 只读 | 运行态枚举 |
statusEx() | ServiceStatus | 设备 | 只读 | 一次取回 state / connected / errorCode |
getErrorCode() | PnetRuntimeErrorCode | 设备 | 只读 | 最近错误码枚举。未识别 = UNKNOWN |
getErrorCodeRaw() | int | 设备 | 只读 | 错误码原值(0 = 无错误) |
ServiceStatus:getState() / connected() / getErrorCode() / getErrorCodeRaw()。connected() = 是否已与 IO 控制器建立周期数据交换(只信头字段 / 服务端原值)。
PnetRuntimeErrorCode:OK=0 / ERR_INIT=-1 / ERR_CFG=-2 / ERR_THREAD=-3 / ERR_RUNNING=-4 / ERR_PDI=-5 / UNKNOWN=-10000。
完整示例
与仓库 examples/ServiceBasicExample.java 同口径。
import com.darra.pnet.PDO;
import com.darra.pnet.service.PnetService;
import com.darra.pnet.service.PnetServiceException;
public class ServiceBasicExample {
public static void main(String[] args) {
PnetService svc = new PnetService();
try {
svc.connect(); // 无主机 = 实时主路径
// HTTP 备用: svc.connect("127.0.0.1");
svc.start();
byte[] q = svc.read(); // 读 Q
if (q.length >= 4) {
System.out.printf("前 4 字节 %02X %02X %02X %02X%n",
q[0] & 0xFF, q[1] & 0xFF, q[2] & 0xFF, q[3] & 0xFF);
}
svc.write(new byte[]{0x01, 0x02, 0x03, 0x04}); // 写 I,看 Q
svc.writeBool("I0.0", true);
PDO pdo = svc.pdo();
System.out.printf("PDO In[0]=0x%02X%n", pdo.in().get(0).getContent() & 0xFF);
pdo.out().get(0).setContent((byte) 0x11);
svc.stop();
} catch (PnetServiceException e) {
System.err.println("错误: " + e.getMessage());
} finally {
svc.close();
}
}
}
Maven 依赖
<dependency>
<groupId>com.darra</groupId>
<artifactId>darra-pnet</artifactId>
<version>1.0.0</version>
</dependency>