You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

296 lines
10 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using AngleSharp.Css.Dom;
using Masuit.Tools;
using CVDEMCS.Common.Constant;
using CVDEMCS.Common.Log;
using CVDEMCS.Devices;
using CVDEMCS.Services;
using CVDEMCS.Services.Impl;
using CVDEMCS.Services.Models;
using System.Linq;
using System.Threading;
namespace CVDEMCS.Devices.Impl
{
/// <summary>
/// 设备运行
/// </summary>
public class DeviceRun : IDeviceRun
{
private IDeviceService deviceService;
private IEquipmentRecordService equipmentRecordService;
private List<DeviceMonitor> monitors = new List<DeviceMonitor>();
private object lockObj = new object();
private object lockObj1 = new object();
public DeviceRun(IDeviceService deviceService, IEquipmentRecordService equipmentRecordService)
{
this.deviceService = deviceService;
this.equipmentRecordService = equipmentRecordService;
TaskRun();
}
/// <summary>
/// 获取所有点位信息
/// </summary>
public List<DevicePoint> GetDevicePoints
{
get
{
return monitors.SelectMany(f => f.Points).ToList();
}
}
/// <summary>
/// 获取控制器连接状态
/// </summary>
public Dictionary<string, bool> GetDeviceIsConnected
{
get
{
return monitors.ToDictionary(f => f.DeviceCode, f => f.IsConnected);
}
}
/// <summary>
/// 开始运行
/// </summary>
public void Run()
{
Stop();
monitors.Clear();
var result = deviceService.GetDeviceInfoList("", "", true);
if (result.IsSuccess)
{
var devices = result.Content;
foreach (var device in devices)
{
var deviceMonitor = new DeviceMonitor(device);
var devicePoints = deviceService.GetDevicePointList(device.Id, activated: true);
if (devicePoints.IsSuccess && devicePoints.Content.Count > 0)
{
deviceMonitor.Load(devicePoints.Content.ToArray());
}
deviceMonitor.ErrorMessage += DeviceMonitor_ErrorMessage;
deviceMonitor.PointChange += DeviceMonitor_PointChnage; ;
monitors.Add(deviceMonitor);
Task<bool> task = deviceMonitor.StartAsync();
($"PLC控制器{device.DeviceCode},开始启动...").WriteInfoLog();
}
}
}
/// <summary>
/// 停止运行
/// </summary>
public void Stop()
{
foreach (var item in monitors)
{
var task = item.StopAsync();
}
}
//
private void TaskRun()
{
//监控设备连接
Task.Run(() =>
{
while (true)
{
foreach (var item in monitors)
{
try
{
var task = item.StartAsync();
}
catch (Exception ex)
{
ex.WriteErrorLog("监控设备连接异常");
}
}
Thread.Sleep(5000);
}
});
//添加设备记录
Task.Run(() =>
{
while (true)
{
RunEquipmentRecord();
Thread.Sleep(3000);
}
});
//设备记录日统计
Task.Run(() =>
{
while (true)
{
try
{
equipmentRecordService.RunEquipmentRecordDayTotal(DateTime.Now);
}
catch (Exception ex)
{
ex.WriteErrorLog("设备记录日统计异常");
}
Thread.Sleep(1000 * 60);
}
});
//设备记录日统计(修复统计,解决出现跨天的数据统计不到的情况)
Task.Run(() =>
{
//凌晨1点运行
var now = DateTime.Now;
var targetTime = new DateTime(now.Year, now.Month, now.Day, 1, 0, 0);
if (targetTime <= now)
{
// 如果目标时间已经过去,则设置到明天
targetTime = targetTime.AddDays(1);
}
while (true)
{
try
{
Thread.Sleep(TimeSpan.FromMilliseconds(targetTime.Subtract(DateTime.Now).TotalMilliseconds));
//这里修复10天前的
for (int i = 10; i > 0; i--)
{
equipmentRecordService.RunEquipmentRecordDayTotal(DateTime.Now.AddDays(-i));
}
$" 设备记录日统计(修复统计) ".WriteInfoLog();
}
catch (Exception ex)
{
ex.WriteErrorLog("设备记录日统计(修复统计)异常");
}
//明天继续
targetTime = targetTime.AddDays(1);
}
});
//设备记录统计
Task.Run(() =>
{
while (true)
{
try
{
equipmentRecordService.RunEquipmentRecordTotal();
}
catch (Exception ex)
{
ex.WriteErrorLog("设备记录统计异常");
}
Thread.Sleep(1000 * 1800);
}
});
}
//记录设备数据
private void RunEquipmentRecord()
{
try
{
var models = new List<EquipmentRecordUpdateModel>();
foreach (var monitor in monitors)
{
if (!monitor.IsRun)
{
continue;
}
var points = monitor.Points;
if (points.IsNullOrEmpty())
{
continue;
}
var equipmentIds = points.Select(f => f.EquipmentId).Distinct();
foreach (var id in equipmentIds)
{
var list = points.Where(f => f.EquipmentId == id).ToList();
if (list.Count >= 2)
{
var startStop = list.Where(f => f.ActionType == ActionType.StartStop).FirstOrDefault();
var alarm = list.Where(f => f.ActionType == ActionType.Alarm).FirstOrDefault();
var maintain = list.Where(f => f.ActionType == ActionType.Maintain).FirstOrDefault();
if (!startStop.IsNullOrEmpty() &&
!alarm.IsNullOrEmpty() &&
!maintain.IsNullOrEmpty() &&
!startStop.ObjectValue.IsNullOrEmpty() &&
!alarm.ObjectValue.IsNullOrEmpty() &&
!maintain.ObjectValue.IsNullOrEmpty()
)
{
var state = EquipmentState.Stop;
//如果运行状态比警告状态高这里先判断运行状态如果运行状态为false在判断警告状态
//故障>运行>停止
if (maintain.GetValue<bool>())
{
state = EquipmentState.Maintain;
}
else if (startStop.GetValue<bool>())
{
state = EquipmentState.Run;
}
else if (alarm.GetValue<bool>())
{
state = EquipmentState.Alarm;
}
//如果为报警状态,则判断是否设为手动,且为不报警,则屏蔽报警信号,不做记录
//if (state == EquipmentState.Alarm &&
// startStop.Model == EquipmentAlarmModel.Manual &&
// !startStop.IsAlarm)
//{
// continue;
//}
//equipmentRecordService.AddUpdateEquipmentRecord(id, state, DateTime.Now);
models.Add(new EquipmentRecordUpdateModel
{
EquipmentId = id,
State = state,
DateTime = DateTime.Now
});
}
}
}
}
if (models.Count > 0)
{
//批量更新
equipmentRecordService.AddUpdateEquipmentRecordBatch(models);
}
}
catch (Exception ex)
{
ex.WriteErrorLog("记录设备数据异常");
}
}
private void DeviceMonitor_PointChnage(object sender, DevicePoint e)
{
}
private void DeviceMonitor_ErrorMessage(object sender, string e)
{
e.WriteErrorLog();
}
}
}