跳到主要内容

诊断

通过 device.getDiagnostics() 读诊断与报警(getDiagSnapshot() / getAlarms() 仍可用)。​

配合事件使用

建议用 事件 处理异常,而非自行轮询。 直接读取诊断方法适用于 UI 显示等场景。

运行态(isConnected() / getStatus() / getErrorCodeEnum())见 属性与状态机,本页只讲诊断快照、IOPS/IOCS 和报警。过程数据读写见 过程数据。

功能概览​

功能说明
诊断快照链路、帧计数、看门狗、抖动、报警观测
现场问题对照按症状选字段
过程数据质量IOPS / IOCS:数据 GOOD 还是 BAD
报警活动列表 / 历史 / 确认

诊断快照​

类别成员类型说明
可用性isOk()boolean诊断是否可用。false = 设备未启动,读 getMessage()
可用性isSharedMemoryMapped()boolean过程数据是否已就绪
可用性getMessage()String不可用时的原因;可用时为空
可用性getTimestamp()String快照时刻。缺字段为空
链路getState()String运行状态文案
链路isLinkUp()boolean网卡链路是否 Up
链路isConnected()boolean周期数据是否正常
链路getActiveIocrCount()long已激活的 IO 连接数
链路getIocrActive() / getIocrHealthy()longIO 连接激活 / 健康位图
计数getHeartbeat() / getCycleCounter()long心跳 / 周期循环计数
计数getLastError()long最近错误码(0 = 无)
计数getRxFrames() / getTxFrames()long收 / 发总帧数
计数getRxRtFrames() / getTxRtFrames()long收 / 发 RT 周期帧
计数getDroppedFrames() / getInvalidFrames()long被丢弃 / 非法帧
计数getWatchdogTrips()long看门狗超时次数
计数getLastRxTsc() / getLastTxTsc()long最近收 / 发帧 TSC
过程区getInputAreaLength() / getOutputAreaLength()longI 区 / Q 区通道容量(区长,含协议前缀,不是净荷真长)。随 PLC 主站协商重建,不要写死
周期getStackCycles()long周期计数
周期getStackFramesRx() / getStackFramesTx()long收 / 发帧
周期getStackMissedTicks()long错过的节拍
周期getStackMaxJitterUs()long最大抖动(微秒)
报警观测getStackAlarmRxCount()long收到控制器报警总数
报警观测getStackAlarmTxAckOk() / getStackAlarmTxAckFail()long本机报警被确认 / 确认失败
报警观测getStackAlarmAckPending()long在途报警(0/1)
报警观测getStackAlarmMaintState()long维护请求状态
报警观测getStackAlarmLastArep() 等long最近控制器报警:Arep / Slot / Subslot / Type / Seq / Usi / Len
错误getErrorCode()int错误码原值(0 = 无)
错误getErrorCodeEnum()PnSRuntimeErrorCode上项的枚举。未识别值为 UNKNOWN

getDiagSnapshot()​

public PnSDiagSnapshot getDiagSnapshot()

一次取回当前诊断快照,适合界面刷新和日志。设备尚未启动时 isOk() == false,读 getMessage(),不视为异常。

示例:

PnSDiagSnapshot snap = device.getDiagSnapshot();
if (!snap.isOk()) {
System.out.println(snap.getMessage());
return;
}

System.out.println(snap.isLinkUp() ? "Up" : "Down");
System.out.println(snap.isConnected() ? "周期交换正常" : "未建立");
System.out.println("帧: " + snap.getRxFrames() + " / " + snap.getTxFrames());
System.out.println("看门狗: " + snap.getWatchdogTrips());

现场问题对照​

现场症状看哪些字段
网线没插好getDiagSnapshot().isLinkUp()
周期数据通不通getDiagSnapshot().isConnected()
看门狗反复跳getDiagSnapshot().getWatchdogTrips()
帧在丢getDroppedFrames() + getInvalidFrames()
周期稳不稳getStackMaxJitterUs() + getStackMissedTicks()
控制器报警没消化getStackAlarmAckPending() / getStackAlarmTxAckFail()
本机有没有活动报警getAlarms() / getAlarmCount()
过程数据能不能信getIoStatus().isAllGood()

过程数据质量​

getIoStatus()​

public PnSIoStatus getIoStatus()

每个过程数据字节对应一个状态字节:0x80 = GOOD,0x00 = BAD。掉线如实全 BAD,不虚构 GOOD。未启动或失败返回 PnSIoStatus.getEmpty(),不抛。

