using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; using LitJson; /// /// 报警记录持久化数据模型 /// [Serializable] public class AlarmRecordData { public int Id; public int Priority; // AlarmPriority枚举值 public string Reason; public string Time; // DateTime序列化为字符串 public string AlarmCode; // 报警代码,用于去重 public bool IsTriggered; // true=报警触发, false=报警解除 public AlarmRecordData() { } public AlarmRecordData(AlarmEvent alarmEvent, byte alarmCode, bool isTriggered) { Id = alarmEvent.Id; Priority = (int)alarmEvent.Priority; Reason = alarmEvent.Reason; Time = alarmEvent.Time.ToString("yyyy-MM-dd HH:mm:ss"); AlarmCode = $"0x{alarmCode:X2}"; IsTriggered = isTriggered; } public AlarmEvent ToAlarmEvent() { return new AlarmEvent { Id = Id, Priority = (AlarmPriority)Priority, Reason = Reason, Time = DateTime.TryParse(Time, out var dt) ? dt : DateTime.Now }; } } /// /// 报警记录存储容器 /// [Serializable] public class AlarmRecordStorage { public List Records = new List(); public int NextId = 1; } /// /// 报警记录持久化服务 /// 负责报警记录的保存、加载和去重 /// public class AlarmRecordPersistenceService { private readonly string _alarmRecordsPath; private const int MAX_ALARM_RECORDS = 1000; // 最大记录数 private AlarmRecordStorage _storage; // 去重窗口时间(秒)- 同一报警在此时间内不重复记录 private const int DEDUPLICATION_WINDOW_SECONDS = 60; public AlarmRecordPersistenceService() { var dataPath = Application.persistentDataPath; _alarmRecordsPath = Path.Combine(dataPath, "alarm_records.json"); LoadFromFile(); } /// /// 添加报警记录(带去重) /// /// 报警事件 /// 报警代码 /// true=报警触发, false=报警解除 public void AddRecord(AlarmEvent alarmEvent, byte alarmCode, bool isTriggered) { if (_storage == null) { _storage = new AlarmRecordStorage(); } // 检查是否为重复记录 if (IsDuplicateRecord(alarmCode, alarmEvent.Reason, alarmEvent.Time, isTriggered)) { string statusStr = isTriggered ? "触发" : "解除"; Debug.Log($"[报警记录持久化] 跳过重复记录: {alarmEvent.Reason} (代码: 0x{alarmCode:X2}, 状态: {statusStr})"); return; } // 创建新记录 var recordData = new AlarmRecordData(alarmEvent, alarmCode, isTriggered); recordData.Id = _storage.NextId++; _storage.Records.Add(recordData); // 保持记录数量在限制范围内 if (_storage.Records.Count > MAX_ALARM_RECORDS) { _storage.Records.RemoveAt(0); // 移除最旧的记录 } // 保存到文件 SaveToFile(); string statusText = isTriggered ? "触发" : "解除"; Debug.Log($"[报警记录持久化] 添加记录: ID={recordData.Id}, {alarmEvent.Priority}, {alarmEvent.Reason} [{statusText}]"); } /// /// 检查是否为重复记录 /// 同一报警代码、同一状态在指定时间窗口内不重复记录 /// private bool IsDuplicateRecord(byte alarmCode, string reason, DateTime time, bool isTriggered) { if (_storage?.Records == null || _storage.Records.Count == 0) return false; string codeStr = $"0x{alarmCode:X2}"; var record = _storage.Records[ _storage.Records.Count - 1]; if (record.AlarmCode == codeStr && record.Reason == reason && record.IsTriggered == isTriggered) { if (DateTime.TryParse(record.Time, out var recordTime)) { var timeDiff = (time - recordTime).TotalSeconds; if (timeDiff < DEDUPLICATION_WINDOW_SECONDS) { return true; } } } // 从最新记录开始检查 // for (int i = _storage.Records.Count - 1; i >= 0; i--) // { // var record = _storage.Records[i]; // // 检查报警代码、原因和状态是否相同 // if (record.AlarmCode == codeStr && record.Reason == reason && record.IsTriggered == isTriggered) // { // // 检查时间差 // if (DateTime.TryParse(record.Time, out var recordTime)) // { // var timeDiff = (time - recordTime).TotalSeconds; // // 如果在去重窗口内,认为是重复记录 // if (timeDiff < DEDUPLICATION_WINDOW_SECONDS) // { // return true; // } // // 如果已经超过窗口时间,后面的记录更早,可以停止检查 // if (timeDiff > DEDUPLICATION_WINDOW_SECONDS * 2) // { // break; // } // } // } // } return false; } /// /// 获取报警记录列表 /// public List GetRecords(int maxCount = 1000) { if (_storage?.Records == null || _storage.Records.Count == 0) return new List(); var count = Math.Min(maxCount, _storage.Records.Count); return _storage.Records .Skip(_storage.Records.Count - count) .Select(r => r.ToAlarmEvent()) .ToList(); } /// /// 获取所有报警记录 /// public List GetAllRecords() { if (_storage?.Records == null || _storage.Records.Count == 0) return new List(); return _storage.Records.Select(r => r.ToAlarmEvent()).ToList(); } /// /// 清除所有报警记录 /// public void ClearRecords() { int clearedCount = _storage?.Records?.Count ?? 0; _storage = new AlarmRecordStorage(); _storage.NextId = 1; SaveToFile(); Debug.Log($"[报警记录持久化] 已清除 {clearedCount} 条记录"); } /// /// 获取报警记录总数 /// public int GetRecordCount() { return _storage?.Records?.Count ?? 0; } /// /// 保存到文件 /// private void SaveToFile() { try { var json = JsonMapper.ToJson(_storage); File.WriteAllText(_alarmRecordsPath, json); #if UNITY_ANDROID && !UNITY_EDITOR AndroidFileLogger.Instance?.LogInfo("AlarmRecord", $"报警记录已保存: {_storage.Records.Count} 条"); #endif } catch (Exception ex) { Debug.LogError($"[报警记录持久化] 保存失败: {ex.Message}"); #if UNITY_ANDROID && !UNITY_EDITOR AndroidFileLogger.Instance?.LogError("AlarmRecord", $"保存失败: {ex.Message}"); #endif } } /// /// 从文件加载 /// private void LoadFromFile() { try { if (File.Exists(_alarmRecordsPath)) { var json = File.ReadAllText(_alarmRecordsPath); _storage = JsonMapper.ToObject(json); Debug.Log($"[报警记录持久化] 加载成功: {_storage.Records.Count} 条记录"); #if UNITY_ANDROID && !UNITY_EDITOR AndroidFileLogger.Instance?.LogInfo("AlarmRecord", $"加载成功: {_storage.Records.Count} 条记录"); #endif } else { _storage = new AlarmRecordStorage(); Debug.Log("[报警记录持久化] 首次启动,创建新存储"); } } catch (Exception ex) { Debug.LogError($"[报警记录持久化] 加载失败: {ex.Message}"); _storage = new AlarmRecordStorage(); #if UNITY_ANDROID && !UNITY_EDITOR AndroidFileLogger.Instance?.LogError("AlarmRecord", $"加载失败: {ex.Message}"); #endif } } /// /// 获取存储文件路径(用于调试) /// public string GetStoragePath() { return _alarmRecordsPath; } }