跳到主要内容

属性与状态机

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

属性

类别属性类型访问说明
静态is_service_ready / PnSService.is_service_readybool只读本机服务是否就绪
last_error / PnSService.last_errorstr只读全应用最近一次失败文案(sticky,成功路径不清空)
last_error_code / PnSService.last_error_codePnSErr只读全应用最近一次失败的调用错误码。从未失败为 OK
service_connected / PnSService.service_connectedbool只读主站是否周期交换。服务没起来 = False
service_state / PnSService.service_statePnSState只读运行态。服务没起来 = UNKNOWN
service_wait_reason / PnSService.service_wait_reasonstr只读等待原因。服务没起来 = 「服务未就绪」
service_status_message / PnSService.service_status_messagestr只读状态文案。服务没起来 = 「服务未就绪」
连接与会话connectedbool只读IO 控制器是否已经建立周期数据交换。True 才表示周期数据在换
attachedbool只读本 SDK 会话是否已连上本机服务。stop 不改变
is_running / is_startedbool只读IO 设备是否已启用(start 之后、stop 之前)
运行态statePnSState只读运行态枚举。读不到真实状态为 UNKNOWN,不要当成 NONE
wait_reasonstr只读本会话等待原因。主站已连时为空
ever_connectedbool只读是否曾与 IO 控制器建立过连接。True 且 connected 为 False = 掉线
错误码error_codePnSRuntimeErrorCode只读最近一次运行错误。未识别值 UNKNOWN
error_code_rawint只读运行错误原值(0 = 无错误)。未识别值仍经本属性透传
error_messagestr只读运行错误中文消息
last_service_errorstr只读本会话最近一次失败文案(sticky,成功路径不清空)
整区字节inputbytes只读整块回读,名字反着 —— 对应 `process_data.Out` 那块,见下方说明
outputbytes只读整块快照,名字反着 —— 对应 `process_data.In` 那块,与 read() 同源
output_committedbool只读写出那块是否已提交到共享区(写过且已送达)。未 start / 提交失败 = False
input / output 的名字是反的

svc.inputsvc.output 沿用服务端内存区的叫法,方向与 process_data 那套正好相反

属性对应过程数据里的哪一块
svc.inputprocess_data.Out / outputs_mapping(S) 同一块(不是 In 那块)
svc.outputprocess_data.In / inputs_mapping(S) 同一块(不是 Out 那块)

日常别用它们:svc.read() / svc.write()process_data.In / Out 的名字和含义一致,用那套。只有要整段裸字节时才用 svc.input / svc.output,用之前先看清上表。

模块函数与类属性等价(类属性无括号)。服务没起来写 last_error,不抛。

from darra_pns import (
is_service_ready, service_connected, service_state,
service_wait_reason, last_error,
)

ready = is_service_ready()
master = service_connected()
st = service_state()
wait = service_wait_reason()
err = last_error()
PnSState

运行态类型。取值见 枚举参考

PnSRuntimeErrorCode

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

启停

构造签名见 初始化start 一次,不要每个周期调用。

start()

def start(self) -> PnSErr

启用 IO:启动本机服务、建立过程数据通道、POST /api/start。已 start 且尚未 stop 则幂等返回 PnSErr.OK

这不是主站已周期交换,主站是否在换数据看 connected。同一时刻只允许一个实时会话,第二个返回 PnSErr.NOT_AVAILABLE(契约见 SDK 连接契约)。

示例:

rc = svc.start()
if rc != PnSErr.OK:
print(svc.last_service_error)

stop()

def stop(self) -> None

停用 IO(POST /api/stop)。过程数据通道与会话都留着,可以再 start。未 start 或已 stop 幂等。不是 close

示例:

svc.stop()

close()

def close(self) -> None

断开本机服务会话。Q 会被清掉(清的是 Q 的净荷窗:PPM 输出区前 3 字节 IOPS 前缀不动);I 留着,等下一个程序。幂等,with 退出会调本方法。放开之后这个实例不能再用,要重新 PnSService()。实时主路径同时让出实时连接门。

示例:

svc.close()

运行态

state

运行态(只读)。start / stop 只管启用 / 停用 IO 设备;本属性始终按现场如实读。读不到真实状态为 UNKNOWN,不要当成 NONE

@property
def state(self) -> PnSState

示例:

if svc.state == PnSState.DATA_EXCHANGE:
print("周期数据交换正常")

wait_reason

@property
def wait_reason(self) -> str

本会话等待原因。主站已连时为空。循环 if not svc.connected 时读本属性或 last_service_error

示例:

if not svc.connected:
print(svc.wait_reason)

ever_connected

@property
def ever_connected(self) -> bool

是否曾与 IO 控制器建立过连接。False = 从未连过;Trueconnected == False = 掉线。掉线后此判别仍保留。

示例:

if not svc.connected and svc.ever_connected:
print("掉线")

错误码

error_code

@property
def error_code(self) -> PnSRuntimeErrorCode

最近一次运行错误(枚举)。未识别值 UNKNOWN。原值仍经 error_code_raw 透传。中文消息用 error_message

示例:

err = svc.error_code
text = svc.error_message
raw = svc.error_code_raw

error_code_raw

@property
def error_code_raw(self) -> int

运行错误原值(0 = 无错误)。未识别值仍经本属性透传。

示例:

raw = svc.error_code_raw

error_message

@property
def error_message(self) -> str

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

示例:

print(svc.error_message)

last_service_error

@property
def last_service_error(self) -> str

本会话最近一次失败文案(sticky)。成功路径不清空。循环 if not connected 时若本属性为空,读 wait_reason

示例:

print(svc.last_service_error)

诊断

诊断子对象 diagnostics,以及读同一份数据的扁平属性。字段逐条见 诊断。运行中先看这里,再去碰过程数据。

类别属性类型访问说明
入口diagnosticsPnSDiagnostics只读诊断子对象(快照 / IOPS / 报警 / 记录)
diag_snapshotPnSServiceDiagSnapshot只读诊断快照。字段见 [诊断](./diagnostics)
io_statusPnSServiceIoStatus只读IOPS / IOCS。`0x80` = GOOD。见 [诊断](./diagnostics)
alarms / alarm_historylist只读活动报警 / 历史(最近 500 条)。空列表不是失败
alarm_count / critical_alarm_countint只读活动报警总数 / Critical 报警数。与 alarms 同源
im_dataPnSServiceImData只读I&M 标识:站名、厂商 / 设备 ID、订货号
process_dataProcessData只读过程数据视图,写 Q / 读 I。见 [过程数据](./io)

示例:

snap = svc.diag_snapshot
if not snap.ok:
print(snap.message)
else:
print("Up" if snap.link_up else "Down")

for a in svc.alarms:
print(a.message)

IOPS 要看 svc.io_status.all_good —— 数值在,不等于这一拍能用。

完整示例

from darra_pns import PnSErr, PnSService

with PnSService() as svc:
rc = svc.start()
if rc != PnSErr.OK:
print(svc.last_service_error)
else:
while running:
if not svc.connected:
print(svc.state)
print(svc.wait_reason)
print(svc.error_message)
continue

svc.write_bool("Q0.0", True) # 写 Q
from_plc = svc.read_bool("I0.0") # 读 I
_ = from_plc

svc.stop()