using Application.Domain.Entities; using Infrastructure.Data; using Infrastructure.Extensions; using Infrastructure.Web.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Readers; using System; using System.Linq; namespace IoTCenter.Services { public class PageHub : BasePageHub { private readonly IServiceProvider _applicationService; public PageHub(IServiceProvider applicationService) { this._applicationService = applicationService; } public override void OnClientToServer(string method, string message, string connectionId) { if (method == "UpdateDeviceInfo") { this.UpdateDeviceInfo(message); } else if (method == "UpdateDevice") { this.UpdateDevice(message); } } private void UpdateDeviceInfo(string message) { try { Console.WriteLine("iot center> receive device info"); var newDeviceInfo = message.FromJson(); using (var scope = this._applicationService.CreateScope()) { var deviceInfoRepo = scope.ServiceProvider.GetService>(); var deviceInfo = deviceInfoRepo.Table().FirstOrDefault(o => o.Number == newDeviceInfo.Number); if (deviceInfo == null) { deviceInfo = new DeviceInfo().Update(newDeviceInfo); deviceInfoRepo.Add(deviceInfo); if (!string.IsNullOrEmpty(deviceInfo.ApiJson)) { this.UpdateApi(deviceInfo); } deviceInfoRepo.SaveChanges(); } } } catch (Exception ex) { ex.PrintStack(); } } private void UpdateDevice(string message) { try { Console.WriteLine("iot center> receive device"); var newDevice = message.FromJson(); using (var scope = this._applicationService.CreateScope()) { var deviceInfoRepo = scope.ServiceProvider.GetService>(); var deviceInfo = deviceInfoRepo.Table().FirstOrDefault(o => o.Number == newDevice.InfoNumber); if (deviceInfo == null) { this.ServerToClient(newDevice.ConnectId, "GetDeviceInfo", newDevice.InfoNumber); throw new Exception("need device info"); } var categoryRepo = scope.ServiceProvider.GetService>(); var category = categoryRepo.Table().FirstOrDefault(o => o.Number == newDevice.CategoryNumber); if (category == null) { category = new Category { Number = newDevice.CategoryNumber, Name = newDevice.CategoryNumber }; categoryRepo.Add(category); categoryRepo.SaveChanges(); } var nodeRepo = scope.ServiceProvider.GetService>(); var node = nodeRepo.Table().FirstOrDefault(o => o.Number == newDevice.NodeNumber); if (node == null) { node = new Node { Number = newDevice.NodeNumber, Name = newDevice.NodeNumber }; nodeRepo.Add(node); nodeRepo.SaveChanges(); } var deviceRepo = scope.ServiceProvider.GetService>(); var device = deviceRepo.Table().Include(o => o.Data).FirstOrDefault(o => o.Number == newDevice.Number); if (device == null) { device = new Device().Update(newDevice); device.InfoId = deviceInfo.Id; device.CategoryId = category.Id; device.NodeId = node.Id; deviceRepo.Add(device); } else { foreach (var newData in newDevice.Data) { var data = device.Data.FirstOrDefault(o => o.Key == newData.Key); if (data == null) { data = new Data().Update(newData); data.DeviceId = device.Id; device.Data.Add(data); } data.Update(newData, "Id", "UpdatedOn"); data.DeviceId = device.Id; } } deviceRepo.SaveChanges(); } } catch (Exception ex) { ex.PrintStack(); } } public void ApiCallback(string message, string connectionId) { if (!string.IsNullOrEmpty(connectionId)) { this.ServerToClient(connectionId, "ApiCallback", message); } } private void UpdateApi(DeviceInfo deviceInfo) { try { var reader = new OpenApiStringReader(new OpenApiReaderSettings { }).Read(deviceInfo.ApiJson, out OpenApiDiagnostic diagnostic); foreach (var path in reader.Paths) { foreach (var operation in path.Value.Operations) { if (!deviceInfo.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() }; deviceInfo.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(); } } } }