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();
}
}
}