using Application.Domain.Entities; using Application.Models; using Infrastructure.Data; using Infrastructure.Extensions; using Infrastructure.Web.SignalR; using IoT.Shared.Application.Models; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Readers; using System; using System.Collections.Generic; using System.Linq; namespace IoTCenter.Services { public class PageHub : BasePageHub { private readonly IServiceProvider _applicationService; public PageHub(IServiceProvider applicationService) { this._applicationService = applicationService; } public override void ClientToServer(string method, string message, string connectionId) { if (method == "HealthCheckResponse") { using (var scope = this._applicationService.CreateScope()) { var nodeRepo = scope.ServiceProvider.GetService>(); var node = nodeRepo.Table().FirstOrDefault(o => o.Number == message); node.IsOnline = true; nodeRepo.SaveChanges(); } } else if (method == Methods.NodeResponse) { this.UpdateNode(message); } else if (method == Methods.ProductResponse) { this.UpdateProduct(message); } else if (method == Methods.DeviceResponse) { this.UpdateDevice(message); } else if (method == Methods.DataResponse) { this.UpdateData(message); } // else if (method == Methods.EditNodeResponse) { this.UpdateNode(message); } else if (method == Methods.EditDeviceResponse) { this.UpdateDevice(message); } else if (method == Methods.DeleteDeviceResponse) { this.DeleteDevice(message); } } private void UpdateNode(string message) { try { Console.WriteLine("iot center> receive node message"); var nodeDto = message.FromJson(); using (var scope = this._applicationService.CreateScope()) { var nodeRepo = scope.ServiceProvider.GetService>(); var node = nodeRepo.Table().FirstOrDefault(o => o.Number == nodeDto.Number); if (node == null) { node = new Node(); nodeRepo.Add(node); } node.Update(nodeDto); nodeRepo.SaveChanges(); this.Clients.Group("page").SendAsync("UpdateNode", message); } } catch (Exception ex) { ex.PrintStack(); } } private void UpdateProduct(string message) { try { Console.WriteLine("iot center> receive product message"); var productDto = message.FromJson(); using (var scope = this._applicationService.CreateScope()) { var categoryRepo = scope.ServiceProvider.GetService>(); var category = categoryRepo.ReadOnlyTable().FirstOrDefault(o => o.Number == productDto.CategoryNumber); var productRepo = scope.ServiceProvider.GetService>(); var product = productRepo.Table().FirstOrDefault(o => o.Number == productDto.Number); if (product == null) { product = new Product().Update(productDto); product.CategoryId = category.Id; productRepo.Add(product); if (!string.IsNullOrEmpty(product.ApiJson)) { this.UpdateApi(product); } productRepo.SaveChanges(); } } } catch (Exception ex) { ex.PrintStack(); } } private void UpdateDevice(string message) { try { Console.WriteLine("iot center> receive device message"); var deviceDto = message.FromJson(); using (var scope = this._applicationService.CreateScope()) { var productRepo = scope.ServiceProvider.GetService>(); var product = productRepo.Table().FirstOrDefault(o => o.Number == deviceDto.ProductNumber); if (product == null) { this.ServerToClient(deviceDto.ConnectId, "GetDeviceInfo", deviceDto.ProductNumber); throw new Exception("need device info"); } var nodeRepo = scope.ServiceProvider.GetService>(); var node = nodeRepo.Table().FirstOrDefault(o => o.Number == deviceDto.NodeNumber); if (node == null) { node = new Node { Number = deviceDto.NodeNumber, Name = deviceDto.NodeNumber }; nodeRepo.Add(node); nodeRepo.SaveChanges(); } var deviceRepo = scope.ServiceProvider.GetService>(); var device = deviceRepo.Table().FirstOrDefault(o => o.Number == deviceDto.Number); if (device == null) { device = new Device(); device.DisplayName = device.Name; device.ProductId = product.Id; device.NodeId = node.Id; deviceRepo.Add(device); } device.Update(deviceDto); deviceRepo.SaveChanges(); var device2 = deviceRepo.ReadOnlyTable().Include(o => o.Data).FirstOrDefault(o => o.Number == deviceDto.Number); this.Clients.Group("page").SendAsync("UpdateDevice", device2.ToJson()); } } catch (Exception ex) { ex.PrintStack(); } } private void DeleteDevice(string number) { try { Console.WriteLine("iot center> receive device message"); using (var scope = this._applicationService.CreateScope()) { var deviceRepo = scope.ServiceProvider.GetService>(); var device = deviceRepo.Table().FirstOrDefault(o => o.Number == number); if (device != null) { deviceRepo.Delete(device); deviceRepo.SaveChanges(); this.Clients.Group("page").SendAsync("DeleteDevice", number); } } } catch (Exception ex) { ex.PrintStack(); } } private void UpdateData(string message) { Console.WriteLine("iot center> receive data message"); var dataDtoList = message.FromJson>(); if (dataDtoList.Count > 0) { using (var scope = this._applicationService.CreateScope()) { var number = dataDtoList.FirstOrDefault().DeviceNumber; var deviceRepo = scope.ServiceProvider.GetService>(); var device = deviceRepo.Table().Include(o => o.Data).FirstOrDefault(o => o.Number == number); foreach (var dataDto in dataDtoList) { var data = device.Data.FirstOrDefault(o => o.Key == dataDto.Key); if (data == null) { data = new Data(); device.Data.Add(data); } data.From(dataDto); } deviceRepo.SaveChanges(); this.Clients.Group("page").SendAsync("UpdateDevice", device.ToJson()); } } } public void ApiCallback(string message, string connectionId) { if (!string.IsNullOrEmpty(connectionId)) { this.ServerToClient(connectionId, Methods.ApiCallback, message); } } private void UpdateApi(Product product) { try { var reader = new OpenApiStringReader(new OpenApiReaderSettings { }).Read(product.ApiJson, out OpenApiDiagnostic diagnostic); foreach (var path in reader.Paths) { foreach (var operation in path.Value.Operations) { if (!product.Apis.Any(o => o.Name == operation.Value.Summary)) { var postion = path.Key.LastIndexOf('/') + 1; var api = new Api { Path = path.Key.Substring(0, postion), Command = path.Key.Substring(postion), Name = operation.Value.Summary, Method = operation.Key.ToString() }; product.Apis.Add(api); foreach (var parameter in operation.Value.Parameters) { if (!api.Parameters.Any(o => o.Name == parameter.Name)) { api.Parameters.Add(new Parameter { Name = parameter.Name, Description = parameter.Description, Required = parameter.Required, Type = parameter.Schema.Type, Minimum = parameter.Schema.Minimum?.ToString(), Maxinum = parameter.Schema.Maximum?.ToString() }); } } } } } } catch (Exception ex) { ex.PrintStack(); } } } }