Former-commit-id: 5f9997e16cae1b32cc5a1e7932874f738584e768
TangShanKaiPing
wanggang 6 years ago
parent 361bed687a
commit 75f08d8023

@ -1,12 +1,18 @@
using Application.Domain.Entities;
using Infrastructure.Data;
using Infrastructure.Extensions;
using IoTCenter.ViewModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Drawing;
using System.Globalization;
using System.Linq;
using Vibrant.InfluxDB.Client;
using Vibrant.InfluxDB.Client.Rows;
namespace UserCenter.Controllers
{
@ -45,5 +51,75 @@ namespace UserCenter.Controllers
return Problem(ex.Message);
}
}
[HttpPost]
public IActionResult GetChartData([FromBody]ChartDataRequest model)
{
try
{
var device = this._deviceRepo.ReadOnlyTable().Include(o => o.Data).FirstOrDefault(o => o.Number == model.Number);
var data = device.Data.FirstOrDefault(o => o.Key == model.Key);
var url = this._cfg["influxdb:url"];
var usr = this._cfg["influxdb:usr"];
var pwd = this._cfg["influxdb:pwd"];
var dbName = "iot";
var measurementName = "data";
var datasets = new List<object>();
var labels = new List<string>();
var hours = Convert.ToInt32(DateTime.Now.ToString("%z"));
using (var client = new InfluxClient(new Uri(url), usr, pwd))
{
var query = $"select { model.Key} from {measurementName} where time>now() - {model.Key} and DeviceNumber = '{model.Number}' limit 10000";
var result = client.ReadAsync<DynamicInfluxRow>(dbName, query).Result;
var rows = result.Results.FirstOrDefault()?
.Series.FirstOrDefault()?
.Rows;
datasets.Add(new
{
label = data.Name,
data = rows != null ? rows.Select(o => o.GetField(data.Key)).ToList() : new List<object>(),
backgroundColor = this.GetColor(data.Key),
fill = false
});
if (rows != null)
{
var format = model.Time.StartsWith("1") ? "H:mm" : (model.Time.StartsWith("7") ? "ddd" : "MMM-d");
labels = rows.Select(o => o.Timestamp.Value).Select(o => o.AddHours(hours).ToString(format, new CultureInfo("zh-CN"))).ToList();
}
var response = new
{
datasets,
labels
};
return Ok(response);
}
}
catch (Exception ex)
{
ex.PrintStack();
return Problem(ex.Message);
}
}
private string GetColor(string key)
{
//var randomGen = new Random();
//var names = (KnownColor[])Enum.GetValues(typeof(KnownColor));
//var randomColorName = names[randomGen.Next(names.Length)];
//var randomColor = Color.FromKnownColor(randomColorName);
//return randomColor.Name;
if (key == "Humidity")
{
return Color.FromKnownColor(KnownColor.Green).Name;
}
else if (key == "Electricity")
{
return Color.FromKnownColor(KnownColor.Red).Name;
}
else if (key == "Light")
{
return Color.FromKnownColor(KnownColor.Orange).Name;
}
return Color.FromKnownColor(KnownColor.DarkBlue).Name;
}
}
}

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
namespace IoTCenter.ViewModels
{
public class ChartDataRequest
{
[Required]
public string Number { get; set; }
[Required]
public string Key { get; set; }
[Required]
public string Time { get; set; }
}
}

