using Application.Domain.Entities; using Application.Models; using Infrastructure.Data; using Infrastructure.Extensions; using Infrastructure.Jwt; using Infrastructure.Web; using IoTCenter.Services; using IoTShared.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using Vibrant.InfluxDB.Client; using Vibrant.InfluxDB.Client.Rows; namespace IoTCenter.Controllers { [Device] public class AppController : Controller { private readonly IConfiguration _configuration; private readonly IJwtHelper _jwtHelper; private readonly IRepository _nodeRepo; private readonly IRepository _sceneRepo; private readonly IRepository _deviceRepo; private readonly IRepository _liveRecordRepo; private readonly IHubContext _pageHubContext; public AppController(IConfiguration configuration, IJwtHelper jwtHelper, IRepository nodeRepo, IRepository sceneRepo, IRepository deviceRepo, IRepository liveRecordRepo, IHubContext pageHubContext) { this._configuration = configuration; this._jwtHelper = jwtHelper; this._nodeRepo = nodeRepo; this._sceneRepo = sceneRepo; this._deviceRepo = deviceRepo; this._liveRecordRepo = liveRecordRepo; this._pageHubContext = pageHubContext; } [Authorize] public IActionResult Index() { return View(); } public IActionResult GetNodeList(string token) { var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString(); var model = this._nodeRepo.ReadOnlyTable() .Include(o => o.Scenes) .Select(o => new { o.Id, o.Number, o.Name, o.DisplayOrder, o.Icon, o.Image, o.Scenes, Count = o.Devices.Count }) .ToList(); return Json(model); } public IActionResult GetNode(string token, string number) { var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString(); var model = this._nodeRepo.ReadOnlyTable() .Include(o => o.Scenes) .Include(o => o.Devices) .ThenInclude(o => o.Data) .FirstOrDefault(o => o.Number == number); return Json(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); } public IActionResult GetDevice(string token, string number) { var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString(); var model = this._deviceRepo.ReadOnlyTable() .Include(o => o.Data) .FirstOrDefault(o => o.Number == number); return Json(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); } public IActionResult Exec(CallApiRequest request) { try { var device = this._deviceRepo.ReadOnlyTable().Include(o => o.Node).FirstOrDefault(o => o.Number == request.Number); if (device != null) { var query = string.Empty; var parameters = Request.Method.ToUpper() == "GET" ? Request.Query.ToArray() : Request.Form.ToArray(); foreach (var item in parameters.Where(o => o.Key != "ConnectionId" && o.Key != "Method")) { query = query.SetParam(item.Key, item.Value); } var message = $"{request.Method}{query}"; this._pageHubContext.Clients.Group(device.Node.Number).SendAsync(Methods.ServerToClient, Methods.CallApi, message, request.ConnectionId); } return Json(ApiResponse.AsyncSuccess()); } catch (Exception ex) { ex.PrintStack(); return Json(ApiResponse.Error(ex)); } } public IActionResult ExecAll(string connectionId, string node, string cmd, List id) { try { var query = string.Empty; foreach (var item in Request.Query.Where(o => o.Key != "node" && o.Key != "cmd" && !o.Key.StartsWith("id["))) { query = query.SetParam(item.Key, item.Value); } this._pageHubContext.Clients.Group(node).SendAsync(nameof(INodeService.ExecAll), connectionId, id, cmd, query); return Json(ApiResponse.AsyncSuccess()); } catch (Exception ex) { ex.PrintStack(); return Json(ApiResponse.Error(ex)); } } public IActionResult Scene(string connectionId, string node, string name) { try { var scene = this._sceneRepo.ReadOnlyTable().FirstOrDefault(o => o.Node.Number == node && o.Name == name); this._pageHubContext.Clients.Group(node).SendAsync(Methods.ServerToClient, Methods.CallScene, name, null); return Json(ApiResponse.AsyncSuccess()); } catch (Exception ex) { ex.PrintStack(); return Json(ApiResponse.Error(ex)); } } public IActionResult Data(Guid id, string time = "10m") { var device = this._deviceRepo.ReadOnlyTable().Include(o => o.Node).Include(o => o.Data).FirstOrDefault(o => o.Id == id); var url = this._configuration["influxdb:url"]; var usr = this._configuration["influxdb:usr"]; var pwd = this._configuration["influxdb:pwd"]; var dbName = "iot"; var measurementName = "data"; var list = new List(); using (var client = new InfluxClient(new Uri(url), usr, pwd)) { var fileds = String.Join(',', device.Data .Where(o => o.Type == DeviceDataType.Int || o.Type == DeviceDataType.Float) .Select(o => o.Key)); var query = $"select {fileds} from {measurementName} where time>now()-{time} and DeviceNumber = '{device.Number}' limit 10000"; var result = client.ReadAsync(dbName, query).Result; var rows = result.Results.FirstOrDefault()? .Series.FirstOrDefault()? .Rows; var labels = rows?.Select(o => o.Timestamp.Value).Select(o => o.ToString("MM-dd HH:mm:ss")).ToList() ?? new List(); foreach (var data in device.Data.Where(o => o.Type == DeviceDataType.Int || o.Type == DeviceDataType.Float)) { list.Add(new { id = data.Key, label = data.Name, labels, data = rows?.Select(o => o.GetField(data.Key)).ToList() ?? new List() }); } } return Json(list); } //{"action":"on_dvr","client_id":128,"ip":"127.0.0.1","vhost":"__defaultVhost__","app":"live","stream":"mainb57e867ae29d11b483864cbd8fd0f747","param":"","cwd":"/root/publish/apps/srs","file":"./objs/nginx/html/live/mainb57e867ae29d11b483864cbd8fd0f747.1565084670048.flv"} public IActionResult OnDvr() { using (var reader = new StreamReader(Request.Body)) { var json = reader.ReadToEnd(); var result = JsonConvert.DeserializeObject>(json); if (result["action"] == "on_dvr") { var streamId = result["stream"]; var deviceNumber = streamId.StartsWith("main") ? streamId.Substring(4) : streamId.Substring(3); this._liveRecordRepo.Add(new LiveRecord { DeviceNumber = deviceNumber, Name = "回放", Value = $"live{result["file"].Substring(result["file"].LastIndexOf('/'))}" }); this._liveRecordRepo.SaveChanges(); } } return Content(string.Empty); } public IActionResult AllPowerOn(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "On", o => o.Name.Contains("开关") || o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult AllPowerOff(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "Off", o => o.Name.Contains("开关") || o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult AllSwitchOn(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "On", o => o.Name.Contains("一路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult AllSwitchOff(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "Off", o => o.Name.Contains("一路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult AllSwitch3On(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "On", o => o.Name.Contains("三路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult AllSwitch3Off(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "Off", o => o.Name.Contains("三路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult AllSocketOn(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "On", o => o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult AllSocketOff(string connectionId, string[] nodes) { this.Power(connectionId, nodes, "Off", o => o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodePowerOn(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "On", o => o.Name.Contains("开关") || o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodePowerOff(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "Off", o => o.Name.Contains("开关") || o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodeSwitchOn(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "On", o => o.Name.Contains("一路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodeSwitchOff(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "Off", o => o.Name.Contains("一路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodeSwitch3On(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "On", o => o.Name.Contains("三路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodeSwitch3Off(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "Off", o => o.Name.Contains("三路开关")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodeSocketOn(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "On", o => o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } public IActionResult NodeSocketOff(string connectionId, string node) { this.Power(connectionId, new string[] { node }, "Off", o => o.Name.Contains("插座")); return Json(ApiResponse.AsyncSuccess()); } private void Power(string connectionId, string[] nodes, string command, Func func) { var devices = this._deviceRepo.ReadOnlyTable() .Include(o => o.Node) .Include(o => o.Product.Apis) .Where(o => nodes.Contains(o.Node.Number)) .Where(func) .ToList(); foreach (var device in devices) { try { var api = device.Product.Apis.FirstOrDefault(o => o.Command == command); var message = $"{api.Path}{api.Command}?number={device.Number}"; this._pageHubContext.Clients.Group(device.Node.Number).SendAsync(Methods.ServerToClient, Methods.CallApi, message, connectionId); } catch (Exception ex) { ex.PrintStack(); } } } } }