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>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander>, IEventHander> { private readonly IConfiguration _cfg; private readonly IExecApiService _apiService; private readonly ILogger _logger; private readonly IRepository _productrepo; private readonly IRepository _deviceRepo; private readonly IRepository _sceneTiggerRepo; private readonly ISceneTiggerService _sceneTiggerService; private readonly IHubContext _hub; public IoTCenterEventHandler(IConfiguration cfg, IExecApiService apiService, ILogger logger, IRepository productRepo, IRepository deviceRepo, IRepository sceneTiggerRepo, ISceneTiggerService sceneTiggerService, IHubContext 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 message) { this.Notify(message); } public void Handle(EntityUpdated message) { this.Notify(message); } public void Handle(EntityDeleted message) { this.Notify(message); } //Building public void Handle(EntityInserted message) { this.Notify(message); } public void Handle(EntityUpdated message) { this.Notify(message); } public void Handle(EntityDeleted message) { this.Notify(message); } //Product public void Handle(EntityInserted message) { UpdateProduct(message.Data); this.Notify(message); } public void Handle(EntityUpdated 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 message) { this.Notify(message); } public void Handle(EntityInserted message) { var timer = message.Data; RecurringJob.AddOrUpdate(timer.Id.ToString(), () => this._apiService.TimerHandle(timer.Id), timer.Cron, TimeZoneInfo.Local); } public void Handle(EntityUpdated message) { var timer = message.Data; RecurringJob.AddOrUpdate(timer.Id.ToString(), () => this._apiService.TimerHandle(timer.Id), timer.Cron, TimeZoneInfo.Local); } public void Handle(EntityDeleted message) { var timer = message.Data; RecurringJob.RemoveIfExists(timer.Id.ToString()); } public void Handle(EntityInserted message) { this.Notify(message); } public void Handle(EntityUpdated message) { this.Notify(message); } public void Handle(EntityDeleted message) { this.Notify(message); } public void Handle(EntityInserted message) { this.Notify(message); } public void Handle(EntityUpdated message) { this.Notify(message); } public void Handle(EntityDeleted message) { this.Notify(message); } public void Handle(EntityInserted 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 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 message) { this.Notify(message); } public void Handle(EntityInserted message) { this.Notify(message); } public void Handle(EntityUpdated message) { this.Notify(message); } public void Handle(EntityDeleted message) { this.Notify(message); } private void Notify(BaseEvent 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 { 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 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 message) { this.Notify(message); } public void Handle(EntityUpdated message) { this.Notify(message); } public void Handle(EntityDeleted message) { this.Notify(message); } } }