设备模型
设备把「寄存器地址」或 PLC 地址变成业务含义,例如炉温。界面和业务应使用点表、ModbusDevice、McDevice、S7Device、FinsDevice、HostLinkDevice、MewtocolDevice 或 EtherNetIpDevice 的读写方法,而不是在窗口里拼十六进制。
登记
先注册通道,再注册设备:
builder.AddAcquisition(TimeSpan.FromMilliseconds(500));
builder.AddVirtualChannel("bus", new ModbusSlaveResponder(1, ModbusTransport.Rtu));
builder.AddModbusRtu("oven", "bus", unitId: 1, points: map =>
{
map.HoldingRegister("temperature", 0, 0.1);
map.HoldingRegister("setpoint", 1, 0.1).Writable("setpoint");
});
自定义设备必须实现 IDevice.Channel(继承 DeviceBase 即可)。卸载通道时,宿主靠这个属性级联移除设备。
自定义设备:
public sealed class TemperatureMeter : DeviceBase, IAcquisitionSource
{
public TemperatureMeter(string name, IChannel channel)
: base(name, channel)
{
Points = [new PointDefinition("temperature", name, PointValueKind.Double)];
// 需要按点名写回时,再实现 IPointWriter,并把对应点标为 writable: true。
}
public IReadOnlyList<PointDefinition> Points { get; }
public async Task<IReadOnlyList<PointReadResult>> ReadAsync(CancellationToken cancellationToken)
{
// 读取通道、换算后返回结果;点表发布和报警由宿主统一处理。
var value = await ReadTemperatureAsync(cancellationToken);
return [PointReadResult.Success(Name + ".temperature", value)];
}
}
builder.AddDevice("oven", "bus", (name, channel) => new TemperatureMeter(name, channel));
运行时:
app.Points.Get<double>("temperature")读取采集循环维护的当前值await app.Points.WriteAsync("setpoint", 80.0)按点名写回可写点app.Devices.Get<ModbusDevice>("oven")、app.Devices.Get<S7Device>("plc")、app.Devices.Get<HostLinkDevice>("plc")、app.Devices.Get<MewtocolDevice>("plc")、app.Devices.Get<EtherNetIpDevice>("plc")、app.Devices.Get<Dlt645Device>("meter")、app.Devices.Get<Iec104Device>("station")、app.Devices.Get<OpcUaDevice>("plc")做一次性或批量协议读写
自定义设备若要支持点名写回,除了 IAcquisitionSource 再实现 IPointWriter。
约定
- 一台设备绑定一条通道。多台设备共用通道时,宿主会按通道协调协议事务,避免同一物理通道上交错请求。
- 设备名在宿主内唯一,查找时不区分大小写。
- 点名在设备内唯一;不同设备出现同名点时,使用
设备.点。 - 设备类型不要引用 WinForms 或 WPF。
- 实现了
IAcquisitionSource且声明了点的设备,会自动进入采集循环;采集源只返回PointReadResult,不要直接写点表。