1.0 beta.107设备统计数据曲线图;修复节点部分AppController调用.

TangShanKaiPing
wanggang 6 years ago
parent 2130602597
commit 62f70ce5bc

@ -761,15 +761,20 @@
</template>
</ul>
</div>
<template v-for="data in Device.Data">
<div class="block" v-if="isChart(data)">
<div class="col">
<canvas :id="data.Key" :data-label="data.Name" class="chart"></canvas>
</div>
</div>
</template>
<div class="block-title" v-if="Device.Apis.length">操作</div>
<div class="list" v-if="Device.Apis.length">
<ul v-if="Device.Name==='摄像头'">
<li>
<div class="item-content">
<div class="item-inner">
<a v-if="isApp" style=' width: 100%;' class="button button-large button-fill button-outline color-green external" :href="getUrl('rtmp')">预览</a>
<a v-else style=' width: 100%;' class="button button-large button-fill button-outline color-green" href="javascript:;" v-on:click="flv()">预览</a>
</div>
<div class="block">
<a v-if="isApp" class="button button-large button-fill button-outline color-green external" :href="getUrl('rtmp')">预览</a>
<a v-else class="button button-large button-fill button-outline color-green" href="javascript:;" v-on:click="flv()">预览</a>
</div>
</li>
</ul>
@ -816,10 +821,8 @@
</template>
</template>
<li>
<div class="item-content">
<div class="item-inner">
<button class="button button-large button-fill button-outline" type="submit">{{api.Name}}</button>
</div>
<div class="block">
<button class="button button-large button-fill button-outline" type="submit">{{api.Name}}</button>
</div>
</li>
</ul>
@ -899,6 +902,7 @@
<script src="lib/dayjs/dayjs.min.js"></script>
<script src="lib/URI.js/URI.min.js"></script>
<script src="lib/flv.js/flv.min.js"></script>
<script src="lib/Chart.js/Chart.bundle.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

