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。