类别成员类型说明
状态字节getInputIops() / getInputIocs()byte[]I 区:控制器提供 / 本设备消费后回报。拷贝,改了不影响本对象
状态字节getOutputIops() / getOutputIocs()byte[]Q 区:本设备提供 / 控制器消费后回报
判据isInputValid() / isOutputValid()boolean本轮是否收到过 I 区 / Q 写过且已送达控制器(掉线、未送出 = false)
判据isInputDataGood()boolean收到过 I 且输入 IOPS 全 GOOD
判据isOutputDataGood()boolean写过 Q 且输出 IOPS 全 GOOD
判据isOutputConsumed()boolean输出 IOCS 全 GOOD(控制器已消费)
判据isAllGood()boolean输入有效 + 输出有效 + 输出已消费
工厂PnSIoStatus.getEmpty()静态方法空状态(未启动 / 读不到)
public enum PnSIoxs {
BAD(0x00), // 数据无效
GOOD(0x80) // 数据有效
}

示例:

PnSIoStatus io = device.getIoStatus();
if (!io.isAllGood()) {
System.out.println(io);
if (!io.isInputDataGood())
System.out.println("控制器送来的数据不可用");
}

报警​

public int getAlarmCount()
public int getCriticalAlarmCount()
public java.util.List<AlarmItem> getAlarms()
public java.util.List<AlarmItem> getAlarmHistory()
public void ackAlarm(String id)
public int ackAllAlarms()

无活动报警返回空列表,不是失败。历史最近 500 条,时间升序。失败抛 PnSServiceException。

getAlarms()​

public java.util.List<AlarmItem> getAlarms()

当前活动报警。无活动报警返回空列表,不是失败。

示例:

for (PnSService.AlarmItem a : device.getAlarms())
System.out.println(a);

getAlarmHistory()​

public java.util.List<AlarmItem> getAlarmHistory()

报警历史(最近 500 条,时间升序)。无历史返回空列表,不是失败。

示例:

for (PnSService.AlarmItem a : device.getAlarmHistory())
System.out.println(a.getOccurredAt() + " " + a.getSeverity() + " " + a.getMessage());

ackAlarm(String id)​

public void ackAlarm(String id)

确认一条活动报警。ID 取自 getAlarms()。空串 / 无此 ID 抛 PnSServiceException。

示例:

device.ackAlarm("PnS.LinkDown");

ackAllAlarms()​

public int ackAllAlarms()

确认全部活动报警。返回被确认条数(0 = 无活动报警)。

示例:

int n = device.ackAllAlarms();
AlarmItem
属性类型说明
getId()String报警 ID(如 PnS.LinkDown)
getSeverity()String严重度:Info / Warning / Error / Critical
getMessage()String报警消息
getOccurredAt()OffsetDateTime最近一次发生时间。解析失败为 null
getCount()int发生次数(≥1)
getSource()String来源

I&M 标识​

getImData()​

public ImData getImData()

设备标识。I&M1–I&M3 已由原生栈启用并如实回读,I&M4 未启用(主站没写过时读到的是栈的出厂占位值)。缺字段保持空 / 0 / false,不虚构。getImSupported() 返回 String,不是 int;这次读到什么看 isIm14Supported() / getImNote()。

类别成员类型说明
I&M0getVendorId() / getDeviceId()int厂商 / 设备 ID
I&M0getOrderId()String订货号
I&M0getSerialNumber()String序列号
I&M0getHardwareRevision() / getSoftwareRevision()String硬件 / 软件版本
身份getStationName()String站点名
身份getProductName()String产品名
能力getImSupported()String已启用的 I&M 记录集,按原生栈掩码如实拼;从站未启动时只报 I&M0
能力isIm14Supported()booleanI&M1–4 是否读回成功;从站未启动读不到为 false,字段为空串
I&M1–4getIm1TagFunction() / getIm1TagLocation()String功能标签 / 安装位置
I&M1–4getIm2Date()String日期
I&M1–4getIm3Descriptor()String描述
I&M1–4getIm4SignatureHex()String签名(十六进制)
工程getImNote()StringI&M 口径说明
工程getProjectOrderNumber()String工程订货号
工程getProjectHardwareRelease() / getProjectSoftwareRelease()String工程硬件 / 软件版本

示例:

PnSService.ImData im = device.getImData();
System.out.println(im.getStationName());
System.out.println(im.getOrderId());

用户记录​

getRecords()​

public UserRecords getRecords()

用户区记录。空列表不是失败。

public static final class UserRecord {
public int getSlot() { }
public int getSubslot() { }
public int getIndex() { }
public int getLength() { }
public String getDataHex() { }
}

public static final class UserRecords {
public UserRecord[] getRecords() { }
public int getCount() { }
public String getTimestamp() { }
}

示例:

PnSService.UserRecords recs = device.getRecords();
int n = recs.getCount();

复位​

resetDevice(String mode)​

public void resetDevice(String mode)

复位设备。mode 非法 / 服务拒绝抛 PnSServiceException。这是慢操作,不要当失败误杀。

参数:

  • mode (String) — communication 通信复位(软停再启,记录保留);factory 工厂复位(销毁后全新启动,记录清空)

示例:

device.resetDevice("communication");