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/EventHandlers/IoTCenterEventHandler.cs

368 lines
12 KiB

using Application.Domain.Entities;
using Hangfire;
using Infrastructure.Data;
using Infrastructure.Events;
using Infrastructure.Extensions;
using IoT.Shared.Services;
using Jint;
using Jint.Native;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Platform.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Vibrant.InfluxDB.Client;
using Vibrant.InfluxDB.Client.Rows;
namespace Platform.EventHandlers
{
public class IoTCenterEventHandler :
IEventHander<EntityInserted<Organ>>,
IEventHander<EntityUpdated<Organ>>,
IEventHander<EntityDeleted<Organ>>,
IEventHander<EntityInserted<Building>>,
IEventHander<EntityUpdated<Building>>,
IEventHander<EntityDeleted<Building>>,
IEventHander<EntityInserted<IoTProduct>>,
IEventHander<EntityUpdated<IoTProduct>>,
IEventHander<EntityDeleted<IoTProduct>>,
IEventHander<EntityInserted<IoTTimer>>,
IEventHander<EntityUpdated<IoTTimer>>,
IEventHander<EntityDeleted<IoTTimer>>,
IEventHander<EntityInserted<IoTGateway>>,
IEventHander<EntityUpdated<IoTGateway>>,
IEventHander<EntityDeleted<IoTGateway>>,
IEventHander<EntityInserted<IoTDevice>>,
IEventHander<EntityUpdated<IoTDevice>>,
IEventHander<EntityDeleted<IoTDevice>>,
IEventHander<EntityInserted<IoTData>>,
IEventHander<EntityUpdated<IoTData>>,
IEventHander<EntityDeleted<IoTData>>,
IEventHander<EntityInserted<IoTCommand>>,
IEventHander<EntityUpdated<IoTCommand>>,
IEventHander<EntityDeleted<IoTCommand>>,
IEventHander<EntityInserted<IoTScene>>,
IEventHander<EntityUpdated<IoTScene>>,
IEventHander<EntityDeleted<IoTScene>>
{
private readonly IConfiguration _cfg;
private readonly IExecApiService _apiService;
private readonly ILogger<IoTCenterEventHandler> _logger;
private readonly IRepository<IoTProduct> _productrepo;
private readonly IRepository<IoTDevice> _deviceRepo;
private readonly IRepository<IoTTigger> _sceneTiggerRepo;
private readonly ISceneTiggerService _sceneTiggerService;
private readonly IHubContext<IoTCenterHub> _hub;
public IoTCenterEventHandler(IConfiguration cfg,
IExecApiService apiService,
ILogger<IoTCenterEventHandler> logger,
IRepository<IoTProduct> productRepo,
IRepository<IoTDevice> deviceRepo,
IRepository<IoTTigger> sceneTiggerRepo,
ISceneTiggerService sceneTiggerService,
IHubContext<IoTCenterHub> hub)
{
this._cfg = cfg;
this._apiService = apiService;
this._logger = logger;
this._productrepo = productRepo;
this._deviceRepo = deviceRepo;
this._sceneTiggerRepo = sceneTiggerRepo;
this._sceneTiggerService = sceneTiggerService;
this._hub = hub;
}
//Organ
public void Handle(EntityInserted<Organ> message)
{
this.Notify(message);
}
public void Handle(EntityUpdated<Organ> message)
{
this.Notify(message);
}
public void Handle(EntityDeleted<Organ> message)
{
this.Notify(message);
}
//Building
public void Handle(EntityInserted<Building> message)
{
this.Notify(message);
}
public void Handle(EntityUpdated<Building> message)
{
this.Notify(message);
}
public void Handle(EntityDeleted<Building> message)
{
this.Notify(message);
}
//Product
public void Handle(EntityInserted<IoTProduct> message)
{
UpdateProduct(message.Data);
this.Notify(message);
}
public void Handle(EntityUpdated<IoTProduct> message)
{
UpdateProduct(message.Data);
this.Notify(message);
}
private void UpdateProduct(IoTProduct entity)
{
var product = this._productrepo.Table()
.Include(o => o.IoTApis)
.ThenInclude(o => o.IoTParameters)
.FirstOrDefault(o => o.Number == entity.Number);
if (product != null)
{
OpenApiService.UpdateApi(product);
this._productrepo.SaveChanges();
}
}
public void Handle(EntityDeleted<IoTProduct> message)
{
this.Notify(message);
}
public void Handle(EntityInserted<IoTTimer> message)
{
var timer = message.Data;
RecurringJob.AddOrUpdate(timer.Id.ToString(), () => this._apiService.TimerHandle(timer.Id), timer.Cron, TimeZoneInfo.Local);
}
public void Handle(EntityUpdated<IoTTimer> message)
{
var timer = message.Data;
RecurringJob.AddOrUpdate(timer.Id.ToString(), () => this._apiService.TimerHandle(timer.Id), timer.Cron, TimeZoneInfo.Local);
}
public void Handle(EntityDeleted<IoTTimer> message)
{
var timer = message.Data;
RecurringJob.RemoveIfExists(timer.Id.ToString());
}
public void Handle(EntityInserted<IoTGateway> message)
{
this.Notify(message);
}
public void Handle(EntityUpdated<IoTGateway> message)
{
this.Notify(message);
}
public void Handle(EntityDeleted<IoTGateway> message)
{
this.Notify(message);
}
public void Handle(EntityInserted<IoTDevice> message)
{
this.Notify(message);
}
public void Handle(EntityUpdated<IoTDevice> message)
{
this.Notify(message);
}
public void Handle(EntityDeleted<IoTDevice> message)
{
this.Notify(message);
}
public void Handle(EntityInserted<IoTData> message)
{
message.Data.IoTDevice = _deviceRepo.ReadOnlyTable().Include(o => o.IoTGateway).Where(o => o.Id == message.Data.IoTDeviceId).FirstOrDefault();
this.Notify(message);
this.TiggerHandle(message);
this.LogData(message.Data);
}
public void Handle(EntityUpdated<IoTData> message)
{
message.Data.IoTDevice = _deviceRepo.ReadOnlyTable().Include(o => o.IoTGateway).Where(o => o.Id == message.Data.IoTDeviceId).FirstOrDefault();
this.Notify(message);
this.TiggerHandle(message);
this.LogData(message.Data);
}
public void Handle(EntityDeleted<IoTData> message)
{
this.Notify(message);
}
public void Handle(EntityInserted<IoTCommand> message)
{
this.Notify(message);
}
public void Handle(EntityUpdated<IoTCommand> message)
{
this.Notify(message);
}
public void Handle(EntityDeleted<IoTCommand> message)
{
this.Notify(message);
}
private void Notify<T>(BaseEvent<T> message)
{
Task.Run(() =>
{
try
{
_hub.ServerToClient($"{typeof(T).Name}{message.Arg}", message.Data, "page", null);
}
catch (Exception ex)
{
ex.PrintStack();
}
});
}
private void LogData(IoTData data)
{
var device = _deviceRepo.ReadOnlyTable()
.Include(o => o.IoTGateway)
//.ThenInclude(o => o.BuildingIoTGateways)
//.ThenInclude(o => o.Building.Organ)
.FirstOrDefault(o => o.Id == data.IoTDeviceId);
//var organ = device.Node.BuildingIoTGateways.FirstOrDefault()?.Building.Organ;
Task.Run(async () =>
{
try
{
if (string.IsNullOrEmpty(data.Value))
{
return;
}
//if (data.ValueType != IoTValueType.Int && data.ValueType != IoTValueType.Float && data.ValueType != IoTValueType.String)
//{
// return;
//}
try
{
var dbName = "iot";
var measurementName = "data";
using var client = InfluxDBHelper.CreateClient(this._cfg);
await client.CreateDatabaseAsync(dbName);
var row = new DynamicInfluxRow
{
Timestamp = DateTimeOffset.FromUnixTimeMilliseconds(data.Timestamp).DateTime
};
//if (organ != null)
//{
// row.Fields.Add("OrganName", organ.Name);
// row.Fields.Add("OrganNumber", organ.Number);
//}
row.Fields.Add("NodeName", device.IoTGateway.Name);
row.Fields.Add("NodeNumber", device.IoTGateway.Number);
row.Fields.Add("DeviceNumber", device.Number);
row.Fields.Add("DeviceName", device.Name);
row.Fields.Add(data.Key, this.GetDataValue(data));
await client.WriteAsync(dbName, measurementName, new List<DynamicInfluxRow> { row });
}
catch (Exception ex)
{
ex.PrintStack();
}
}
catch (Exception ex)
{
ex.PrintStack();
}
});
}
private object GetDataValue(IoTData model)
{
return model.ValueType switch
{
IoTValueType.Int => Convert.ToInt32(model.Value),
IoTValueType.Double => Convert.ToDouble(model.Value),
_ => model.Value,
};
}
public void TiggerHandle(BaseEvent<IoTData> eventMessage)
{
try
{
foreach (var item in this._sceneTiggerService.GetSceneTiggers())
{
var data = eventMessage.Data;
if (item.IoTDataId == data.Id)
{
try
{
var condition = item.Condition;
var value = data.Value;
var engine = new Engine().Execute($"function valid(value){{return {condition};}}");
var result = engine.Invoke("valid", value);
if (result == JsValue.True)
{
this._logger.LogDebug($"global tigger exec:{item.Id}");
var scenes = this._sceneTiggerRepo.ReadOnlyTable().Where(o => o.Id == item.Id).Select(o => o.IoTScene.Id);
foreach (var sceneId in scenes)
{
this._apiService.ExecScene(sceneId, null);
}
}
}
catch (Exception ex)
{
this._logger.LogError(ex.ToString());
}
}
}
}
catch (Exception ex)
{
this._logger.LogError(ex.ToString());
}
}
public void Handle(EntityInserted<IoTScene> message)
{
this.Notify(message);
}
public void Handle(EntityUpdated<IoTScene> message)
{
this.Notify(message);
}
public void Handle(EntityDeleted<IoTScene> message)
{
this.Notify(message);
}
}
}