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.
141 lines
5.1 KiB
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);
|
|
}
|
|
}
|
|
}
|
|
} |