Files
pnokerandClaude Opus 4.8 93b111e3fb docs(site): deepen all 28 driver pages and add foundations back-links
Rewrite every protocol driver page (zh+en) into a four-section structure
— protocol background, attribute config, troubleshooting, and how it lands
in DC3 — cross-linked to the foundations network-layer chapters and the
driver capability matrix. Implementation status is verified against each
driver's source and labeled honestly (skeleton: ethernet-ip, iec104, dlms,
can, zigbee; partial: fins, mqtt, lwm2m, virtual). Add foundations
back-links from the concepts and drivers hubs to close the theory↔practice
loop.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:04:07 +08:00

9.8 KiB
Raw Permalink Blame History

title
title
Virtual 驱动

Virtual 驱动

dc3-driver-virtual 是 IoT DC3 的虚拟(仿真)驱动:它不连接任何真实设备,而是按采集周期为位号生成随机位号值,并模拟命令执行与事件上报。读完本页你能用它把整套接入链路跑通,并理解它"哪些能力是真实实现、哪些只是占位"。

你在这里:还没有真实 PLC/传感器,想先把平台端到端验证一遍,或想找一份最简单的驱动样板来照着写自己的协议。下一步可看设备接入。

协议背景

Virtual 不是某种现场总线或工业协议,而是一个仿真驱动——它把 IoT DC3 的整套接入流程(建设备、配模板 Profile、跑采集、看位号值)走通,但底层不发任何网络报文,所有数据都是本地随机造的。因为没有真实协议层,所以它不属于物联网四层架构里的某一层网络协议,而是平台侧用来演练、教学、压测的"无设备接入器"。典型用途:

  • 跑通平台、做演示——没有真实硬件时,先用它把端到端链路验证一遍。
  • 学习驱动模型——它是最简单的驱动,源码 VirtualDriverCustomServiceImpl 就是写自定义驱动的参考样板。
  • 压测与联调——批量造设备和位号,观察平台在持续数据流下的表现。

读取时按位号的数据类型造值:STRING 固定返回 abcd1234,BOOLEAN 返回随机真/假,其余类型返回 0~100 之间的随机浮点数。造什么值只看位号本身的数据类型(Point 的 pointTypeFlag),与 tag 内容无关。

::: info 虚拟驱动没有真实协议层 其他驱动页会链接到对应协议规范,本页没有——Virtual 不实现任何线缆协议。它的"链路"完全在 IoT DC3 内部,更多协议驱动请见驱动总览。 :::

属性配置

属性分两类:填在设备上的驱动属性(driver-attribute)和填在每个位号上的位号属性(point-attribute)。此外驱动还声明了命令属性与事件属性,用于命令执行和事件上报的模板渲染。这些属性的定义来自驱动模块的 application.yml,下面逐项说明它们的作用与取值来源。

驱动属性(设备级 driver-attribute)

接入一台虚拟设备时,在设备上填以下两项。注意:虚拟驱动并不真正连接 host:port,这两项只是占位,保持与真实驱动一致的配置形态,方便照搬演练。

属性 code 类型 默认值 说明
Host host STRING localhost 设备 IP(占位,不实际建连)
Port port INT 18600 设备端口(占位,不实际建连)

位号属性(point-attribute)

每个采集位号上填一项 tag,作为该位号在设备上的标识占位:

属性 code 类型 默认值 说明
Tag tag STRING TAG 位号标签名

::: tip 造值由位号类型决定,与 tag 无关 虚拟驱动忽略 tag 的具体内容,造值只看位号的数据类型 pointTypeFlag:STRING 出 abcd1234、BOOLEAN 出随机布尔、数值类出 0~100 随机浮点。想看布尔翻转就把位号配成 BOOLEAN,想看连续曲线就配成 FLOAT。 :::

命令属性(command-attribute)

虚拟驱动实现了命令执行(execute()):下发命令时,用命令参数与设备/命令上下文渲染 payloadTemplate 得到请求载荷,再渲染并解析 responseTemplate 得到一份模拟响应。整个过程不接触任何真实设备。

属性 code 类型 默认值 说明
Payload Template payloadTemplate STRING ${value} 用命令参数渲染出的请求载荷模板
Response Template responseTemplate STRING {} 模拟响应模板

::: tip 模板用 ${...} 占位,由命令上下文渲染 模板里的 ${value}、${deviceCode}、${commandCode}、${deviceId}、${commandName} 等占位,会被命令参数与设备/命令上下文逐一字符串替换。responseTemplate 是 JSON 对象时,其字段会被原样解析进命令返回结果;非 JSON 则整体作为 response 字段返回。返回里还会带上渲染后的 payload。 :::

