using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using MoviconHub.App.Models; using NLog; namespace MoviconHub.App.Services { /// /// Db Server /// public class DBServices : IDisposable { private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private Timer _dataPollingTimer; private readonly object _lockObject = new object(); private bool _isRunning = false; private int _pollingInterval = 1000; // 默认轮询间隔1秒 private WebSocketData _realtimeData; private CancellationTokenSource _cancellationTokenSource; /// /// 实时数据对象,用于缓存从RTVar表中读取的数据 /// public WebSocketData RealtimeData { get { return _realtimeData; } } public SglModel SglModel { get; } /// /// 实时数据更新事件 /// public event EventHandler DataUpdated; /// /// 初始化数据库服务 /// public DBServices(SglModel sglModel) { _realtimeData = new WebSocketData(); _cancellationTokenSource = new CancellationTokenSource(); SglModel = sglModel; } /// /// 开始实时数据轮询 /// /// 轮询间隔,单位毫秒 /// 是否成功启动 public bool StartPolling(int interval = 2000) { if (_isRunning) return false; lock (_lockObject) { if (_isRunning) return false; _pollingInterval = interval; _isRunning = true; _cancellationTokenSource = new CancellationTokenSource(); // 使用Task来轮询数据 Task.Run(async () => await PollDataAsync(_cancellationTokenSource.Token), _cancellationTokenSource.Token); Logger.Info($"实时数据轮询已启动,间隔: {_pollingInterval}ms"); return true; } } /// /// 停止实时数据轮询 /// public void StopPolling() { if (!_isRunning) return; lock (_lockObject) { if (!_isRunning) return; _cancellationTokenSource.Cancel(); _isRunning = false; Logger.Info("实时数据轮询已停止"); } } /// /// 异步轮询数据任务 /// /// 取消标记 private async Task PollDataAsync(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { // 读取RTVar表数据 await ReadRTVarDataAsync(); // 等待指定的轮询间隔 await Task.Delay(_pollingInterval, cancellationToken); } catch (TaskCanceledException) { // 任务被取消,正常退出 break; } catch (Exception ex) { Logger.Error($"实时数据轮询时发生错误: {ex.Message}"); // 发生错误时,等待一段时间后重试 await Task.Delay(5000, cancellationToken); } } } /// /// 异步读取RTVar表数据 /// private async Task ReadRTVarDataAsync() { try { // 使用FSqlContext封装的FreeSql调用DB数据 var rtVars = await FSqlContext.FDb.Select().ToListAsync(); // 更新实时数据对象 UpdateWebSocketData(rtVars); // 触发数据更新事件 //DataUpdated?.Invoke(this, _realtimeData); } catch (Exception ex) { Logger.Error($"读取RTVar数据时发生错误: {ex.StackTrace}"); throw; } } /// /// 使用RTVar数据更新WebSocketData模型 /// /// RTVar数据列表 private void UpdateWebSocketData(List rtVars) { try { if (rtVars == null || rtVars.Count == 0) return; lock (_lockObject) { // 更新设备状态信息 var deviceCodeVar = rtVars.FirstOrDefault(v => v.Name == "Device_Code"); if (deviceCodeVar != null) _realtimeData.Device_Code = deviceCodeVar.Val; var deviceNameVar = rtVars.FirstOrDefault(v => v.Name == "Device_Name"); if (deviceNameVar != null) _realtimeData.Device_Name = deviceNameVar.Val; var deviceManufacturerVar = rtVars.FirstOrDefault(v => v.Name == "Device_Manufacturer"); if (deviceManufacturerVar != null) _realtimeData.Device_Manufacturer = deviceManufacturerVar.Val; var statusVar = rtVars.FirstOrDefault(v => v.Name == "Device_Status"); if (statusVar != null) _realtimeData.Device_Status = statusVar.Val; // 解析故障信息 UpdateFaultDetails(rtVars); // 解析组件信息 UpdateComponentsInfo(rtVars); // 解析测试数据 UpdateTestData(rtVars); //获取条码信息,确定是否需要搜索数据 SglModel.CodeReady = rtVars.FirstOrDefault(v => v.Name == "part_qrid").Val; UpdateRemoteDb(RealtimeData); //把最新的数据赋值给WebSocketClient中 WebSocketClientHelper.CurWebSocketData = RealtimeData; //更新数据到远程数据库 // 记录日志 //Logger.Debug("实时数据已更新"); } } catch (Exception ex) { Logger.Error($"UpdateWebSocketData: {ex.StackTrace}"); } } /// /// 更新远程数据库 /// /// private void UpdateRemoteDb(WebSocketData webSocketData) { try { // 获取组件信息 var component = webSocketData.ListComponentsInfo?.FirstOrDefault(); // 创建CurRunClearState对象并映射数据 var curRunClearState = new CurRunClearState() { //只有一个,更新数据 Id = 1, // 基本信息 DeviceCode = webSocketData.Device_Code, DeviceName = webSocketData.Device_Name, // 组件信息 part_qrid = component?.part_qrid, part_num = component?.part_num, part_position = component?.part_position, component_name = component?.part_name, vehicle_model = component?.part_Vehicle_model, locomotive_number = component?.part_locomotive_number, repair_process = component?.part_repair_process, program_process = webSocketData.TestData.Test_FrameworkProgramProcess, // 程序进程 Test_FrameworkProgramProcess = webSocketData.TestData.Test_FrameworkProgramProcess, Test_FrameworkProgramProcessPercentage = webSocketData.TestData.Test_FrameworkProgramProcessPercentage, // 设备状态 Test_PartsEquipmentStatus = webSocketData.TestData.Test_PartsEquipmentStatus, // 清洗时长和用量 Test_FrameworkPerModelCleaningDuration = webSocketData.TestData.Test_FrameworkPerModelCleaningDuration, Test_FrameworkPerModelCleaningAgentUsage = webSocketData.TestData.Test_FrameworkPerModelCleaningAgentUsage, Test_FrameworkPerModelWaterUsage = webSocketData.TestData.Test_FrameworkPerModelWaterUsage, // 水箱和清洗剂罐信息 WaterTank_Temp = webSocketData.TestData.Test_WaterTankTemperature, AgentTank_Temp = webSocketData.TestData.Test_CleaningAgentTankTemperature, WaterTank_Level = webSocketData.TestData.Test_WaterTankLevel, AgentTank_Level = webSocketData.TestData.Test_CleaningAgentTankLevel, // 浸泡池温度 SoakingTank1_Temp = webSocketData.TestData.Test_SoakingTank1Temperature, SoakingTank2_Temp = webSocketData.TestData.Test_SoakingTank2Temperature, // 运行模式 Test_WaterTankHeat = webSocketData.TestData.Test_WaterTankHeat, Test_WaterTankAdd = webSocketData.TestData.Test_WaterTankAdd, Test_CleaningAgentTankHeat = webSocketData.TestData.Test_CleaningAgentTankHeat, Test_CleaningAgentTankAdd = webSocketData.TestData.Test_CleaningAgentTankAdd, // 监控信息 Test_ElectricSurveillance = webSocketData.TestData.Test_ElectricSurveillance, Test_SteamSurveillance = webSocketData.TestData.Test_SteamSurveillance }; var Data = FRemoteSqlContext.FDb .InsertOrUpdate() .SetSource(curRunClearState) .ExecuteAffrows(); if (Data > 0) { Logger.Debug("实时数据已更新到远程数据库"); } } catch (Exception ex) { Logger.Error($"UpdateRemoteDb: {ex.StackTrace}"); } } /// /// 更新故障信息 /// /// RTVar数据列表 private void UpdateFaultDetails(List rtVars) { var hasFault = rtVars.FirstOrDefault(v => v.Name.Contains("Fault_")); if (hasFault != null && !string.IsNullOrEmpty(hasFault.Val)) { if (_realtimeData.FaultDetails == null) _realtimeData.FaultDetails = new FaultDetails(); var faultDevice = rtVars.FirstOrDefault(v => v.Name == "Fault_Code"); if (faultDevice != null) _realtimeData.FaultDetails.Fault_Code = faultDevice.Val; var faultTime = rtVars.FirstOrDefault(v => v.Name == "Fault_Time"); if (faultTime != null && DateTime.TryParse(faultTime.Val, out DateTime time)) _realtimeData.FaultDetails.Fault_Time = time; var faultDescription = rtVars.FirstOrDefault(v => v.Name == "Fault_Description"); if (faultDescription != null) _realtimeData.FaultDetails.Fault_Description = faultDescription.Val; } else { // 没有故障时,置空故障信息 _realtimeData.FaultDetails = null; } } /// /// 更新组件信息 /// /// RTVar数据列表 private void UpdateComponentsInfo(List rtVars) { var componentsCountVar = rtVars.FirstOrDefault(v => v.Name.Contains("part_")); if (componentsCountVar != null) { if (_realtimeData.ListComponentsInfo == null) _realtimeData.ListComponentsInfo = new List() { new ComponentsInfo() }; //else // _realtimeData.ListComponentsInfo.Clear(); var component = _realtimeData.ListComponentsInfo.FirstOrDefault(); //var partQRCode = rtVars.FirstOrDefault(v => v.Name == $"part_qrid"); //if (partQRCode != null) // component.part_qrid = partQRCode.Val; var partNum = rtVars.FirstOrDefault(v => v.Name == $"part_num"); if (partNum != null) component.part_num = partNum.Val; var partPosition = rtVars.FirstOrDefault(v => v.Name == $"part_position"); if (partPosition != null) component.part_position = partPosition.Val; var componentName = rtVars.FirstOrDefault(v => v.Name == $"part_name"); if (componentName != null) component.part_name = componentName.Val; // 车型 var vehicleModel = rtVars.FirstOrDefault(v => v.Name == $"part_Vehicle_model"); if (vehicleModel != null) component.part_Vehicle_model = vehicleModel.Val; // 车号 var locomotiveNumber = rtVars.FirstOrDefault(v => v.Name == $"part_locomotive_number"); if (locomotiveNumber != null) component.part_locomotive_number = locomotiveNumber.Val; // 修程 var repairProcess = rtVars.FirstOrDefault(v => v.Name == $"part_repair_process"); if (repairProcess != null) component.part_repair_process = repairProcess.Val; // Id var part_qrid = rtVars.FirstOrDefault(v => v.Name == $"part_qrid"); if (part_qrid != null) component.part_qrid = part_qrid.Val; } else { // 没有组件信息时,初始化空列表 if (_realtimeData.ListComponentsInfo == null) _realtimeData.ListComponentsInfo = new List() { new ComponentsInfo() }; //else // _realtimeData.ListComponentsInfo.Clear(); } } ///// ///// 更新组件信息 ///// ///// RTVar数据列表 //private void UpdateComponentsInfoMulit(List rtVars) //{ // var componentsCountVar = rtVars.FirstOrDefault(v => v.Name == "ComponentsCount"); // if (componentsCountVar != null && int.TryParse(componentsCountVar.Val, out int count) && count > 0) // { // if (_realtimeData.ListComponentsInfo == null) // _realtimeData.ListComponentsInfo = new List(); // else // _realtimeData.ListComponentsInfo.Clear(); // // 解析多个组件信息 // for (int i = 0; i < count; i++) // { // var component = new ComponentsInfo(); // var partQRCode = rtVars.FirstOrDefault(v => v.Name == $"Component_{i}_PartQRCode"); // if (partQRCode != null) // component.part_qrid = partQRCode.Val; // var partNum = rtVars.FirstOrDefault(v => v.Name == $"Component_{i}_PartNum"); // if (partNum != null) // component.part_num = partNum.Val; // var partPosition = rtVars.FirstOrDefault(v => v.Name == $"Component_{i}_PartPosition"); // if (partPosition != null && int.TryParse(partPosition.Val, out int position)) // component.part_position = position; // var componentName = rtVars.FirstOrDefault(v => v.Name == $"Component_{i}_ComponentName"); // if (componentName != null) // component.component_name = componentName.Val; // // 车型 // var vehicleModel = rtVars.FirstOrDefault(v => v.Name == $"Component_{i}_VehicleModel"); // if (vehicleModel != null) // component.Vehicle_model = vehicleModel.Val; // // 车号 // var locomotiveNumber = rtVars.FirstOrDefault(v => v.Name == $"Component_{i}_LocomotiveNumber"); // if (locomotiveNumber != null) // component.locomotive_number = locomotiveNumber.Val; // // 修程 // var repairProcess = rtVars.FirstOrDefault(v => v.Name == $"Component_{i}_RepairProcess"); // if (repairProcess != null) // component.repair_process = repairProcess.Val; // // 添加到列表 // _realtimeData.ListComponentsInfo.Add(component); // } // } // else // { // // 没有组件信息时,初始化空列表 // if (_realtimeData.ListComponentsInfo == null) // _realtimeData.ListComponentsInfo = new List(); // else // _realtimeData.ListComponentsInfo.Clear(); // } //} /// /// 更新测试数据 /// /// RTVar数据列表 private void UpdateTestData(List rtVars) { var hasTestData = rtVars.FirstOrDefault(v => v.Name.Contains("Test_")); if (hasTestData != null && !string.IsNullOrEmpty(hasTestData.Val)) { if (_realtimeData.TestData == null) _realtimeData.TestData = new TestData(); // 从RTVar中提取测试数据 var testItems = rtVars.Where(v => v.Name.StartsWith("Test_")).ToList(); foreach (var item in testItems) { // 根据命名规则解析测试数据项 string itemName = item.Name; // 使用反射设置属性 var property = typeof(TestData).GetProperty(itemName); if (property != null && property.CanWrite) { if (property.PropertyType == typeof(string)) { property.SetValue(_realtimeData.TestData, item.Val); } else if (property.PropertyType == typeof(int) && int.TryParse(item.Val, out int intValue)) { property.SetValue(_realtimeData.TestData, intValue); } else if (property.PropertyType == typeof(double) && double.TryParse(item.Val, out double doubleValue)) { property.SetValue(_realtimeData.TestData, doubleValue); } else if (property.PropertyType == typeof(DateTime) && DateTime.TryParse(item.Val, out DateTime dateValue)) { property.SetValue(_realtimeData.TestData, dateValue); } else if (property.PropertyType == typeof(bool) && bool.TryParse(item.Val, out bool boolValue)) { property.SetValue(_realtimeData.TestData, boolValue); } } } } else { // 没有测试数据时,置空测试数据对象 _realtimeData.TestData = null; } } /// /// 获取最新的RTVar数据(可在外部直接调用) /// /// WebSocketData对象 public async Task GetLatestDataAsync() { await ReadRTVarDataAsync(); return _realtimeData; } /// /// 释放资源 /// public void Dispose() { StopPolling(); _cancellationTokenSource?.Dispose(); _dataPollingTimer?.Dispose(); } } }