using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ProductionLineMonitor.Application.Services.EnergyConsumptionService.Dtos;
using ProductionLineMonitor.Core.Models;
using ProductionLineMonitor.EntityFramework;
using ProductionLineMonitor.EntityFramework.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ProductionLineMonitor.Web.HostedServices
{
///
/// 设备电能表运行状况检测服务
///
public class ElectricEnergyMeterCheckService : BackgroundService
{
private readonly IServiceScopeFactory _scopeFactory;
public ElectricEnergyMeterCheckService(
IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
await Task.Delay(CheckPeriod, stoppingToken);
lock (Machines)
{
GetMachines();
foreach (var machine in Machines)
{
machine.GetElectricEnergyMeterDtos();
machine.Check();
}
CheckOfflineMachine();
AddElectricEnergyMeterLog();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
public int CheckPeriod { get; private set; } = 1000 * 60 * 5;
public static IList Machines { get; set; }
= new List();
public void GetMachines()
{
using IServiceScope scope = _scopeFactory.CreateScope();
ProductionLineContext dbContext = scope.ServiceProvider.GetRequiredService();
UnitOfWork unitOfWork = new UnitOfWork(dbContext);
var machines = unitOfWork.MachineRepository.GetList().OrderBy(o => o.Type);
foreach (var machine in machines)
{
MachineElectricEnergyDto dto = new MachineElectricEnergyDto()
{
Id = machine.Id,
Name = machine.Name,
Topic = machine.Topic,
Type = machine.Type,
IsInclusionLineStatistics = machine.IsInclusionLineStatistics,
ProductionLineId = machine.ProductionLineId,
ProductionLineOrder = machine.ProductionLineOrder,
FaultTopic = machine.FaultTopic
};
var line = unitOfWork.ProductionLineRepository
.FirstOrDefault(x => x.Id == machine.ProductionLineId);
if (line != null)
{
dto.Floor = line.Floor;
dto.Line = line.Line;
}
var meters = unitOfWork.ElectricEnergyMeterRepository
.GetList(x => x.MachineId == machine.Id)
.OrderBy(o => o.Order)
.ToList();
if (meters != null)
dto.Meters = meters;
if (!Machines.Any(x => x.Id == dto.Id))
{
var m = new MachineElectricEnergyMeterCheckDto()
{
Id = dto.Id,
Name = dto.Name,
Topic = dto.Topic,
ProductionLineOrder = dto.ProductionLineOrder,
Type = dto.Type,
FaultTopic = dto.FaultTopic,
ProductionLineId = dto.ProductionLineId,
IsInclusionLineStatistics = dto.IsInclusionLineStatistics,
Meters = dto.Meters
};
Machines.Add(m);
}
}
}
public void AddElectricEnergyMeterLog()
{
var abnormalMachines = Machines.Where(x =>
x.MachineState != 1 &&
x.State != MachineElectricEnergyMeterCheckDto.MachineMeterState.Normal &&
x.State != MachineElectricEnergyMeterCheckDto.MachineMeterState.MesApiGetNull);
if (abnormalMachines != null && abnormalMachines.Count() > 0)
{
using IServiceScope scope = _scopeFactory.CreateScope();
ProductionLineContext dbContext = scope.ServiceProvider.GetRequiredService();
UnitOfWork unitOfWork = new UnitOfWork(dbContext);
foreach (var abnormalMachine in abnormalMachines)
{
unitOfWork.ElectricEnergyMeterLogRepository.Create(new Core.Models.ElectricEnergyMeterLog()
{
Id = Guid.NewGuid().ToString().ToUpper(),
CreateTime = DateTime.Now,
MachineId = abnormalMachine.Id,
Message = abnormalMachine.Message,
MachineName = abnormalMachine.Name
});
}
unitOfWork.SaveChanges();
}
}
private void CheckOfflineMachine()
{
foreach (var machine in Machines)
{
machine.MachineState = 0;
}
var abnormalMachines = Machines.Where(x =>
x.State != MachineElectricEnergyMeterCheckDto.MachineMeterState.Normal &&
x.State != MachineElectricEnergyMeterCheckDto.MachineMeterState.MesApiGetNull);
if (abnormalMachines != null && abnormalMachines.Count() > 0)
{
using IServiceScope scope = _scopeFactory.CreateScope();
ProductionLineContext dbContext = scope.ServiceProvider.GetRequiredService();
UnitOfWork unitOfWork = new UnitOfWork(dbContext);
List cims = unitOfWork.CimRepository.GetList().ToList();
DateTime dateTime = DateTime.Now;
foreach (var abnormalMachine in abnormalMachines)
{
var cim = cims.FirstOrDefault(x => x.Topic == abnormalMachine.Topic);
if (cim == null)
{
continue;
}
int min = (dateTime - cim.UpdateTime).Value.Minutes;
if (min > 5)
{
abnormalMachine.MachineState = 1;
}
}
}
}
public static IList GetCheckMachines()
{
return Machines;
}
public static void ChearMachines()
{
lock (Machines)
{
Machines = new List();
}
}
}
}