跳到主要内容

属性与状态机

提示
  • 初始化请参考 初始化 页面。
  • 过程数据(写 Q / 读 I)请参考 过程数据 页面。
  • 诊断功能请参考 诊断 页面。

看状态用命名空间函数,不必构造。做 IO:构造 → Start() → 写 Q / 读 I。主站是否已周期交换看 Connected()

Start() 失败返回 false,写入 LastError(),不抛。读写 IO 失败抛 PnSException

属性

类别属性类型访问说明
静态IsServiceReady()bool只读本机服务是否就绪
LastError()const std::string&只读全应用最近一次失败文案(sticky,成功路径不清空)
LastErrorCode()PnSErrorCode只读全应用最近一次失败的调用错误码。从未失败为 Success
ServiceConnected()bool只读主站是否周期交换。服务没起来 = false
ServiceState()PnSState只读运行态。服务没起来 = Unknown
ServiceWaitReason()std::string只读等待原因。服务没起来 = 「服务未就绪」
ServiceStatusMessage()std::string只读状态文案。服务没起来 = 「服务未就绪」
连接与会话Connected()bool只读IO 控制器是否已经建立周期数据交换。true 才表示周期数据在换
Attached()bool只读本 SDK 会话是否已连上本机服务。Stop 不改变
IsRunning()bool只读IO 设备是否已启用(Start 之后、Stop 之前)
运行态Status()PnSState只读运行态。等于 StatusEx().state。读不到真实状态为 Unknown
StatusEx()PnSServiceStatus只读一次取回 state / connected / error_code
WaitReason()std::string只读本会话等待原因。主站已连时为空
EverConnected()bool只读是否曾与 IO 控制器建立过连接。true 且 Connected 为 false = 掉线
错误码ErrorCode()PnSRuntimeErrorCode只读最近一次运行错误。未识别值 Unknown
ErrorCodeRaw()int只读运行错误原值(0 = 无错误)。未识别值仍经本函数透传
ErrorMessage()std::string只读运行错误中文消息
LastServiceError()const std::string&只读本会话最近一次失败文案(sticky,成功路径不清空)
报警AlarmCount()int只读活动报警总数。与 GetAlarms 同源
CriticalAlarmCount()int只读Critical 报警数
GetAlarms()vector<PnSServiceAlarmItem>只读活动报警。见 [诊断 · 报警](./diagnostics#报警)
GetAlarmHistory()vector<PnSServiceAlarmItem>只读历史报警。见 [诊断 · 报警](./diagnostics#报警)
诊断与过程数据Events()PnSEvents&只读本机运行态事件。见 [事件](./events)
DiagSnapshot()PnSServiceDiagSnapshot只读一次取回链路、帧计数、看门狗、抖动。读不到时 ok 为 false
ProcessData()PnSProcessData只读过程数据子对象。见 [过程数据](./io)
本机会话Host()const std::string&只读本会话连接的服务主机
Port()uint16_t只读本会话连接的服务端口

同名命名空间函数与 PnSService:: 静态函数等价,不必构造:IsServiceReady()LastError()LastErrorCode()ServiceConnected()ServiceState()ServiceWaitReason()ServiceStatusMessage()。服务没起来写 LastError(),不抛。

PnSState

运行态。取值见 枚举参考

PnSRuntimeErrorCode

运行错误码。取值见 枚举参考

启停

Start()

bool Start();

使能 IO 设备。已 Start 且尚未 Stop 则幂等返回 true。这不是主站已周期交换,主站是否在换数据看 Connected()

返回值:

  • booltrue 成功;失败返回 false

失败写入静态 LastError(),不抛。

示例:

if (!device.Start())
printf("%s\n", LastError().c_str());

Stop()

void Stop();

停用 IO 设备。实例仍在,可再次 Start()。未 Start 或已 Stop 则幂等返回。失败写 LastError(),不抛。

不是 Close()Stop 不结束 SDK 会话。

示例:

device.Stop();

运行态

Status()

运行态。Start / Stop 只管启用 / 停用 IO 设备;本函数始终按现场如实读。读不到真实状态为 Unknown。未连上服务时抛 PnSException,不必构造时用 ServiceState()

PnSState Status();

示例:

if (device.Status() == PnSState::Running)
printf("周期数据交换正常\n");

StatusEx()

PnSServiceStatus StatusEx();

一次取回 state / connected / error_code、等待文案、报警计数。未连上服务时抛 PnSExceptionsnap.connected == true 表示已与 IO 控制器建立周期数据交换。运行错误枚举用 device.ErrorCode()

struct PnSServiceStatus
{
PnSState state = PnSState::Disconnected;
bool connected = false;
int error_code = 0;
std::string wait_reason;
std::string status_message;
int alarm_count = 0;
int critical_alarm_count = 0;
bool ever_connected = false;
};

示例:

auto snap = device.StatusEx();
if (snap.connected)
printf("周期交换正常\n");

WaitReason()

std::string WaitReason();

本会话等待原因。主站已连时为空。循环 if (!device.Connected()) 时读本函数或 LastServiceError()

示例:

if (!device.Connected())
printf("%s\n", device.WaitReason().c_str());

EverConnected()

bool EverConnected();

是否曾与 IO 控制器建立过连接。false = 从未连过;trueConnected() == false = 掉线。掉线后此判别仍保留。未连上服务 = false

示例:

if (!device.Connected() && device.EverConnected())
printf("掉线\n");

Connected()

bool Connected();

IO 控制器是否已经建立周期数据交换。true 才表示周期数据在换。未连上服务时改用 ServiceConnected(),不抛。不必构造时用 ServiceConnected()

Start() 之后本值仍可能是 false

示例:

if (device.Connected())
printf("主站在换周期数据\n");

错误码

ErrorCode()

PnSRuntimeErrorCode ErrorCode();

最近一次运行错误(枚举)。未识别值 Unknown。原值仍经 ErrorCodeRaw() 透传。中文消息用 ErrorMessage()。未连上服务 = Ok

示例:

PnSRuntimeErrorCode err = device.ErrorCode();
std::string text = device.ErrorMessage();
int raw = device.ErrorCodeRaw();

ErrorCodeRaw()

int ErrorCodeRaw();

运行错误原值(0 = 无错误)。未识别值仍经本函数透传。未连上服务 = 0。

示例:

int raw = device.ErrorCodeRaw();

ErrorMessage()

std::string ErrorMessage();

运行错误中文消息。未识别码返回带原值的说明,不丢信息。

示例:

printf("%s\n", device.ErrorMessage().c_str());

LastServiceError()

const std::string& LastServiceError() const;

本会话最近一次失败文案(sticky)。成功路径不清空。循环 if (!Connected()) 时若本值为空,读 WaitReason()

示例:

printf("%s\n", device.LastServiceError().c_str());

LastError() / LastErrorCode()

static const std::string& LastError();
static PnSErrorCode LastErrorCode();

全局,不必构造。成功路径不清空。读写 IO 失败抛 PnSExceptioncode() 为 SDK 调用错误码。

PnSErrorCode

SDK 调用错误码。取值见 枚举参考

C 语言码 ≠ 本枚举码-4..-8 同值不同义),跨语言换算必须走 PnSErrorCodeFromNative(int)constexpr,可用于 static_assert),禁止裸 static_cast

示例:

try {
device.WriteBool("Q0.0", true);
} catch (const PnSException& ex) {
printf("%s code=%d\n", ex.what(), ex.code());
}

诊断

DiagSnapshot()

PnSServiceDiagSnapshot DiagSnapshot();

一次取回链路、帧计数、看门狗、抖动。读不到时 ok == false,读 message,不视为异常。字段见 诊断

示例:

auto snap = device.DiagSnapshot();
if (!snap.ok)
printf("%s\n", snap.message.c_str());

完整示例

#include "pns.hpp"
#include <cstdio>
using namespace darra::pns;

int main()
{
PnSService device;
if (!device.Start())
return 1;

while (running)
{
if (!device.Connected())
{
printf("%d\n", static_cast<int>(device.Status()));
printf("%s\n", device.WaitReason().c_str());
printf("%s\n", device.ErrorMessage().c_str());
continue;
}

device.WriteBool("Q0.0", true);
bool fromPlc = device.ReadBool("I0.0");
(void)fromPlc;
}
device.Stop();
return 0;
}