140 lines
5.0 KiB
C#
140 lines
5.0 KiB
C#
using System.Text.Json.Serialization;
|
||
|
||
namespace ThingHK;
|
||
|
||
// ===== 数据契约(与 ThingHK_GUIDE.md 第 2.4 节一致,schemaVersion=1) =====
|
||
// 这些类型同时用于:HTTP 响应、SSE 推送、--scan 命令输出。
|
||
// 任何字段变更必须递增 SensorSnapshot.SchemaVersion。
|
||
|
||
/// <summary>
|
||
/// 传感器快照:一次全量采样的标准化输出。
|
||
/// 同时用于 GET /snapshot 响应、GET /stream SSE 事件、--scan 命令输出。
|
||
/// </summary>
|
||
internal sealed class SensorSnapshot
|
||
{
|
||
/// <summary>数据契约版本, breaking 变更时递增</summary>
|
||
public int SchemaVersion { get; set; } = 1;
|
||
|
||
/// <summary>采样时间戳(UTC 毫秒)</summary>
|
||
public long Timestamp { get; set; }
|
||
|
||
/// <summary>从 Kernel 启动到首次产生快照的毫秒数(仅首个快照有意义,后续为 0)</summary>
|
||
public double ColdStartMs { get; set; }
|
||
|
||
/// <summary>Kernel 是否以管理员权限运行</summary>
|
||
public bool IsAdmin { get; set; }
|
||
|
||
/// <summary>当前 Kernel 是否已完成首轮扫描(ready 信号依据)</summary>
|
||
public bool Ready { get; set; }
|
||
|
||
/// <summary>本次快照包含的硬件分组</summary>
|
||
public List<SensorGroup> Groups { get; set; } = new();
|
||
}
|
||
|
||
internal sealed class SensorGroup
|
||
{
|
||
/// <summary>分组标识(hardware type 小写,如 cpu/gpuintel/storage)</summary>
|
||
public string Id { get; set; } = "";
|
||
|
||
/// <summary>分组显示名(如 CPU / GpuIntel)</summary>
|
||
public string Name { get; set; } = "";
|
||
|
||
/// <summary>该分组下的传感器列表</summary>
|
||
public List<SensorEntry> Sensors { get; set; } = new();
|
||
}
|
||
|
||
internal sealed class SensorEntry
|
||
{
|
||
/// <summary>全局唯一 ID:{groupId}/{hwName}/{sensorType}/{sensorName} 小写化</summary>
|
||
public string Id { get; set; } = "";
|
||
|
||
public string Name { get; set; } = "";
|
||
public string Type { get; set; } = "";
|
||
public string HardwareName { get; set; } = "";
|
||
|
||
/// <summary>传感器当前值;null 表示首轮未就绪或硬件不可读</summary>
|
||
public float? Value { get; set; }
|
||
|
||
public string Unit { get; set; } = "";
|
||
}
|
||
|
||
/// <summary>
|
||
/// /status 路由响应:用于冷启动就绪探测(见指南第 3.1 节)。
|
||
/// 前端通过轮询此接口判断是否可请求 /snapshot 或订阅 /stream。
|
||
/// </summary>
|
||
internal sealed class KernelStatus
|
||
{
|
||
public bool Ready { get; set; }
|
||
public bool IsAdmin { get; set; }
|
||
public double UptimeMs { get; set; }
|
||
public int GroupCount { get; set; }
|
||
public int SensorCount { get; set; }
|
||
public List<string> Providers { get; set; } = new();
|
||
public int SchemaVersion { get; set; } = 1;
|
||
}
|
||
|
||
/// <summary>
|
||
/// /config 请求体:运行时调整采样配置。
|
||
/// 字段均可选,仅传递需要变更的字段。
|
||
/// </summary>
|
||
internal sealed class ConfigRequest
|
||
{
|
||
/// <summary>快通道采样间隔(毫秒),0 或负数表示不变</summary>
|
||
public int? FastIntervalMs { get; set; }
|
||
|
||
/// <summary>慢通道采样间隔(毫秒),0 或负数表示不变</summary>
|
||
public int? SlowIntervalMs { get; set; }
|
||
|
||
/// <summary>SSE 推送间隔(毫秒),仅影响后续 stream 订阅,0 或负数表示不变</summary>
|
||
public int? StreamIntervalMs { get; set; }
|
||
}
|
||
|
||
internal sealed class ConfigResponse
|
||
{
|
||
public bool Success { get; set; }
|
||
public int FastIntervalMs { get; set; }
|
||
public int SlowIntervalMs { get; set; }
|
||
public int StreamIntervalMs { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根路由健康检查响应。
|
||
/// </summary>
|
||
internal sealed class HealthResponse
|
||
{
|
||
public bool Ok { get; set; } = true;
|
||
public string Name { get; set; } = "ThingHK";
|
||
public string Version { get; set; } = "0.2.0";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 错误响应:AOT 下所有 BadRequest/NotFound 必须用强类型,不能用匿名对象。
|
||
/// </summary>
|
||
internal sealed class ErrorResponse
|
||
{
|
||
public ErrorResponse(string error, string message) { Error = error; Message = message; }
|
||
public string Error { get; set; }
|
||
public string Message { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// JSON 源生成上下文:消除 Native AOT 下反射式序列化的 IL3050/IL2026 警告。
|
||
/// 所有 HTTP 响应类型必须在此注册,否则 AOT 下序列化会抛异常。
|
||
/// </summary>
|
||
[JsonSourceGenerationOptions(
|
||
WriteIndented = false,
|
||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
|
||
[JsonSerializable(typeof(SensorSnapshot))]
|
||
[JsonSerializable(typeof(KernelStatus))]
|
||
[JsonSerializable(typeof(ConfigRequest))]
|
||
[JsonSerializable(typeof(ConfigResponse))]
|
||
[JsonSerializable(typeof(ConfigRequest[]))]
|
||
[JsonSerializable(typeof(HealthResponse))]
|
||
[JsonSerializable(typeof(ErrorResponse))]
|
||
[JsonSerializable(typeof(HardwareConfig))]
|
||
[JsonSerializable(typeof(HardwareConfigResponse))]
|
||
[JsonSerializable(typeof(HardwareConfigUpdateResponse))]
|
||
[JsonSerializable(typeof(HardwareConfigUpdateRequest))]
|
||
internal sealed partial class ThingHKJsonContext : JsonSerializerContext;
|