@ -9,23 +9,35 @@ 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.Linq;
using Vibrant.InfluxDB.Client;
using Vibrant.InfluxDB.Client.Rows;
namespace IoTCenter.Controllers
{
public class AppController : Controller
{
private readonly IConfiguration _configuration;
private readonly IJwtHelper _jwtHelper;
private readonly INodeService _nodeService;
private readonly IRepository<Node> _nodeRepo;
private readonly IRepository<Device> _deviceRepo;
private readonly IHubContext<PageHub> _pageHubContext;
public AppController(IJwtHelper jwtHelper, IRepository<Node> nodeRepo, IRepository<Device> deviceRepo, IHubContext<PageHub> pageHubContext)
public AppController(IConfiguration configuration,
IJwtHelper jwtHelper,
INodeService nodeService,
IRepository<Node> nodeRepo,
IRepository<Device> deviceRepo,
IHubContext<PageHub> pageHubContext)
{
this._configuration = configuration;
this._jwtHelper = jwtHelper;
this._nodeService = nodeService;
this._nodeRepo = nodeRepo;
this._deviceRepo = deviceRepo;
this._pageHubContext = pageHubContext;
@ -39,7 +51,7 @@ namespace IoTCenter.Controllers
public IActionResult GetNodes(string token)
{
var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString();
//var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString();
var model = this._nodeRepo.ReadOnlyTable()
.Select(o => new { o.Id, o.Number, o.Name, o.DisplayOrder, Count = o.Devices.Count })
.ToList();
@ -48,7 +60,7 @@ namespace IoTCenter.Controllers
public IActionResult GetNode(string token, string number)
{
var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString();
//var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString();
var model = this._nodeRepo.ReadOnlyTable()
.Include(o => o.Sences)
.Include(o => o.Devices).ThenInclude(o => o.Data)
@ -58,7 +70,7 @@ namespace IoTCenter.Controllers
public IActionResult GetDevice(string token, string number)
{
var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString();
//var userName = this._jwtHelper.GetPayload(token)["UserName"].ToString();
var model = this._deviceRepo.ReadOnlyTable()
.Include(o => o.Data)
.Include(o => o.Apis).ThenInclude(o => o.Parameters)
@ -75,8 +87,7 @@ namespace IoTCenter.Controllers
{
query = query.SetParam(item.Key, item.Value);
}
this._pageHubContext.Clients.Group(node).SendAsync(nameof(INodeService.Exec), connectionId, id, cmd, query);
return Json(ApiResponse.AsyncSuccess());
return Json(this._nodeService.Exec(id, cmd, query));
}
catch (Exception ex)
{
@ -94,7 +105,7 @@ namespace IoTCenter.Controllers
{
query = query.SetParam(item.Key, item.Value);
}
this._pageHubContext.Clients.Group(node).SendAsync(nameof(INodeService.ExecAll), connectionId, id, cmd, query);
this._nodeService.ExecAll(id, cmd, query);
return Json(ApiResponse.AsyncSuccess());
}
catch (Exception ex)
@ -108,7 +119,7 @@ namespace IoTCenter.Controllers
{
try
{
this._pageHubContext.Clients.Group(node).SendAsync(nameof(INodeService.Sence), connectionId, id);
this._nodeService.Sence(id);
return Json(ApiResponse.AsyncSuccess());
}
catch (Exception ex)
@ -117,5 +128,37 @@ namespace IoTCenter.Controllers
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<object>();
using (var client = new InfluxClient(new Uri(url), usr, pwd))
{
var fileds = String.Join(',', device.Data.Where(o => o.Type == "Int" || o.Type == "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<DynamicInfluxRow>(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<string>();
foreach (var data in device.Data.Where(o => o.Type == "Int" || o.Type == "Float"))
{
list.Add(new
{
id = data.Key,
label = data.Name,
labels,
data = rows?.Select(o => o.GetField(data.Key)).ToList() ?? new List<object>()
});
}
}
return Json(list);
}
}
}

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Warning"

@ -34,7 +34,7 @@ img.shot.zoom {
max-width:none;
max-height: none;
}
.list.media-list{
.block .list{
margin:0;
}
@ -51,6 +51,8 @@ img.shot.zoom {
.videoContainer #ptz {
position:absolute;
text-align:center;
width:300px;
margin:auto;
left:0;
right:0;
bottom:0;
@ -58,3 +60,13 @@ img.shot.zoom {
.videoContainer table {
margin: 0 auto;
}
.device-desktop.with-modal-dialog .page-content {
overflow: auto;
}
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 394 B

@ -649,18 +649,26 @@
</div>
<template v-for="data in _.orderBy(device.Data,['DisplayOrder','Name'])">
<template v-if="data.Key==='code[]'">
<a v-for="key in JSON.parse(data.Value)" class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.Id,'22call','code='+key.value)">{{key.text}}</a>
<div class="col" v-for="(value, key, index) in _.chain(JSON.parse(data.Value)).groupBy(o => o.text.split('-')[0]).value()">
<div>{{key}}</div>
<div class="card">
<a v-for="btn in value" class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.Id,'send','code='+btn.value)">
{{btn.text.indexOf('-')>0?btn.text.split('-')[1]:btn.text}}
</a>
</div>
</div>
</template>
</template>
</div>
</div>
</div>
</template>
<template v-if="getDevices('串口控制器').length">
<div class="block-title">串口控制器</div>
<div class="block block-strong">
<div class="row">
<div class="col" v-for="device in getDevices('串口控制器')">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('串口控制器')">
<div class="list">
<ul>
<li>
@ -753,15 +761,20 @@
</template>
</ul>
</div>
<template v-for="data in Device.Data">
<div class="block" v-if="isChart(data)">
<div class="col">
<canvas :id="data.Key" :data-label="data.Name" class="chart"></canvas>
</div>
</div>
</template>
<div class="block-title" v-if="Device.Apis.length">操作</div>
<div class="list" v-if="Device.Apis.length">
<ul v-if="Device.Name==='摄像头'">
<li>
<div class="item-content">
<div class="item-inner">
<a v-if="isApp" style=' width: 100%;' class="button button-large button-fill button-outline color-green external" :href="getUrl('rtmp')">预览</a>
<a v-else style=' width: 100%;' class="button button-large button-fill button-outline color-green" href="javascript:;" v-on:click="flv()">预览</a>
</div>
<div class="block">
<a v-if="isApp" class="button button-large button-fill button-outline color-green external" :href="getUrl('rtmp')">预览</a>
<a v-else class="button button-large button-fill button-outline color-green" href="javascript:;" v-on:click="flv()">预览</a>
</div>
</li>
</ul>
@ -808,10 +821,8 @@
</template>
</template>
<li>
<div class="item-content">
<div class="item-inner">
<button class="button button-large button-fill button-outline" type="submit">{{api.Name}}</button>
</div>
<div class="block">
<button class="button button-large button-fill button-outline" type="submit">{{api.Name}}</button>
</div>
</li>
</ul>
@ -832,23 +843,23 @@
<tr>
<td></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('26up')"><img src="images/up.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('26up')"><img src="images/up.png" /></a></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('24left')"><img src="images/left.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('24left')"><img src="images/left.png" /></a></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('25right')"><img src="images/right.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('25right')"><img src="images/right.png" /></a></td>
<td></td>
</tr>
<tr>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('21zoomin')"><img src="images/zoomin.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('21zoomin')"><img src="images/zoomin.png" /></a></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('27down')"><img src="images/down.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('27down')"><img src="images/down.png" /></a></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('22zoomout')"><img src="images/zoomout.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('22zoomout')"><img src="images/zoomout.png" /></a></td>
</tr>
</table>
</div>
@ -891,6 +902,7 @@
<script src="lib/dayjs/dayjs.min.js"></script>
<script src="lib/URI.js/URI.min.js"></script>
<script src="lib/flv.js/flv.min.js"></script>
<script src="lib/Chart.js/Chart.bundle.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Warning"

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Information"

@ -1,4 +1,4 @@
version=1.0.0-beta.106
version=1.0.0-beta.107
server.host=127.0.0.1
server.port=8003
spring.thymeleaf.cache=false

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Information"

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Information"

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Warning"

@ -9,22 +9,31 @@ 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.Linq;
using Vibrant.InfluxDB.Client;
using Vibrant.InfluxDB.Client.Rows;
namespace IoTCenter.Controllers
{
public class AppController : Controller
{
private readonly IConfiguration _configuration;
private readonly IJwtHelper _jwtHelper;
private readonly IRepository<Node> _nodeRepo;
private readonly IRepository<Device> _deviceRepo;
private readonly IHubContext<PageHub> _pageHubContext;
public AppController(IJwtHelper jwtHelper, IRepository<Node> nodeRepo, IRepository<Device> deviceRepo, IHubContext<PageHub> pageHubContext)
public AppController(IConfiguration configuration,
IJwtHelper jwtHelper,
IRepository<Node> nodeRepo,
IRepository<Device> deviceRepo,
IHubContext<PageHub> pageHubContext)
{
this._configuration = configuration;
this._jwtHelper = jwtHelper;
this._nodeRepo = nodeRepo;
this._deviceRepo = deviceRepo;
@ -117,5 +126,37 @@ namespace IoTCenter.Controllers
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<object>();
using (var client = new InfluxClient(new Uri(url), usr, pwd))
{
var fileds = String.Join(',', device.Data.Where(o => o.Type == "Int" || o.Type == "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<DynamicInfluxRow>(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<string>();
foreach (var data in device.Data.Where(o => o.Type == "Int" || o.Type == "Float"))
{
list.Add(new
{
id = data.Key,
label = data.Name,
labels,
data = rows?.Select(o => o.GetField(data.Key)).ToList() ?? new List<object>()
});
}
}
return Json(list);
}
}
}

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Warning"

@ -34,7 +34,7 @@ img.shot.zoom {
max-width:none;
max-height: none;
}
.list.media-list{
.block .list{
margin:0;
}
@ -51,6 +51,8 @@ img.shot.zoom {
.videoContainer #ptz {
position:absolute;
text-align:center;
width:300px;
margin:auto;
left:0;
right:0;
bottom:0;
@ -58,3 +60,13 @@ img.shot.zoom {
.videoContainer table {
margin: 0 auto;
}
.device-desktop.with-modal-dialog .page-content {
overflow: auto;
}
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 394 B

@ -649,18 +649,26 @@
</div>
<template v-for="data in _.orderBy(device.Data,['DisplayOrder','Name'])">
<template v-if="data.Key==='code[]'">
<a v-for="key in JSON.parse(data.Value)" class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.Id,'22call','code='+key.value)">{{key.text}}</a>
<div class="col" v-for="(value, key, index) in _.chain(JSON.parse(data.Value)).groupBy(o => o.text.split('-')[0]).value()">
<div>{{key}}</div>
<div class="card">
<a v-for="btn in value" class="button button-large button-raised button-fill" href="javascript: ;" v-on:click="call(device.Id,'send','code='+btn.value)">
{{btn.text.indexOf('-')>0?btn.text.split('-')[1]:btn.text}}
</a>
</div>
</div>
</template>
</template>
</div>
</div>
</div>
</template>
<template v-if="getDevices('串口控制器').length">
<div class="block-title">串口控制器</div>
<div class="block block-strong">
<div class="row">
<div class="col" v-for="device in getDevices('串口控制器')">
<div class="col-100 tablet-50 desktop-25" v-for="device in getDevices('串口控制器')">
<div class="list">
<ul>
<li>
@ -753,15 +761,20 @@
</template>
</ul>
</div>
<template v-for="data in Device.Data">
<div class="block" v-if="isChart(data)">
<div class="col">
<canvas :id="data.Key" :data-label="data.Name" class="chart"></canvas>
</div>
</div>
</template>
<div class="block-title" v-if="Device.Apis.length">操作</div>
<div class="list" v-if="Device.Apis.length">
<ul v-if="Device.Name==='摄像头'">
<li>
<div class="item-content">
<div class="item-inner">
<a v-if="isApp" style=' width: 100%;' class="button button-large button-fill button-outline color-green external" :href="getUrl('rtmp')">预览</a>
<a v-else style=' width: 100%;' class="button button-large button-fill button-outline color-green" href="javascript:;" v-on:click="flv()">预览</a>
</div>
<div class="block">
<a v-if="isApp" class="button button-large button-fill button-outline color-green external" :href="getUrl('rtmp')">预览</a>
<a v-else class="button button-large button-fill button-outline color-green" href="javascript:;" v-on:click="flv()">预览</a>
</div>
</li>
</ul>
@ -808,10 +821,8 @@
</template>
</template>
<li>
<div class="item-content">
<div class="item-inner">
<button class="button button-large button-fill button-outline" type="submit">{{api.Name}}</button>
</div>
<div class="block">
<button class="button button-large button-fill button-outline" type="submit">{{api.Name}}</button>
</div>
</li>
</ul>
@ -832,23 +843,23 @@
<tr>
<td></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('26up')"><img src="images/up.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('26up')"><img src="images/up.png" /></a></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('24left')"><img src="images/left.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('24left')"><img src="images/left.png" /></a></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('25right')"><img src="images/right.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('25right')"><img src="images/right.png" /></a></td>
<td></td>
</tr>
<tr>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('21zoomin')"><img src="images/zoomin.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('21zoomin')"><img src="images/zoomin.png" /></a></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('27down')"><img src="images/down.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('27down')"><img src="images/down.png" /></a></td>
<td></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mousedown="call('22zoomout')"><img src="images/zoomout.png" /></a></td>
<td><a href="javascript:;" v-on:mouseup="call('28stopturn')" v-on:mouseleave="call('28stopturn')" v-on:mousedown="call('22zoomout')"><img src="images/zoomout.png" /></a></td>
</tr>
</table>
</div>
@ -891,6 +902,7 @@
<script src="lib/dayjs/dayjs.min.js"></script>
<script src="lib/URI.js/URI.min.js"></script>
<script src="lib/flv.js/flv.min.js"></script>
<script src="lib/Chart.js/Chart.bundle.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Warning"

@ -1,5 +1,5 @@
{
"version": "1.0.0-beta.106",
"version": "1.0.0-beta.107",
"Logging": {
"LogLevel": {
"Default": "Warning"

Loading…
Cancel
Save