Skip to content

Virtual 驱动

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

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

协议背景

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

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

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

虚拟驱动没有真实协议层

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

属性配置

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

驱动属性(设备级 driver-attribute

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

属性code类型默认值说明
HosthostSTRINGlocalhost设备 IP(占位,不实际建连)
PortportINT18600设备端口(占位,不实际建连)

位号属性(point-attribute

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

属性code类型默认值说明
TagtagSTRINGTAG位号标签名

造值由位号类型决定,与 tag 无关

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

命令属性(command-attribute

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

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

模板用 ${...} 占位,由命令上下文渲染

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

事件属性(event-attribute

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

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

仅支持简单点号路径,不是完整 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

host/port 是占位,连不连得上都不影响出值

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

在 IoT DC3 中如何落地

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

点位写是占位实现

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

事件/命令是真实实现,但与矩阵的"协议订阅"含义不同

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

最小接入示例

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

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

延伸阅读

基于 AGPL-3.0 协议发布