VOCsReminder 1.0.4
dotnet add package VOCsReminder --version 1.0.4
NuGet\Install-Package VOCsReminder -Version 1.0.4
<PackageReference Include="VOCsReminder" Version="1.0.4" />
<PackageVersion Include="VOCsReminder" Version="1.0.4" />
<PackageReference Include="VOCsReminder" />
paket add VOCsReminder --version 1.0.4
#r "nuget: VOCsReminder, 1.0.4"
#:package VOCsReminder@1.0.4
#addin nuget:?package=VOCsReminder&version=1.0.4
#tool nuget:?package=VOCsReminder&version=1.0.4
VOCsReminder
VOCsReminder 是面向 VOCs 色谱设备应用的本地提醒库,用于统一处理磁盘容量不足提醒和设备模块维护到期提醒。库负责配置保存、到期计算、磁盘检测、提醒去重、状态持久化和处理闭环;应用层负责触发检测、展示提醒,并在用户完成处理后通知库。
- 当前版本:
1.0.0 - 目标框架:
.NET Framework 4.8、.NET Standard 2.0、.NET 8.0、.NET 10.0 - 数据存储:SQLite
- 调度方式:由应用层调用,库不包含定时器
解决目标
- 定期检查指定目录所在磁盘的可用容量;
- 可用容量小于或等于阈值时产生提醒;
- 按小时、天或月维护设备模块的到期时间;
- 维护时间到期后产生提醒;
- 同一模块存在未处理提醒时,不重复创建或推送新提醒;
- 使用 SQLite 保存配置、维护时间和提醒历史;
- 应用重启后恢复显示尚未处理的提醒;
- 应用处理维护提醒后,从处理时间开始计算下一次到期时间;
- 通过接口把提醒展示交给应用层,不依赖具体 UI 框架。
工作原理
磁盘容量检测
应用调用 StorageCapacityDetectProcess.Execute() 后,库按以下顺序执行:
- 查询
EquipmentModuleToken.STORAGE_CAPACITY对应的模块配置; - 配置不存在或未启用时结束;
- 已存在该模块的未处理提醒时结束;
- 读取磁盘容量配置;
- 获取配置目录所在磁盘分区的可用空间;
- 可用空间大于阈值时结束;
- 可用空间小于或等于阈值时,先写入未处理提醒,再调用
IMessageReminder通知应用层。
每调用一次流程,就执行一次容量检测。检测周期由应用层决定。
设备模块维护检测
应用调用 DeviceModuleMaintainRemindProcess.Execute() 后,库遍历除磁盘容量以外的模块配置:
- 跳过未启用的模块;
- 跳过已经存在未处理提醒的模块;
- 读取模块维护数据;
- 到期时间未到时跳过;
- 到期后先写入未处理提醒,再调用
IMessageReminder通知应用层。
统一检测入口
ReminderProcess.Execute() 是推荐入口,一次调用依次执行:
- 磁盘容量检测;
- 设备模块维护检测。
应用层也可以按需单独调用任一检测流程。
提醒处理闭环
应用展示提醒后,在用户确认处理完成时调用 IMessageHandler.Handling(...):
- 磁盘容量提醒:标记为已处理并记录处理时间;
- 设备维护提醒:标记为已处理、记录处理时间,并从处理时间开始计算下一次到期时间。
已处理提醒不会删除,可以继续作为历史记录查询。
库分层
| 层次 | 主要类型 | 职责 |
|---|---|---|
| 应用接入层 | VOCsRemindManager、IMessageReminder |
提供统一入口,接收应用层提醒实现,暴露读取、设置和处理能力 |
| 流程层 | ReminderProcess、StorageCapacityDetectProcess、DeviceModuleMaintainRemindProcess |
执行检测、判断触发条件、创建并推送提醒 |
| 提醒服务层 | RemindGetter、RemindSetter、RemindHandler |
实现配置查询、配置保存、提醒处理和周期续期 |
| 领域模型层 | ReminderNotice、DeviceModuleMaintainInfo、DeviceModuleMaintainData、StorageCapacityInfo |
表达提醒、模块配置、维护状态和容量配置 |
| 持久化层 | ReminderSQLite、SQLiteBase |
创建 SQLite 数据库及数据表,完成数据查询和写入;不向应用层公开 |
应用层通常只需要使用:
VOCsRemindManager.GetInstance()VOCsRemindManager.GetterVOCsRemindManager.SetterVOCsRemindManager.HandlerReminderProcess.GetInstance().Execute()IMessageReminder
快速开始
1. 实现应用层提醒接口
IMessageReminder 由应用层实现。库产生提醒后,会把 ReminderNotice 传给该接口。
using System;
using System.Threading.Tasks;
using VOCsReminder;
public sealed class AppMessageReminder : IMessageReminder
{
public Task Reminder(ReminderNotice notice)
{
if (notice == null)
{
return Task.CompletedTask;
}
// 替换为应用自己的消息框或消息中心。
Console.WriteLine($"[{notice.ReminderType}] {notice.Message}");
return Task.CompletedTask;
}
}
如果检测流程从后台线程调用,WinForms 或 WPF 应用应在接口实现中自行切换到 UI 线程。
2. 获取管理器并注册提醒实现
VOCsRemindManager manager = VOCsRemindManager
.GetInstance()
.SetReminder(new AppMessageReminder());
SetPusher(IDataPusher) 是预留能力。当前版本的 IDataPusher 为空接口,提醒流程尚未使用,普通应用无需设置。
3. 恢复未处理提醒
应用启动时,在注册 IMessageReminder 后调用一次:
await manager.GetCurrentRemind();
该方法查询数据库中的所有未处理提醒,并重新调用 IMessageReminder。它只恢复已有提醒,不执行新的容量检测或维护到期检测。
推荐初始化顺序:
获取 VOCsRemindManager
↓
注册 IMessageReminder
↓
调用 GetCurrentRemind
↓
启动应用层定时检测
配置磁盘容量提醒
磁盘容量提醒需要同时配置容量信息和模块启用状态。
设置检测目录和容量阈值
bool capacitySaved = await manager.Setter.SetStorageCapacity(
@"D:\VOCsData",
20d);
folder:要监控的目录;实际检测的是该目录所在磁盘分区;minCapacity:最小可用容量,单位为 GB,必须大于0,且不能为NaN或无穷大。
检测时目录必须存在,对应磁盘必须处于可用状态,否则本次检测会跳过。
启用磁盘容量模块
bool reminderSaved = await manager.Setter.SetModuleMaintainInfo(
new DeviceModuleMaintainInfo
{
ModuleToken = EquipmentModuleToken.STORAGE_CAPACITY,
IsEnabled = true,
ReminderValue = 1,
ReminderTimeType = ReminderTimeType.DAY,
Message = "数据盘可用空间不足,请及时清理。"
});
磁盘容量检测不使用 ReminderValue 和 ReminderTimeType 控制检测周期,检测周期完全由应用层调用频率决定。但由于启用配置复用 DeviceModuleMaintainInfo,启用时 ReminderValue 仍须大于 0。
容量判断规则:
可用容量 > MinCapacity 不提醒
可用容量 <= MinCapacity 产生提醒
配置设备模块维护提醒
bool saved = await manager.Setter.SetModuleMaintainInfo(
new DeviceModuleMaintainInfo
{
ModuleToken = EquipmentModuleToken.HYDROGEN_GENERATOR,
IsEnabled = true,
ReminderValue = 30,
ReminderTimeType = ReminderTimeType.DAY,
Message = "氢气发生器已到维护周期。"
});
首次新增并启用配置时,库以当前本地时间为起点计算到期时间。以下情况会重新从当前时间计算到期时间:
- 模块由停用变为启用;
ReminderValue发生变化;ReminderTimeType发生变化;- 模块维护数据不存在。
仅修改 Message 不会重置到期时间。停用模块不会删除配置、维护数据或提醒历史,只会停止该模块的到期检测。
批量设置
bool saved = await manager.Setter.SetModuleMaintainInfo(
new System.Collections.Generic.List<DeviceModuleMaintainInfo>
{
new DeviceModuleMaintainInfo
{
ModuleToken = EquipmentModuleToken.PROBE_FILTER,
IsEnabled = true,
ReminderValue = 1,
ReminderTimeType = ReminderTimeType.MONTH,
Message = "请更换探头过滤器。"
},
new DeviceModuleMaintainInfo
{
ModuleToken = EquipmentModuleToken.AIR_COMPRESSOR,
IsEnabled = true,
ReminderValue = 500,
ReminderTimeType = ReminderTimeType.HOUR,
Message = "请维护空气压缩机。"
}
});
批量设置按列表顺序逐条执行,遇到失败立即返回 false。此前已经成功保存的数据不会回滚。
执行检测
库不包含定时器,应用层应根据业务要求周期性调用:
await ReminderProcess.GetInstance().Execute();
例如应用层每小时调用一次,提醒时间精度也约为一小时。也可以单独执行某个流程:
await StorageCapacityDetectProcess.GetInstance().Execute();
await DeviceModuleMaintainRemindProcess.GetInstance().Execute();
应用层应等待本次 Execute() 完成后再开始下一次调用,避免检测流程重叠执行。
处理提醒
用户完成处理后,应用层使用模块标识通知库:
bool handled = await manager.Handler.Handling(
EquipmentModuleToken.HYDROGEN_GENERATOR,
ProcessStatus.PROCESSED);
调用要求:
token不能为空;status必须为ProcessStatus.PROCESSED;- 对应模块必须存在未处理提醒;
- 对应模块配置必须存在并保持启用状态。
设备维护提醒处理成功后,下一次到期时间以本次处理时间为起点重新计算。磁盘容量提醒处理成功后,如果磁盘空间仍小于或等于阈值,下一次检测会再次产生提醒。
查询配置、状态和历史
StorageCapacityInfo capacity =
await manager.Getter.GetStorageCapacity();
System.Collections.Generic.List<DeviceModuleMaintainInfo> infos =
await manager.Getter.GetModuleMaintainInfo();
System.Collections.Generic.List<DeviceModuleMaintainData> allData =
await manager.Getter.GetModuleMaintainData();
DeviceModuleMaintainData oneData =
await manager.Getter.GetModuleMaintainDataByToken(
EquipmentModuleToken.HYDROGEN_GENERATOR);
System.Collections.Generic.List<ReminderNotice> allNotices =
await manager.Getter.GetRemindStatus();
System.Collections.Generic.List<ReminderNotice> unprocessed =
await manager.Getter.GetRemindStatus(
status: ProcessStatus.UNPROCESSED);
System.Collections.Generic.List<ReminderNotice> history =
await manager.Getter.GetRemindStatus(
start: new DateTime(2026, 1, 1),
end: new DateTime(2027, 1, 1),
type: ReminderType.MODULE_MAINTAIN_EXPIRE,
token: EquipmentModuleToken.HYDROGEN_GENERATOR,
status: ProcessStatus.PROCESSED);
条件查询的时间范围为左闭右开区间:
Time >= start && Time < end
条件查询结果按提醒时间倒序排列。如果同时传入 start 和 end,且 start >= end,方法返回 null。
公开数据模型
| 类型 | 关键属性 | 用途 |
|---|---|---|
DeviceModuleMaintainInfo |
ModuleToken、IsEnabled、ReminderValue、ReminderTimeType、Message |
模块维护配置 |
DeviceModuleMaintainData |
ModuleToken、ExpireTime、UpdateTime |
库维护的模块运行状态 |
StorageCapacityInfo |
Folder、MinCapacity |
磁盘容量配置,阈值单位为 GB |
ReminderNotice |
Time、ReminderType、ModuleToken、ProcessingStatus、ProcessingTime、Message |
应用收到的提醒及历史记录 |
模块标识与枚举
EquipmentModuleToken
| 常量 | 含义 |
|---|---|
STORAGE_CAPACITY |
存储容量,磁盘检测保留标识 |
HYDROGEN_GENERATOR |
氢气发生器 |
ZERO_GAS_GENERATOR |
零气发生器 |
AIR_COMPRESSOR |
空气压缩机 |
PROBE_FILTER |
探头过滤器 |
SECONDARY_FILTER |
二级过滤器 |
DEOXYGENATION_UNIT |
除氧单元 |
ModuleToken 用于关联配置、维护状态和提醒。同一个模块应始终使用相同且唯一的标识。STORAGE_CAPACITY 具有特殊含义,不应分配给其他设备模块。
枚举
| 枚举 | 值 | 含义 |
|---|---|---|
ReminderTimeType |
HOUR / DAY / MONTH |
按小时、天或日历月计算周期 |
ReminderType |
STORAGE_CAPACITY_NOT_ENOUGH |
磁盘容量不足 |
ReminderType |
MODULE_MAINTAIN_EXPIRE |
设备模块维护到期 |
ProcessStatus |
UNPROCESSED / PROCESSED |
未处理 / 已处理 |
SQLite 数据存储
数据库在第一次访问相关功能时自动创建,实际路径为:
{AppContext.BaseDirectory}\File\VOCsReminder\DB\VOCsReminder.db
宿主程序需要对该目录具有读写权限。数据库包含四张表:
| 表名 | 用途 |
|---|---|
RemindStatus |
保存未处理提醒和已处理历史 |
DeviceModuleMaintainInfo |
保存模块启用状态、提醒周期和文案 |
DeviceModuleMaintainData |
保存模块到期时间和更新时间 |
StorageCapacityInfo |
保存检测目录和最小容量阈值 |
时间写入 SQLite 前统一格式化为:
yyyy-MM-dd HH:mm:ss.fff
应用层不应直接修改数据库文件,应通过 Getter、Setter 和 Handler 操作数据。
参数、返回值与失败处理
SetStorageCapacity:目录不能为空;阈值必须大于0,且不能为NaN或无穷大;SetModuleMaintainInfo:模块标识和提醒内容不能为空;时间类型必须有效;启用时周期值必须大于0;- 设置和处理方法返回
true表示成功,返回false表示失败; - 查询无数据或底层操作失败时可能返回
null,应用层应做好空值判断; - 检测流程只有在提醒成功写入数据库后才调用
IMessageReminder; - 未注册
IMessageReminder时,检测流程不会生成新的提醒; IMessageReminder.Reminder(...)返回的Task会被库等待,实现中不应长时间阻塞。
使用注意事项
VOCsRemindManager和三个检测流程均为进程内单例;- 库使用宿主进程的本地时间
DateTime.Now,不进行时区转换; - 库不创建定时器,检测频率和生命周期由应用层管理;
- 同一模块已有未处理提醒时,不会再次创建或推送提醒;
- 应用启动后应先调用
SetReminder(...),再调用一次GetCurrentRemind(); - 用户完成设备维护后必须调用
Handler.Handling(...),否则该模块不会进入下一个维护周期; - 容量不足状态未解除时,磁盘提醒处理后会在下一次检测中再次出现;
- 设置为停用只停止检测,不会删除配置、维护状态和提醒历史;
- 批量设置不是整体事务,调用方应检查返回值;
- 应用层应避免重叠执行总流程和单独流程。
最小完整示例
using System;
using System.Threading.Tasks;
using VOCsReminder;
public sealed class ConsoleReminder : IMessageReminder
{
public Task Reminder(ReminderNotice notice)
{
Console.WriteLine(
$"{notice.Time:yyyy-MM-dd HH:mm:ss} {notice.Message}");
return Task.CompletedTask;
}
}
public static class ReminderBootstrap
{
public static async Task ConfigureAndCheck()
{
VOCsRemindManager manager = VOCsRemindManager
.GetInstance()
.SetReminder(new ConsoleReminder());
// 应用启动时恢复未处理提醒。
await manager.GetCurrentRemind();
await manager.Setter.SetStorageCapacity(@"D:\VOCsData", 20d);
await manager.Setter.SetModuleMaintainInfo(
new DeviceModuleMaintainInfo
{
ModuleToken = EquipmentModuleToken.STORAGE_CAPACITY,
IsEnabled = true,
ReminderValue = 1,
ReminderTimeType = ReminderTimeType.DAY,
Message = "数据盘可用空间不足。"
});
await manager.Setter.SetModuleMaintainInfo(
new DeviceModuleMaintainInfo
{
ModuleToken = EquipmentModuleToken.ZERO_GAS_GENERATOR,
IsEnabled = true,
ReminderValue = 1,
ReminderTimeType = ReminderTimeType.MONTH,
Message = "零气发生器需要维护。"
});
// 实际应用中由应用层定时调用。
await ReminderProcess.GetInstance().Execute();
// 用户确认完成维护后调用:
// await manager.Handler.Handling(
// EquipmentModuleToken.ZERO_GAS_GENERATOR,
// ProcessStatus.PROCESSED);
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- BreezyWuAttribute (>= 1.0.4)
- BreezyWuSTBrainPowerCenter (>= 1.0.40)
- Dapper (>= 2.1.89)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SQLite (>= 2.0.4)
-
.NETStandard 2.0
- BreezyWuAttribute (>= 1.0.4)
- BreezyWuSTBrainPowerCenter (>= 1.0.40)
- Dapper (>= 2.1.89)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SQLite (>= 2.0.4)
-
net10.0
- BreezyWuAttribute (>= 1.0.4)
- BreezyWuSTBrainPowerCenter (>= 1.0.40)
- Dapper (>= 2.1.89)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SQLite (>= 2.0.4)
-
net8.0
- BreezyWuAttribute (>= 1.0.4)
- BreezyWuSTBrainPowerCenter (>= 1.0.40)
- Dapper (>= 2.1.89)
- Newtonsoft.Json (>= 13.0.4)
- System.Data.SQLite (>= 2.0.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
本次更新内容:
1.修复已处理后再次检测会重新报警的问题。
2.修复忽略后依然触发提醒的问题。