@ -61,8 +61,12 @@ label > * {
padding-left:0;
padding-right:0;
}
.card-body{
padding:10px;
.card-header{
line-height:27px;
}
.card-header,.card-body {
box-sizing:border-box;
padding: 10px;
}
[class^="weui"] {
box-sizing: initial;

@ -16,9 +16,36 @@
<iot-switch3 v-else-if="device.name==='三路开关'" v-bind:device="device"></iot-switch3>
<iot-socket v-else-if="device.name==='智能插座'" v-bind:device="device"></iot-socket>
<iot-ir v-else-if="device.name==='红外转发器'" v-bind:device="device" v-bind:edit="true"></iot-ir>
<iot-color-light v-else-if="device.name==='调色灯'" v-bind:device="device" v-bind:edit="true"></iot-color-light>
<iot-camera v-else-if="device.name==='摄像头'" v-bind:device="device" v-bind:edit="true"></iot-camera>
<iot-color-light v-else-if="device.name==='调色灯'" v-bind:device="device"></iot-color-light>
<iot-camera v-else-if="device.name==='摄像头'" v-bind:device="device"></iot-camera>
<iot-serial-port v-else-if="device.name==='串口控制器'" v-bind:device="device" v-bind:edit="true"></iot-serial-port>
</div>
</div>
<div class="row" v-if="device&&hasChart">
<template v-for="data in device.data">
<div class="col-12" v-if="data.type===10||data.type===20">
<div class="card" style="margin:10px;">
<div class="card-header">
{{data.name}}(单位:{{data.unit}})
</div>
<div class="card-body">
<div class="weui-tab">
<div class="weui-navbar">
<a href="javascript:;" class="weui-tabbar__item" v-on:click="changeTime(data.key,'1d')">
<p class="weui-tabbar__label">近24小时</p>
</a>
<a href="javascript:;" class="weui-tabbar__item" v-on:click="changeTime(data.key,'7d')">
<p class="weui-tabbar__label">近7日</p>
</a>
<a href="javascript:;" class="weui-tabbar__item" v-on:click="changeTime(data.key,'30d')">
<p class="weui-tabbar__label">近30日</p>
</a>
</div>
</div>
<canvas class="chart" style="width:60%;max-width:100%;" :id="device.number+'-'+data.key"></canvas>
</div>
</div>
</div>
</template>
</div>
</div>

@ -9,10 +9,15 @@
};
},
mounted: function () {
var vm = this;
axios.post(this.url)
.then(function (response) {
store.commit('setDevice', response.data);
$('title').text(response.data.displayName);
vm.$nextTick(function () {
weui.tab('.weui-tab');
vm.updateChart();
});
})
.catch(function (error) {
})
@ -23,11 +28,75 @@
destroyed: function () {
store.commit('setDevice', null);
},
methods: {
methods: {
updateChart: function () {
var keys = Enumerable.from(this.device.data).where(function (o) {
return o.type === 10 || o.type === 20;
}).toArray();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
this.changeTime(key, '1d');
}
},
changeTime: function (key, time) {
var url = '/IoTCenter/api/v1/Device/GetChartData';
var data = {
number:this.device.number,
key: key,
time: time
};
axios.post(url,data, { crossDomain: true })
.then(function (response) {
var data = response.data;
UpdateChartInternal(key, data);
console.log('折线图更新成功');
})
.catch(function (error) {
console.log(error);
});
},
UpdateChartInternal(key, data) {
var canvas = document.getElementById(this.device.number + '-' + key);
var chart;
Chart.helpers.each(Chart.instances, function (instance) {
if (instance.chart.canvas.id === canvas.id) {
chart = instance;
}
});
if (chart) {
chart.data = data;
chart.update();
}
else {
var ctx = canvas.getContext('2d');
var options = {
responsive: true,
legend: {
position: 'bottom'
},
title: {
display: false,
text: title
},
animation: {
duration: 0
}
};
chart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
}
}
},
computed: {
device: function () {
return store.state.device;
},
hasChart: function () {
var o = this.device;
return o.name === '温湿度传感器' || o.name === 'PM2.5感应器' || o.name === '光强检测器' || o.name === '智能插座';
}
}
});

@ -4,7 +4,7 @@
{{device.displayName}}
</div>
<div class="card-body" style="padding:0;">
<div class="row video-container" style="width:100%;height:240px;margin: 0 auto;background-color:#333;position:relative;">
<div class="row video-container" style="width:320px;height:240px;margin: 0 auto;background-color:#333;position:relative;">
<video controls muted autoplay :class="device.number" v-if="isFlvSupported" v-on:volumechange="volumeChange($event)" style="width:100%;height:100%;object-fit:contain;"></video>
<template v-else>
<canvas width="1080" height="720" style="width:100%;height:100%;object-fit:contain;background: #333;margin:0 auto;" :class="device.number" v-on:click="showControls()"></canvas>
@ -26,7 +26,7 @@
</div>
</template>
</div>
<div style="box-sizing: border-box;width: 100%;margin: 5px auto;" :class="'row ptz '+ device.number">
<div style="box-sizing: border-box;width: 320px;margin: 5px auto;" :class="'row ptz '+ device.number">
<table style="width: 100%; height:100px;">
<tr>
<td colspan="2" style="text-align:center;"><button class="weui-btn weui-btn_mini weui-btn_default" v-on:click="execApi(model.number,'/Onvif/StartRecord')">启动推流</button></td>

Loading…
Cancel
Save