🎓 基本概念
本页介绍了 Snet 中使用的基础接口、模型、枚举和模式。
IDaq -- 数据采集接口
IDaq 将 15 个接口合并为一个单一契约,用于所有 DAQ 设备操作:
public interface IDaq : IOn, IOff, IRead, IWrite, ISubscribe,
IGetStatus, IEvent, IGetParam, ICreateInstance, ILog,
IWA, IGetObject, ILanguage, IDisposable, IAsyncDisposable
{ }
| 接口 | 用途 |
|---|---|
IOn |
OnAsync(token) -- 打开设备连接 |
IOff |
OffAsync(bool, token) -- 关闭设备连接 |
IRead |
ReadAsync(Address, token) -- 从设备读取数据 |
IWrite |
WriteAsync(data, token) -- 向设备写入数据 |
ISubscribe |
订阅生命周期(添加/移除地址) |
IGetStatus |
GetStatusAsync(token) -- 设备状态 |
IEvent |
6 个事件(数据、信息、语言) |
IGetParam |
GetParamAsync() -- 获取类型化的参数元数据 |
ICreateInstance |
CreateInstanceAsync(param) -- 工厂方法 |
ILog |
日志输出和通知配置 |
IWA |
WAOnAsync、WAOffAsync、WAStatusAsync -- WebAPI 端点 |
IGetObject |
GetBaseObjectAsync() -- 获取底层对象 |
ILanguage |
GetLanguageAsync() / SetLanguageAsync() |
IDisposable / IAsyncDisposable |
资源清理 |
IMq -- 消息中间件接口
IMq 将 12 个接口合并用于消息协议(MQTT、Kafka 等):
public interface IMq : IOn, IOff, IProducer, IConsumer,
IGetStatus, IEvent, IGetParam, ICreateInstance, ILog,
ILanguage, IDisposable, IAsyncDisposable
{ }
与 IDaq 的主要区别:使用 IProducer/IConsumer 而非 IRead/IWrite,并且不包含 IWA、IGetObject、ISubscribe。
OperateResult
每个 Snet 方法都返回 OperateResult,一个统一的成功/失败信封:
public class OperateResult : ResultModel
{
public bool Status { get; set; } // true = 成功
public string Message { get; set; } // 人类可读的消息
public int RunTime { get; set; } // 执行时间(毫秒)
public object? ResultData { get; set; } // 类型化的结果有效载荷
}
工厂方法
// 无数据的成功
OperateResult.CreateSuccessResult("操作完成", runTime: 15);
// 带类型化数据的成功
OperateResult.CreateSuccessResult("读取成功", myFloatList, runTime: 42);
// 失败
OperateResult.CreateFailureResult("连接超时", runTime: 1000);
获取结果
var result = await modbus.ReadAsync(address);
if (result.GetDetails(out var details))
{
// details.Status 为 true,details.ResultData 包含值
}
Address 模型
Address -> AddressDetails -> AddressValue 链模型描述了 Snet 如何表示设备数据:
Address
public class Address
{
public string SN { get; set; } // 唯一组标识符
public List<AddressDetails> AddressArray { get; set; } // 地址集合
public DateTime CreationTime { get; set; }
}
关键方法:
GetAddressInfo(name, alias)-- 按名称或别名查找地址CheckAddress()-- 验证所有地址都有名称RemoveVirtualAddress()-- 仅过滤出真实(非虚拟)地址GetRealityAddressCount()-- 实际设备地址的数量
AddressDetails
一个包含元数据的单个地址条目:
| 属性 | 描述 |
|---|---|
AddressName |
设备地址字符串(例如 "40001"、"M100") |
AddressAnotherName |
可选别名 |
AddressDataType |
预期的数据类型(Float、Int16、Int32、Bool 等) |
AddressValue |
读取后解析的值 |
AddressType |
Reality(真实设备)或虚拟类型 |
SN |
地址组内的标识符 |
Quality |
QualityType 枚举值 |
AddressValue
继承 AddressDetails,增加数据质量和值属性。是 ReadAsync 返回的主要数据载体:
public class AddressValue : AddressDetails
{
public QualityType Quality { get; set; } // 数据质量
public object? ResultValue { get; set; } // 解析后的值
public object? OriginalValue { get; set; } // 解析前的原始值
public string Message { get; set; } // 详细信息
public DateTime Time { get; set; } // 采集时间
}
QualityType 枚举 (Snet.Model.@enum.QualityType : int)
指示每个地址读取的数据质量。带有中文 [Description] 特性:
| Int | 枚举 | 描述 (EN) | 描述 (ZH) |
|---|---|---|---|
-1 |
None |
Not yet processed | 未经过处理 |
0 |
Exception |
Error / exception | 异常 |
1 |
Normal |
Valid data — 触发 MQ 自动转发 | 正常 |
2 |
DataTypeError |
Data type mismatch | 数据类型错误 |
3 |
ParseUnknown |
Parse succeeded, correctness unknown (也触发 MQ 转发) | 数据经过解析并且解析成功无法得知数据的正确性 |
4 |
ParseError |
Parse failed | 解析错误 |
AddressMq
在中间件(MQTT、Kafka)中用于表示基于主题的寻址:
| 组件 | 描述 |
|---|---|
ISns |
订阅标识符 |
Topic |
MQTT 主题或 Kafka 主题名称 |
ContentFormat |
消息内容如何被解释 |
LanguageType 枚举
public enum LanguageType
{
zh, // 中文
en // 英文
}
用法:
await modbus.SetLanguageAsync(LanguageType.zh); // 切换到中文
var lang = await modbus.GetLanguageAsync(); // 获取当前语言
语言更改通过 OnLanguageEvent/OnLanguageEventAsync 事件传播到所有实例。
