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