事件属性(event-attribute)

虚拟驱动会周期性地为设备模拟事件上报(每 30 秒一轮)。事件属性用类 JSON Path 告诉驱动:从模拟报文里哪个路径取事件 code、哪个路径取事件载荷。

属性 code 类型 默认值 说明
Event Code Path eventCodePath STRING $.eventCode 解析事件 code 的 JSON 路径
Payload Path payloadPath STRING $.payload 解析事件载荷的 JSON 路径

::: warning 仅支持简单点号路径,不是完整 JSONPath 驱动内部 resolvePath() 只按 . 逐段在 Map 里取值(如 $.payload.value),不支持数组下标、过滤表达式等完整 JSONPath 语法。模拟报文形如 {"eventCode":"...","payload":{"value":...,"deviceCode":...,"source":"virtual"}},取不到时回退到事件自身的 eventCode。 :::

故障排查

Virtual 几乎不会因"连不上设备"而失败(它根本不建连),所以常见问题集中在调度、类型与配置上:

  • 30 秒内看不到位号值:确认驱动已注册上线、设备绑定的 Profile 下挂了启用的位号,且采集调度 dc3.driver.schedule.read.enable=true(默认开,cron 0/30 * * * * ?)。首轮值最长要等一个采集周期。
  • 位号值形态不符合预期(想要布尔却出数字):检查位号的 pointTypeFlag。类型配错只会造出不符合预期形态的值,不会报错——类型是位号侧的约定。
  • 写命令总是失败 / 不回显:这是预期行为。虚拟驱动的点位写 write() 是占位实现,永远返回 false,详见下文"在 IoT DC3 中如何落地"。要看可工作的下行链路,请用命令执行(execute(),对应命令属性)或换接真实驱动。
  • 收不到事件上报:事件上报由内部定时任务 dc3.driver.schedule.custom(cron 0/5 * * * * ?)驱动、并按 30 秒间隔节流;同时设备下必须有启用状态的事件定义,否则该轮跳过。
  • 设备显示离线:健康检查 cron 0/15 * * * * ?、租约超时 45 秒。若驱动进程停了或未按周期心跳,设备会被判离线——在线机制见设备。
  • host/port 填错却照样出值:见下方易错提示——虚拟驱动从不校验也不连接 host:port。

::: warning host/port 是占位,连不连得上都不影响出值 虚拟驱动从不真正建立到 host:port 的连接,即使填一个不存在的地址也照样产出随机值。换言之,用它验证不了真实的网络连通性——要测真实链路请换对应协议的驱动。 :::

在 IoT DC3 中如何落地

  • dc3.driver.code:VirtualDriver(驱动名 Virtual Driver)。这是稳定的路由标识,平台据此把设备、命令、事件路由到本驱动,不要随意改。
  • 类型:DRIVER_CLIENT——驱动作主动方,按周期主动产出数据。
  • 能力(与驱动能力矩阵对齐):
能力 状态 说明
读 read() 可用 按位号类型造随机值,已完整实现
写 write() 占位 点位写永远返回 false,不落任何设备
命令执行 execute() 可用 模板渲染 + 模拟响应,已完整实现
事件上报 schedule() 可用 每 30 秒模拟一轮事件上报

::: warning 点位写是占位实现 write() 在源码中直接返回 false——通过位号写值的请求永远"失败",不会改变任何状态。这与驱动能力矩阵里 Virtual 的「写 = —」一致。需要可工作的下行能力时,用命令执行(execute(),配 command-attribute),或换接真实驱动。 :::

::: info 事件/命令是真实实现,但与矩阵的"协议订阅"含义不同 矩阵把 Virtual 的「订阅/上报」标为 —,指的是它没有真实协议层的被动订阅。但代码里 execute() 与 schedule()(事件上报)都是完整实现的仿真能力——本页据源码如实标注。校验类方法 validate()/validatePoint() 当前不做实质校验,恒为通过。 :::

最小接入示例

不需要任何真实硬件,把一台虚拟设备接进来看到数据流动:

  1. 选 Virtual Driver 创建设备,驱动属性填 host=localhost、port=18600(保持默认即可)。
  2. 给设备绑定的 Profile 加一个温度位号(pointTypeFlag=FLOAT),位号属性填 tag=temperature。
  3. 启动驱动,30 秒内就能在位号值里看到 0~100 之间不断变化的随机值。

延伸阅读