You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iot/projects/Platform/Services/ExecApiService.cs

141 lines
5.1 KiB

using Application.Domain.Entities;
using Hangfire;
using Hangfire.Storage;
using Infrastructure.Application.Services.Settings;
using Infrastructure.Data;
using Infrastructure.Events;
using Infrastructure.Extensions;
using IoT.Shared.Application.Models;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
namespace Platform.Services
{
public class ExecApiService : IExecApiService
{
private readonly IConfiguration _cfg;
private readonly ILogger<ExecApiService> _logger;
private readonly ISettingService _settingService;
private readonly IRepository<IoTScene> _sceneRepo;
private readonly IRepository<IoTSceneIoTCommand> _organSceneCommandRepo;
private readonly IRepository<IoTTimer> _organSceneTimerRepo;
private readonly IRepository<IoTCommand> _commandRepo;
private readonly IRepository<IoTDevice> _deviceRepo;
private readonly IHubContext<IoTCenterHub> _hub;
private readonly IEventPublisher _publisher;
public ExecApiService(IConfiguration cfg,
ILogger<ExecApiService> logger,
ISettingService settingService,
IRepository<IoTScene> sceneRepo,
IRepository<IoTSceneIoTCommand> organSceneCommandRepo,
IRepository<IoTTimer> sceneTimerRepo,
IRepository<IoTCommand> commandRepo,
IRepository<IoTDevice> deviceRepo,
IHubContext<IoTCenterHub> hub,
IEventPublisher publisher)
{
this._cfg = cfg;
this._logger = logger;
this._settingService = settingService;
this._sceneRepo = sceneRepo;
this._organSceneCommandRepo = organSceneCommandRepo;
this._organSceneTimerRepo = sceneTimerRepo;
this._commandRepo = commandRepo;
this._deviceRepo = deviceRepo;
this._hub = hub;
this._publisher = publisher;
}
public void UpdateTimer()
{
using var conn = JobStorage.Current.GetConnection();
var jobs = conn.GetRecurringJobs();
foreach (var job in jobs)
{
RecurringJob.RemoveIfExists(job.Id);
}
var list = this._organSceneTimerRepo.ReadOnlyTable().ToList();
foreach (var timer in list)
{
try
{
RecurringJob.AddOrUpdate(timer.Id.ToString(), () => TimerHandle(timer.Id), timer.Cron, TimeZoneInfo.Local);
}
catch (Exception ex)
{
ex.PrintStack();
this._logger.LogError(ex.ToString());
}
}
}
public void TimerHandle(Guid id)
{
try
{
_logger.LogInformation($"global timer exec at {DateTime.Now:G}:{id}");
var scenes = _organSceneTimerRepo.ReadOnlyTable().Where(o => o.Id == id).Select(o => o.IoTScene.Id);
foreach (var sceneId in scenes)
{
this.ExecScene(sceneId, null);
}
}
catch (Exception ex)
{
_logger.LogError(ex.ToString());
}
}
public void ExecScene(Guid id, string connectionId)
{
var scene = this._sceneRepo.ReadOnlyTable()
.Include(o => o.IoTSceneIoTCommands)
.ThenInclude(o => o.IoTCommand.Api)
.Include(o => o.IoTSceneIoTCommands)
.ThenInclude(o => o.IoTCommand.IoTDevice.IoTGateway)
.FirstOrDefault(o => o.Id == id);
if (scene != null)
{
this._publisher.Publish(new BaseEvent<IoTScene>(scene, nameof(ExecScene)));
foreach (var item in scene.IoTSceneIoTCommands)
{
this.ExecCommandInternal(item.IoTCommand, connectionId);
this.Delay(this._settingService, item.IoTCommand.Delay);
}
}
}
private void ExecCommandInternal(IoTCommand command, string connectionId)
{
var group = command.IoTDevice.IoTGateway.Number;
var message = $"{command.Api.Path}{command.Api.Command}";
if (!string.IsNullOrEmpty(command.QueryString))
{
message += "?" + command.QueryString;
}
this._hub.ServerToClient(Methods.ExecDeviceApi, message, group, connectionId);
this._publisher.Publish(new BaseEvent<IoTCommand>(command, "ExecCommand"));
}
private void Delay(ISettingService _settingService, int delay)
{
if (int.TryParse(_settingService.GetValue("delay"), out int commandDelay))
{
if (commandDelay > 0)
{
delay += commandDelay;
}
}
if (delay > 0)
{
Thread.Sleep(delay);
}
}
}
}