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/IoTCenter/Services/PageHub.cs

531 lines
20 KiB

using Application.Domain.Entities;
using Application.Models;
using Infrastructure.Data;
using Infrastructure.Extensions;
using Infrastructure.Web.SignalR;
using IoT.Shared.Infrastructure;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Vibrant.InfluxDB.Client;
using Vibrant.InfluxDB.Client.Rows;
namespace IoTCenter.Services
{
public class PageHub : BasePageHub
{
private readonly IConfiguration _cfg;
private readonly IRepository<Node> _nodeRepo;
private readonly IRepository<Device> _deviceRepo;
private readonly IRepository<Data> _dataRepo;
private readonly IRepository<Api> _apiRepo;
private readonly IRepository<Command> _commandRepo;
private readonly IRepository<Category> _categoryRepo;
private readonly IRepository<Product> _productRepo;
private readonly IRepository<Scene> _sceneRepo;
private readonly IRepository<SceneCommand> _sceneCommandRepo;
private readonly IRepository<IoTTimer> _timerRepo;
private readonly IRepository<IoTTigger> _tiggerRepo;
public PageHub(IConfiguration cfg,
IRepository<Node> nodeRepo,
IRepository<Device> deviceRepo,
IRepository<Data> dataRepo,
IRepository<Api> apiRepo,
IRepository<Command> commandRepo,
IRepository<Category> categoryRepo,
IRepository<Product> productRepo,
IRepository<Scene> sceneRepo,
IRepository<SceneCommand> sceneCommandRepo,
IRepository<IoTTimer> timerRepo,
IRepository<IoTTigger> tiggerRepo)
{
this._cfg = cfg;
this._nodeRepo = nodeRepo;
this._deviceRepo = deviceRepo;
this._dataRepo = dataRepo;
this._apiRepo = apiRepo;
this._commandRepo = commandRepo;
this._categoryRepo = categoryRepo;
this._productRepo = productRepo;
this._sceneRepo = sceneRepo;
this._sceneCommandRepo = sceneCommandRepo;
this._timerRepo = timerRepo;
this._tiggerRepo = tiggerRepo;
}
public override void ClientToServer(string method, string message, string connectionId)
{
Console.WriteLine($"iot center> receive message from {connectionId}");
if (method == Methods.HealthCheckResponse)
{
var node = _nodeRepo.Table().FirstOrDefault(o => o.Number == message);
node.IsOnline = true;
_nodeRepo.SaveChanges();
}
else if (method == Methods.RefreshDeviceListResponse)
{
this.RefreshDeviceList(message, connectionId);
}
else if (method == Methods.RefreshSceneListResponse)
{
this.RefreshSceneList(message, connectionId);
}
else if (method == Methods.RefreshCommandListResponse)
{
this.RefreshCommandList(message, connectionId);
}
else if (method == Methods.EditNodeResponse)//上报节点
{
this.UpdateNode(message);
}
else if (method == Methods.GetProductResponse)//上报产品
{
this.UpdateProduct(message);
}
else if (method == Methods.EditDeviceResponse)//上报设备
{
this.UpdateDevice(message);
}
else if (method == Methods.EditDataResponse)//上报数据
{
this.UpdateData(message);
}
//
else if (method == Methods.EditDeviceResponse)
{
this.UpdateDevice(message);
}
else if (method == Methods.DeleteDeviceResponse)
{
this.DeleteDevice(message);
}
else if (method == Methods.DeleteDataResponse)
{
this.DeleteData(message);
}
else if (method == Methods.EditSceneResponse)
{
this.UpdateScene(message);
}
else if (method == Methods.DeleteSceneResponse)
{
this.DeleteScene(message);
}
else if (method == Methods.EditCommandResponse)
{
this.UpdateCommand(message);
}
else if (method == Methods.DeleteCommandResponse)
{
this.DeleteCommand(message);
}
else if (method == Methods.EditSceneCommandResponse)
{
this.UpdateSceneCommand(message);
}
else if (method == Methods.DeleteSceneCommandResponse)
{
this.DeleteSceneCommand(message);
}
}
private void RefreshDeviceList(string message, string connectionId)
{
var list = message.FromJson<List<string>>();
var devices = _deviceRepo.Table().Where(o => o.Node.Number == connectionId && !list.Contains(o.Number)).ToList();
foreach (var device in devices)
{
_deviceRepo.Delete(device);
}
_deviceRepo.SaveChanges();
}
private void RefreshSceneList(string message, string connectionId)
{
var list = message.FromJson<List<Guid>>();
var scenes = _sceneRepo.Table().Where(o => o.Node.Number == connectionId && !list.Contains(o.Id)).ToList();
foreach (var scene in scenes)
{
_sceneRepo.Delete(scene);
}
_sceneRepo.SaveChanges();
}
private void RefreshCommandList(string message, string connectionId)
{
var list = message.FromJson<List<Guid>>();
var commands = _commandRepo.Table().Where(o => o.Device.Node.Number == connectionId && !list.Contains(o.Id)).ToList();
foreach (var command in commands)
{
_commandRepo.Delete(command);
}
_commandRepo.SaveChanges();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void UpdateNode(string message)
{
try
{
Console.WriteLine("iot center> receive node message");
var nodeDto = message.FromJson<EditNodeModel>();
var node = _nodeRepo.Table().FirstOrDefault(o => o.Number == nodeDto.Number);
if (node == null)
{
node = new Node();
_nodeRepo.Add(node);
}
node.FromDto(nodeDto);
_nodeRepo.SaveChanges();
this.Clients.Group("page").SendAsync("UpdateNode", message);
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void UpdateProduct(string message)
{
try
{
Console.WriteLine("iot center> receive product message");
var productDto = message.FromJson<EditProductModel>();
var category = _categoryRepo.ReadOnlyTable().FirstOrDefault(o => o.Number == productDto.CategoryNumber);
var product = _productRepo.Table().FirstOrDefault(o => o.Number == productDto.Number);
if (product == null)
{
product = new Product().FromDto(productDto);
product.CategoryId = category.Id;
_productRepo.Add(product);
OpenApiService.UpdateApi(product);
_productRepo.SaveChanges();
}
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void UpdateDevice(string message)
{
try
{
Console.WriteLine("iot center> receive device message");
var deviceDto = message.FromJson<EditDeviceModel>();
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 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 device = _deviceRepo.Table().FirstOrDefault(o => o.Number == deviceDto.Number);
if (device == null)
{
device = new Device();
device.ProductId = product.Id;
device.NodeId = node.Id;
_deviceRepo.Add(device);
}
device.FromDto(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();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void DeleteDevice(string message)
{
try
{
Console.WriteLine("iot center> receive device message");
var model = message.FromJson<EditDeviceModel>();
var device = _deviceRepo.Table().FirstOrDefault(o => o.Number == model.Number);
if (device != null)
{
_deviceRepo.Delete(device);
_deviceRepo.SaveChanges();
this.Clients.Group("page").SendAsync("DeleteDevice", model.Number);
}
}
catch (Exception ex)
{
ex.PrintStack();
}
}
private void UpdateData(string message)
{
Console.WriteLine("iot center> receive data message");
var dataDtoList = message.FromJson<List<EditDataModel>>();
if (dataDtoList.Count > 0)
{
var number = dataDtoList.FirstOrDefault().DeviceNumber;
var device = _deviceRepo.Table().Include(o => o.Data).FirstOrDefault(o => o.Number == number);
if (device != null)
{
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.FromDto(dataDto);
}
_deviceRepo.SaveChanges();
this.Clients.Group("page").SendAsync("UpdateDevice", device.ToJson());
foreach (var dataDto in dataDtoList)
{
this.LogToInfluxdbAsync(dataDto).Wait(0);
}
}
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void DeleteData(string message)
{
try
{
Console.WriteLine("iot center> receive delete data message");
var model = message.FromJson<EditDataModel>();
var data = _dataRepo.Table().FirstOrDefault(o => o.Device.Number == model.DeviceNumber && o.Key == model.Key);
if (data != null)
{
_dataRepo.Delete(data);
_dataRepo.SaveChanges();
this.Clients.Group("page").SendAsync("DeleteData", message);
}
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void UpdateScene(string message)
{
try
{
Console.WriteLine("iot center> receive edit scene message");
var model = message.FromJson<EditSceneModel>();
var scene = _sceneRepo.Table().FirstOrDefault(o => o.Id == model.Id);
if (scene == null)
{
scene = new Scene
{
Id = model.Id
};
_sceneRepo.Add(scene);
}
scene.FromDto(model);
scene.NodeId = _nodeRepo.ReadOnlyTable().FirstOrDefault(o => o.Number == model.NodeNumber).Id;
_sceneRepo.SaveChanges();
this.Clients.Group("page").SendAsync("UpdateScene", message);
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void DeleteScene(string message)
{
try
{
Console.WriteLine("iot center> receive delete scene message");
var model = message.FromJson<EditSceneModel>();
var scene = _sceneRepo.Table().FirstOrDefault(o => o.Id == model.Id);
if (scene != null)
{
_sceneRepo.Delete(scene);
_sceneRepo.SaveChanges();
this.Clients.Group("page").SendAsync("DeleteScene", message);
}
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void UpdateCommand(string message)
{
try
{
Console.WriteLine("iot center> receive edit command message");
var model = message.FromJson<EditCommandModel>();
var device = _deviceRepo.ReadOnlyTable().Where(o => o.Number == model.DeviceNumber).FirstOrDefault();
var api = _apiRepo.ReadOnlyTable().Where(o => o.ProductId == device.ProductId && o.Name == model.ApiName).FirstOrDefault();
var command = _commandRepo.Table().FirstOrDefault(o => o.Id == model.Id);
if (command == null)
{
command = new Command
{
Id = model.Id
};
_commandRepo.Add(command);
}
command.FromDto(model);
command.DeviceId = device.Id;
command.ApiId = api.Id;
_commandRepo.SaveChanges();
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void DeleteCommand(string message)
{
try
{
Console.WriteLine("iot center> receive delete scene message");
var model = message.FromJson<EditCommandModel>();
var command = _commandRepo.Table().FirstOrDefault(o => o.Id == model.Id);
if (command != null)
{
_commandRepo.Delete(command);
_commandRepo.SaveChanges();
}
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void UpdateSceneCommand(string message)
{
try
{
Console.WriteLine("iot center> receive edit scene command message");
var model = message.FromJson<EditSceneCommandModel>();
var sceneCommand = _sceneCommandRepo.Table().FirstOrDefault(o => o.Id == model.Id);
if (sceneCommand == null)
{
sceneCommand = new SceneCommand
{
Id = model.Id
};
_sceneCommandRepo.Add(sceneCommand);
}
sceneCommand.SceneId = model.SceneId.Value;
sceneCommand.CommandId = model.CommandId.Value;
_sceneCommandRepo.SaveChanges();
}
catch (Exception ex)
{
ex.PrintStack();
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private void DeleteSceneCommand(string message)
{
try
{
Console.WriteLine("iot center> receive delete scene command message");
var model = message.FromJson<EditSceneCommandModel>();
var sceneCommand = _sceneCommandRepo.Table().FirstOrDefault(o => o.Id == model.Id);
if (sceneCommand != null)
{
_sceneCommandRepo.Delete(sceneCommand);
_sceneCommandRepo.SaveChanges();
}
}
catch (Exception ex)
{
ex.PrintStack();
}
}
public void ApiCallback(string message, string connectionId)
{
if (!string.IsNullOrEmpty(connectionId))
{
this.ServerToClient(connectionId, Methods.ApiCallback, message);
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private async Task LogToInfluxdbAsync(EditDataModel model)
{
if (string.IsNullOrEmpty(model.Value))
{
return;
}
if (model.Type != DeviceDataType.Int && model.Type != DeviceDataType.Float)
{
return;
}
try
{
var url = _cfg["influxdb:url"];
var usr = _cfg["influxdb:usr"];
var pwd = _cfg["influxdb:pwd"];
var dbName = "iot";
var measurementName = "data";
using var client = new InfluxClient(new Uri(url), usr, pwd);
await client.CreateDatabaseAsync(dbName);
var row = new DynamicInfluxRow
{
Timestamp = DateTime.UtcNow
};
row.Fields.Add("DeviceNumber", model.DeviceNumber);
row.Fields.Add("DeviceName", model.Name);
row.Fields.Add(model.Key, this.GetDataValue(model));
await client.WriteAsync(dbName, measurementName, new List<DynamicInfluxRow> { row });
}
catch (Exception ex)
{
ex.PrintStack();
}
}
private object GetDataValue(EditDataModel model)
{
return model.Type switch
{
DeviceDataType.Int => Convert.ToInt32(model.Value),
DeviceDataType.Float => Convert.ToSingle(model.Value),
_ => model.Value,
};
}
}
}