02 · 驱动通信与运行数据引擎 —— Hmi.Drivers / Hmi.Backend
要"把工程真正跑起来、连上 PLC、出实时值",靠这两个:Hmi.Drivers 提供协议驱动框架与插件,Hmi.Backend 用它建实时库、跑采集。
Hmi.Drivers —— 协议驱动框架
职责:与协议无关的驱动框架 —— 插件注册表、驱动/解析器契约(只管连接、收发、地址解析;调度、块读、重连由上层 App 负责)。子项目:Drivers.Abstractions、Drivers.S7SmartClient、Drivers.ModbusTcp、Drivers.IoTClientPlc、Drivers.PanasonicMewtocol。
插件契约 IProtocolPackage
src/Hmi.Drivers/Drivers.Abstractions/Plugins/IProtocolPackage.cs —— 一个协议包的入口:
string ProtocolId; // 唯一协议 id
string DisplayName; // 界面显示名
string Version;
string? AddressSyntaxHelp; // 地址语法帮助(向导用)
IProtocolDriver CreateDriver();
IAddressParser CreateAddressParser();
想加一个自研协议:实现这个接口,编译成 dll 丢进 plugins/ 目录即可;ABI 由 ProtocolAbi.Version 校验。
注册表 ProtocolRegistry
src/Hmi.Drivers/Hmi.Drivers/Plugins/ProtocolRegistry.cs(public sealed class):
bool Register(IProtocolPackage)—— 内置协议先注册;插件 id 撞车会被拒。IReadOnlyList<string> RegisterLoaded(IEnumerable<PluginLoadResult>)—— 批量登记已加载插件。(IProtocolDriver, IAddressParser) Create(string protocolId)。bool Contains(string)/IReadOnlyCollection<IProtocolPackage> Packages。
Hmi.Backend —— 运行数据引擎
职责:从工程建 RTDB、跑通道采集(块读规划 + 调度)、对外提供读写。依赖 Hmi.Core、Hmi.Project、全部驱动项目。
入口 RuntimeHost : IBackendDataService
src/Hmi.Backend/RuntimeHost.cs(public sealed class)。构造:RuntimeHost(LoadedProject project, ProtocolRegistry? protocols = null) —— 内部用 RtdbBridge.BuildTags 建库、BuildChannels + BlockPlanner + ChannelRuntime + ChannelScheduler 组采集。
| 成员 | 作用 |
|---|---|
RtdbCore Rtdb |
建好的实时库(交给上层订阅/读写) |
IReadOnlyDictionary<string,int> TagIdByName |
点名 → id 映射 |
void Start() / Task StopAsync() |
启停采集 |
WriteTag(name, value) |
写值(运行态) |
OpenScreen(...) / RunScript(...) |
动作转发(实现 IActionDispatcher) |
bool IsDeviceOnline(...) / bool ReconnectChannel(...) |
设备在线判断 / 手动重连 |
event CycleOverrun |
采集周期超时告警 |
IBackendDataService
IBackendDataService : IActionDispatcher, IDisposable —— RtdbCore Rtdb; IReadOnlyDictionary<string,int> TagIdByName; void Start(); Task StopAsync();。上层(Shell、RuntimeCore.Host)只认这个接口。
驱动工厂 DriverFactory(静态)
BuildRegistry(string? pluginsDir = null) —— 注册 Simulation、ModbusTcp、S7(S7Profiles.All)、Mitsubishi、OmronFins、Panasonic 内置包,并加载 pluginsDir 下的插件;PluginErrors 收集加载失败。
小结 —— 跑起来的最小骨架
var project = ProjectLoader.Load(projectDir);
var registry = DriverFactory.BuildRegistry(Path.Combine(projectDir, "plugins"));
using var host = new RuntimeHost(project, registry);
host.Start(); // 开始采集,Rtdb 里开始出真实值
// … 订阅 host.Rtdb / host.WriteTag(...) …
await host.StopAsync();
要在此之上叠历史、报警、脚本 → 见第 03、04 章的 RuntimeDataServices.Compose。