diff --git a/2jciebu.cs b/2jciebu.cs index a820afe..2a1f313 100644 --- a/2jciebu.cs +++ b/2jciebu.cs @@ -1,32 +1,116 @@ namespace SensorReadings; +/// +/// 表示 OMRON 2JCIE-BU 传感器的单条读数。 +/// internal sealed class Jciebu2 { + /// + /// 采样时间戳(字符串格式)。 + /// public string Ts { get; set; } = string.Empty; + /// + /// 采样位置或设备位置标识。 + /// public string Location { get; set; } = string.Empty; + /// + /// 温度(摄氏度)。 + /// public double TemperatureC { get; set; } + /// + /// 相对湿度(%RH)。 + /// public double HumidityRh { get; set; } + /// + /// 环境光照度。 + /// public double AmbientLight { get; set; } + /// + /// 气压(hPa)。 + /// public double PressureHpa { get; set; } + /// + /// 噪声(dB)。 + /// public double NoiseDb { get; set; } + /// + /// 总挥发性有机物(eTVOC,ppb)。 + /// public double EtvocPpb { get; set; } + /// + /// 等效二氧化碳浓度(eCO2,ppm)。 + /// public double Eco2Ppm { get; set; } + /// + /// 舒适度指数。 + /// public double DiscomfortIndex { get; set; } + /// + /// 中暑指数。 + /// public double HeatstrokeIndex { get; set; } + /// + /// 振动信息(设备原始标记值)。 + /// public int VibrationInfo { get; set; } + /// + /// 振动 SI 值。 + /// public double SiValue { get; set; } + /// + /// 峰值加速度(PGA,gal)。 + /// public double PgaGal { get; set; } + /// + /// 地震烈度(计算值)。 + /// public double SeismicIntensity { get; set; } + /// + /// 温度告警标记。 + /// public int TemperatureFlag { get; set; } + /// + /// 湿度告警标记。 + /// public int HumidityFlag { get; set; } + /// + /// 光照告警标记。 + /// public int AmbientLightFlag { get; set; } + /// + /// 气压告警标记。 + /// public int PressureFlag { get; set; } + /// + /// 噪声告警标记。 + /// public int NoiseFlag { get; set; } + /// + /// eTVOC 告警标记。 + /// public int EtvocFlag { get; set; } + /// + /// eCO2 告警标记。 + /// public int Eco2Flag { get; set; } + /// + /// 舒适度告警标记。 + /// public int DiscomfortFlag { get; set; } + /// + /// 中暑告警标记。 + /// public int HeatstrokeFlag { get; set; } + /// + /// SI 告警标记。 + /// public int SiFlag { get; set; } + /// + /// PGA 告警标记。 + /// public int PgaFlag { get; set; } + /// + /// 地震烈度告警标记。 + /// public int SeismicIntensityFlag { get; set; } } diff --git a/Program.cs b/Program.cs index a2f0e52..8219e09 100644 --- a/Program.cs +++ b/Program.cs @@ -17,6 +17,11 @@ private static readonly string ODataToken = GetEnv("ODATA_TOKEN", string.Empty).Trim(); private static readonly double TimeoutSeconds = GetEnvDouble("ODATA_TIMEOUT_S", 10); + /// + /// 程序入口,读取最新传感器数据并可选上报到 OData。 + /// + /// 命令行参数。 + /// 进程退出码。 private static int Main(string[] args) { try @@ -47,6 +52,11 @@ } } + /// + /// 将传感器数据发送到配置的 OData 端点。 + /// + /// 要发送的传感器数据。 + /// HTTP 状态码与响应内容。 private static async Task<(int StatusCode, string Body)> PostODataAsync(Jciebu2 payload) { using var client = new HttpClient @@ -69,6 +79,13 @@ return ((int)resp.StatusCode, body); } + /// + /// 从串口设备读取最新数据,并统一时间戳与位置字段。 + /// + /// 串口设备路径。 + /// 位置标识,若为空则使用默认值。 + /// 是否开启读数时的指示灯。 + /// 解析后的传感器数据。 private static Jciebu2 GetLatestReading(string port, string? location, bool led) { using var serial = new SerialPort(port, 115200, Parity.None, 8, StopBits.One) @@ -138,6 +155,11 @@ } } + /// + /// 将指令附加 CRC 后写入串口。 + /// + /// 串口实例。 + /// 原始指令字节。 private static void WriteWithCrc(SerialPort serial, byte[] command) { var crc = CalcCrc(command); @@ -147,6 +169,12 @@ serial.Write(buf, 0, buf.Length); } + /// + /// 从串口读取可用字节,直到缓冲不再增长或超时。 + /// + /// 串口实例。 + /// 读取超时时间。 + /// 读取到的字节数组。 private static byte[] ReadAvailable(SerialPort serial, TimeSpan timeout) { var deadline = DateTime.UtcNow + timeout; @@ -178,6 +206,11 @@ return buffer.ToArray(); } + /// + /// 解析“latest data long”响应为传感器数据。 + /// + /// 设备返回的原始数据。 + /// 解析后的传感器数据。 private static Jciebu2 ParseLatestDataLong(byte[] data) { if (data.Length < 56) @@ -215,6 +248,11 @@ }; } + /// + /// 计算给定缓冲区的 CRC-16(Modbus)。 + /// + /// 输入缓冲区。 + /// CRC 字节(低位在前)。 private static byte[] CalcCrc(byte[] buf) { var crc = 0xFFFF; @@ -237,24 +275,54 @@ return new[] { crcL, crcH }; } + /// + /// 从缓冲区读取无符号 16 位小端值。 + /// + /// 数据缓冲区。 + /// 起始偏移。 + /// 读取到的数值。 private static ushort U16Le(byte[] data, int offset) => (ushort)(data[offset] | (data[offset + 1] << 8)); + /// + /// 从缓冲区读取有符号 16 位小端值。 + /// + /// 数据缓冲区。 + /// 起始偏移。 + /// 读取到的数值。 private static short S16Le(byte[] data, int offset) => (short)(data[offset] | (data[offset + 1] << 8)); + /// + /// 从缓冲区读取无符号 32 位小端值。 + /// + /// 数据缓冲区。 + /// 起始偏移。 + /// 读取到的数值。 private static uint U32Le(byte[] data, int offset) => (uint)(data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)); + /// + /// 读取环境变量,未设置或为空时返回默认值。 + /// + /// 环境变量名。 + /// 默认值。 + /// 环境变量值或默认值。 private static string GetEnv(string name, string defaultValue) { var value = Environment.GetEnvironmentVariable(name); return string.IsNullOrEmpty(value) ? defaultValue : value; } + /// + /// 读取环境变量为 double(InvariantCulture),失败则返回默认值。 + /// + /// 环境变量名。 + /// 默认值。 + /// 解析结果或默认值。 private static double GetEnvDouble(string name, double defaultValue) { var value = Environment.GetEnvironmentVariable(name); @@ -263,6 +331,12 @@ : defaultValue; } + /// + /// 判断参数列表中是否包含指定开关。 + /// + /// 命令行参数。 + /// 要查找的参数名。 + /// 存在则为 true。 private static bool HasArg(string[] args, string name) { foreach (var arg in args)