166 lines
6.0 KiB
C#
166 lines
6.0 KiB
C#
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Text.Json;
|
||
using System.Text.Json.Serialization;
|
||
|
||
namespace ThingHK;
|
||
|
||
/// <summary>
|
||
/// 硬件监控配置:控制启用哪些硬件分组 + 过滤哪些传感器类型。
|
||
///
|
||
/// 设计要点:
|
||
/// - 硬件开关影响 Computer.IsXxxEnabled,需重启 Kernel 才生效(LHB 在 Open 时决定枚举范围)
|
||
/// - 传感器类型过滤在 BuildSnapshot 时生效,可热更新(无需重启)
|
||
/// - 默认配置仅覆盖概览页需要的指标:CPU/GPU/Memory/Storage + temp/load/power/clock/data
|
||
/// - 配置文件由 Tauri 通过 --config 参数传递路径,Kernel 负责加载/保存
|
||
/// </summary>
|
||
internal sealed class HardwareConfig
|
||
{
|
||
/// <summary>硬件分组开关,key 为 HardwareConfigKey(cpu/gpu/memory/storage/...)</summary>
|
||
public Dictionary<string, bool> Hardware { get; set; } = new();
|
||
|
||
/// <summary>传感器类型开关,key 为 SensorType 小写(temperature/load/power/...)</summary>
|
||
public Dictionary<string, bool> SensorTypes { get; set; } = new();
|
||
|
||
/// <summary>默认配置:仅覆盖概览页需要的指标,最小化性能开销</summary>
|
||
public static HardwareConfig Default => new()
|
||
{
|
||
Hardware = new Dictionary<string, bool>
|
||
{
|
||
["cpu"] = true,
|
||
["gpu"] = true,
|
||
["memory"] = true,
|
||
["storage"] = true,
|
||
["motherboard"] = false,
|
||
["controller"] = false,
|
||
["battery"] = false,
|
||
["network"] = false,
|
||
["psu"] = false,
|
||
},
|
||
SensorTypes = new Dictionary<string, bool>
|
||
{
|
||
["temperature"] = true,
|
||
["load"] = true,
|
||
["power"] = true,
|
||
["clock"] = true,
|
||
["voltage"] = false,
|
||
["fan"] = false,
|
||
["data"] = true,
|
||
["smalldata"] = false,
|
||
["throughput"] = false,
|
||
["level"] = false,
|
||
["control"] = false,
|
||
["factor"] = false,
|
||
["frequency"] = false,
|
||
["timespan"] = false,
|
||
["energy"] = false,
|
||
["noise"] = false,
|
||
["conductivity"] = false,
|
||
["humidity"] = false,
|
||
["flow"] = false,
|
||
},
|
||
};
|
||
|
||
/// <summary>从文件加载配置,文件不存在或解析失败时返回默认配置</summary>
|
||
public static HardwareConfig Load(string? path)
|
||
{
|
||
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
||
return Default;
|
||
|
||
try
|
||
{
|
||
var json = File.ReadAllText(path);
|
||
var cfg = JsonSerializer.Deserialize(json, ThingHKJsonContext.Default.HardwareConfig);
|
||
if (cfg == null) return Default;
|
||
|
||
// 合并默认值:确保新增的硬件/传感器类型有默认值
|
||
MergeWithDefaults(cfg);
|
||
return cfg;
|
||
}
|
||
catch
|
||
{
|
||
return Default;
|
||
}
|
||
}
|
||
|
||
/// <summary>保存配置到文件</summary>
|
||
public void Save(string path)
|
||
{
|
||
var dir = Path.GetDirectoryName(path);
|
||
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
|
||
var json = JsonSerializer.Serialize(this, ThingHKJsonContext.Default.HardwareConfig);
|
||
File.WriteAllText(path, json);
|
||
}
|
||
|
||
/// <summary>检查指定传感器类型是否启用</summary>
|
||
public bool IsSensorTypeEnabled(string sensorTypeLower)
|
||
=> SensorTypes.TryGetValue(sensorTypeLower, out var enabled) ? enabled : false;
|
||
|
||
/// <summary>检查指定硬件分组是否启用</summary>
|
||
public bool IsHardwareEnabled(string key)
|
||
=> Hardware.TryGetValue(key, out var enabled) ? enabled : false;
|
||
|
||
/// <summary>合并默认值:确保配置文件缺少的新增项有默认值</summary>
|
||
private static void MergeWithDefaults(HardwareConfig cfg)
|
||
{
|
||
var def = Default;
|
||
foreach (var (k, v) in def.Hardware)
|
||
if (!cfg.Hardware.ContainsKey(k)) cfg.Hardware[k] = v;
|
||
foreach (var (k, v) in def.SensorTypes)
|
||
if (!cfg.SensorTypes.ContainsKey(k)) cfg.SensorTypes[k] = v;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// /config/hardware GET 响应:返回当前配置 + 可用硬件/传感器类型清单。
|
||
/// 前端用此数据渲染配置 Dialog。
|
||
/// </summary>
|
||
internal sealed class HardwareConfigResponse
|
||
{
|
||
public HardwareConfig Config { get; set; } = new();
|
||
public List<HardwareTypeInfo> AvailableHardware { get; set; } = new();
|
||
public List<SensorTypeInfo> AvailableSensorTypes { get; set; } = new();
|
||
}
|
||
|
||
/// <summary>硬件分组元信息</summary>
|
||
internal sealed class HardwareTypeInfo
|
||
{
|
||
/// <summary>配置 key(cpu/gpu/memory/...)</summary>
|
||
public string Key { get; set; } = "";
|
||
/// <summary>显示名</summary>
|
||
public string Name { get; set; } = "";
|
||
/// <summary>是否已启用</summary>
|
||
public bool Enabled { get; set; }
|
||
/// <summary>是否需要管理员权限才能读取完整数据</summary>
|
||
public bool RequiresAdmin { get; set; }
|
||
}
|
||
|
||
/// <summary>传感器类型元信息</summary>
|
||
internal sealed class SensorTypeInfo
|
||
{
|
||
/// <summary>配置 key(temperature/load/...)</summary>
|
||
public string Key { get; set; } = "";
|
||
/// <summary>显示名</summary>
|
||
public string Name { get; set; } = "";
|
||
/// <summary>是否已启用</summary>
|
||
public bool Enabled { get; set; }
|
||
}
|
||
|
||
/// <summary>/config/hardware POST 响应</summary>
|
||
internal sealed class HardwareConfigUpdateResponse
|
||
{
|
||
public bool Success { get; set; }
|
||
/// <summary>硬件开关是否变化(需重启 Kernel 才生效)</summary>
|
||
public bool RestartRequired { get; set; }
|
||
public string? ConfigPath { get; set; }
|
||
}
|
||
|
||
/// <summary>/config/hardware POST 请求体</summary>
|
||
internal sealed class HardwareConfigUpdateRequest
|
||
{
|
||
/// <summary>硬件开关(可选,仅传需要变更的字段)</summary>
|
||
public Dictionary<string, bool>? Hardware { get; set; }
|
||
/// <summary>传感器类型开关(可选,仅传需要变更的字段)</summary>
|
||
public Dictionary<string, bool>? SensorTypes { get; set; }
|
||
}
|