Python API 参考
Darra Profinet Slave Python SDK(包名 darra_pns)。产品路径:PnSService.connect() 后 start / 写 I / 读 Q / stop。命名用 Python 惯例(snake_case)。周期自由配置,最低 1 ms。
应用只做:
start→ 写 I → 读 Q →stop。
from darra_pns import PnSService
数据方向
| 区 | 方向 | 应用该做什么 |
|---|---|---|
| I(输入面) | 设备 → 控制器 | 写。write / svc[i] = / pdo.Out[i] / write_bool("I0.0", …) |
| Q(输出面) | 控制器 → 设备 | 读。read / svc[i] / pdo.In[i] / read_bool("Q0.0")。写 Q 失败 |
概览
| 类 | 职责 |
|---|---|
PnSService | 服务模式单一入口:connect() / start / stop / 写 I / 读 Q / 地址化 / pdo |
Pdo / PdoArray / PdoDataItem | ETH 式 PDO:In 只读 Q,Out 可写 I |
PnSServiceAddress / PnSServiceArea | HSL 式地址解析 |
PnSServiceStatus / PnSRuntimeErrorCode | 运行态快照 / 服务端错误码 |
PnSDevice 等 | native 直连备选,不是产品路径 |
PnSService.connect()
from darra_pns import PnSService, PnSServiceError
with PnSService.connect() as svc:
svc.start()
svc.write(b"\x01\x02\x03\x04") # 写 I(设备 → 控制器)
q = svc.read() # 读 Q(控制器 → 设备)
print(q)
svc.stop()
生命周期:connect → start → 写 I / 读 Q / 地址化 / pdo → stop → close。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
connect(host=None, port=None, api_key=None) | PnSService | 设备 | 静态 | 本机会话。传 host 则连指定本机服务 |
start() | None | 设备 | 写 | 启动会话。已启动则直接返回 |
stop() | None | 设备 | 写 | 停止本会话。主站在连时不要拆应用关系 |
close() | None | 设备 | 写 | 释放会话。空会话 / 重复调用安全 |
is_connected | bool | 设备 | 只读 | 会话层是否仍有效(不是控制器 AR) |
is_started | bool | 设备 | 只读 | 本会话是否已 start |
host / port | str / int | 设备 | 只读 | 服务主机 / 端口 |
DEFAULT_PORT | int | 设备 | 只读 | 本机服务默认端口 |
写 I / 读 Q
svc.write(b"\x01\x02\x03\x04") # I
q = svc.read() # Q
print(svc[0]) # 从 PLC 读 Q[0]
svc[0] = 0xAA # 发给 PLC(写 I[0])
print(svc.input) # I 区快照(设备 → 控制器)
print(svc.output) # Q 区快照(控制器 → 设备)
允许短写。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
write(data) | None | IO | 写 | 写 I(设备 → 控制器) |
read() | bytes | IO | 只读 | 读 Q(控制器 → 设备) |
svc[offset] | int | IO | 只读 | 读 Q 一字节(从 PLC) |
svc[offset] = value | None | IO | 写 | 写 I 一字节(发给 PLC) |
input | bytes | IO | 只读 | I 区快照(设备 → 控制器) |
output | bytes | IO | 只读 | Q 区快照(控制器 → 设备) |
get_io() | (bytes, bytes) | IO | 只读 | 返回 (I, Q)。主 API 请用 read / write / input / output |
read_area(area, offset, length) | bytes | IO | 只读 | 整区批量读(I / Q / M) |
write_area(area, offset, data) | None | IO | 写 | 整区批量写(仅 I / M)。写 Q 抛 PnSServiceError |
地址化读写
HSL 式地址,与 C# PnSAddress.Parse 对齐。字 / 双字大端(PROFINET 网络序);偏移即字节偏移,不强制 2 / 4 对齐(IW3 合法)。服务模式是单一线性过程区,DB 仅槽位 1 有效。
svc.write_bool("I0.0", True) # 写 I 位
svc.write_int16("IW2", 0x1234) # 写 I 字(大端)
start = svc.read_bool("Q0.0") # 读 Q 位
cmd = svc.read_int16("QW2") # 读 Q 字
svc.write_bool("Q0.0", True) # 失败:Q 只读 → PnSServiceError
| 区域 | 地址格式 | 方向 | 写 |
|---|---|---|---|
| I 区 | I0.0 / IB0 / IW2 / ID4 | 设备 → 控制器 | 允许 |
| Q 区 | Q0.0 / QB0 / QW2 / QD4 | 控制器 → 设备 | 只读,写抛 PnSServiceError(NOT_AVAILABLE,文案含「Q 区 … 只读」) |
| M 区 | M0.0 / MB0 / MW100 / MD0 | 映射输入面 | 允许 |
| DB 区 | DB1.DBX0.0 / DB1.DBB2 / DB1.DBW0 / DB1.DBD4 | 槽位 1 数据块 | 写走 I 面;槽位 > 1 抛 PnSServiceError |
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
read_bool(address) | bool | IO | 只读 | 位:I0.0 / Q0.0 / M1.6 / DB1.DBX0.0 |
write_bool(address, value) | None | IO | 写 | 写位(I / M / DB)。写 Q 失败 |
read_int16(address) | int | IO | 只读 | 字:IW2 / QW2 / MW0 / DB1.DBW0,大端 |
write_int16(address, value) | None | IO | 写 | 写字(I / M / DB)。写 Q 失败 |
read_int32(address) | int | IO | 只读 | 双字:ID4 / QD4 / MD0 / DB1.DBD4,大端 |
write_int32(address, value) | None | IO | 写 | 写双字(I / M / DB)。写 Q 失败 |
parse_address(text) | PnSServiceAddress | IO | 静态 | 解析 HSL 式地址 |
PDO:In 读 Q / Out 写 I
对齐 ETH PDOArrayInstance / PdoDataItem。In 是合法标识符(主属性名);inn 是同一数组别名。偏移是过程映像字节地址。
pdo = svc.pdo
print(pdo.In[0].content) # 读 Q[0](控制器 → 设备),只读
pdo.Out[0].content = 0x11 # 写 I[0](设备 → 控制器)
pdo.Out[2].as_int16 = -2 # 大端 Int16
status, pos = pdo.read_struct("Hi")
pdo.write_struct("Hi", 1, -2)
pdo.In[0].content = 1 # 失败:RuntimeError(In 只读,写请用 Out)
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
pdo | Pdo | PDO | 只读 | 懒创建。In = Q 只读,Out = I 可写 |
pdo.In / pdo.inn | PdoArray | PDO | 只读 | In[i].content 读 Q。写 In 抛 RuntimeError |
pdo.Out | PdoArray | PDO | 读写 | Out[i].content = v 写 I;Out[i] = v 等价 |
PdoArray.length | int | PDO | 只读 | 当前过程映像字节长度 |
PdoDataItem.content | int | PDO | 读写 | 1 字节。In 读 Q;Out 写 / 回读 I |
as_int16 / as_uint16 | int | PDO | 读写 | 大端 16 位(写仅 Out) |
as_int32 / as_uint32 | int | PDO | 读写 | 大端 32 位(写仅 Out) |
as_float | float | PDO | 读写 | 大端 float(写仅 Out) |
get_bit(bit) / set_bit(bit, value) | bool / None | PDO | 读写 | 本字节位 0–7。set_bit 仅 Out |
read_struct(fmt) | tuple | PDO | 只读 | 从 Q struct.unpack('>'+fmt) |
write_struct(fmt, *values) | None | PDO | 写 | 大端 pack 后整段写 I |
inputs_mapping(fmt=None) | bytes / tuple | PDO | 只读 | Q 区快照;有 fmt 则 unpack |
copy_inputs_to(buf) | int | PDO | 只读 | 把当前 Q 拷到调用方缓冲 |
copy_to_outputs(src) | int | PDO | 写 | 把调用方缓冲写入 I(允许短写) |
运行态
已启动时 state / connected 读运行态。error_code 主返回枚举,不要把裸 int 当主 API。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
state | PnSState | 设备 | 只读 | 运行态。未启动 = NONE |
connected | bool | 设备 | 只读 | 是否已与 IO 控制器建立周期数据交换 |
error_code | PnSRuntimeErrorCode | 设备 | 只读 | 枚举主返回。未识别 = UNKNOWN |
error_code_enum | PnSRuntimeErrorCode | 设备 | 只读 | 旧名,转调 error_code |
status() | str | 设备 | 只读 | 状态原文字符串(诊断用) |
status_ex() | PnSServiceStatus | 设备 | 只读 | 一次取回 state / connected / error_code |
PnSState:NONE / IDLE / CONNECTING / PARAMETERIZED / APPLICATION_READY / DATA_EXCHANGE / ABORTED / RESETTING / CONFIG_ERROR / UNKNOWN。
PnSRuntimeErrorCode:OK=0 / ERR_INIT=-1 / ERR_CFG=-2 / ERR_THREAD=-3 / ERR_RUNNING=-4 / ERR_PDI=-5 / ERR_DAP=-6 / ERR_NULL=-8 / ERR_DIAG=-9 / UNKNOWN=-10000。
旧 get_state / get_error_code / get_connected / get_input / get_output 一律转调上表属性,不是主 API。
服务接口
PnSService.connect("127.0.0.1") 连本机服务。过程数据仍应走无 host 的 connect()。
| 成员 | 类型 | 类别 | 读写 | 说明 |
|---|---|---|---|---|
get_alarms() | list[PnSServiceAlarm] | 报警 | 只读 | 活动报警 |
ack_alarm(id) / ack_all_alarms() | None / int | 报警 | 写 | 确认单条 / 全部 |
send_process_alarm(slot, subslot, usi, payload=None) | None | 报警 | 写 | 发送过程报警 |
get_im_data() | PnSServiceImData | 标识 | 只读 | I&M |
get_records() | PnSServiceRecords | 记录 | 只读 | 应用参数记录 |
reset_device(mode) | None | 设备 | 写 | 复位(communication / factory) |
薄 SDK 无配置下发。网卡 / 站名由 GUI → 运行配置 XML → Service 加载。设备对外只开放一个 PROFINET 网口。
完整示例
from darra_pns import PnSService, PnSServiceError
with PnSService.connect() as svc:
svc.start()
svc.write(b"\x01\x02\x03\x04")
q = svc.read()
print(q)
svc.write_bool("I0.0", True)
print("Q0.0 =", svc.read_bool("Q0.0"))
svc.pdo.Out[1].content = 0x22
print("In[1] =", svc.pdo.In[1].content)
try:
svc.write_bool("Q0.0", True)
except PnSServiceError as e:
print("Q 只读:", e)
svc.stop()
安装
pip install darra-pns
或本地源码:
cd Darra_PnS_SDK/Python
pip install -e .
运行前提:Darra Profinet Slave 服务已启动,驱动已就绪(Windows,通常需管理员)。
native 直连(备选)
PnSDevice / PnSlave / PnSIo 仍导出。产品路径是上面的 PnSService.connect()。不要把 native 当默认入口。