Former-commit-id: c8bd677165dbf2783c6f21f91d4955d89cc6cdc6
TangShanKaiPing
wanggang 6 years ago
parent 00a86984a9
commit de19cccb06

@ -318,13 +318,13 @@ namespace IoTCenter.Services
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
private async Task LogToInfluxdbAsync(EditDataModel model, string deviceNumber)
public async Task LogToInfluxdbAsync(Data data)
{
if (string.IsNullOrEmpty(model.Value))
if (string.IsNullOrEmpty(data.Value))
{
return;
}
if (model.Type != DeviceDataType.Int && model.Type != DeviceDataType.Float)
if (data.Type != DeviceDataType.Int && data.Type != DeviceDataType.Float)
{
return;
}
@ -341,9 +341,10 @@ namespace IoTCenter.Services
{
Timestamp = DateTime.UtcNow
};
row.Fields.Add("DeviceNumber", deviceNumber);
row.Fields.Add("DeviceName", model.Name);
row.Fields.Add(model.Key, this.GetDataValue(model));
var device = this._deviceRepo.ReadOnlyTable().FirstOrDefault(o => o.Id == data.DeviceId);
row.Fields.Add("DeviceNumber", device.Number);
row.Fields.Add("DeviceName", device.Name);
row.Fields.Add(data.Key, this.GetDataValue(data));
await client.WriteAsync(dbName, measurementName, new List<DynamicInfluxRow> { row });
}
@ -353,7 +354,7 @@ namespace IoTCenter.Services
}
}
private object GetDataValue(EditDataModel model)
private object GetDataValue(Data model)
{
return model.Type switch
{

@ -13,6 +13,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using Vibrant.InfluxDB.Client;
@ -175,6 +176,52 @@ namespace IoTCenter.Controllers
}
}
public IActionResult GetChartData(string number, string time)
{
var device = this._deviceRepo.ReadOnlyTable().Include(o => o.Data).FirstOrDefault(o => o.Number == number);
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 == 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<DynamicInfluxRow>(dbName, query).Result;
var rows = result.Results.FirstOrDefault()?
.Series.FirstOrDefault()?
.Rows;
foreach (var data in device.Data.Where(o => o.Type == DeviceDataType.Int || o.Type == DeviceDataType.Float))
{
list.Add(new
{
label = data.Name,
data = rows != null ? rows.Where(o => o.Fields.ContainsKey(data.Key)).Select(o => o.GetField(data.Key)).ToList() : new List<object>(),
backgroundColor = this.GetColor(data.Key),
fill = false
});
}
var labels = rows != null ? rows.Select(o => o.Timestamp.Value).Select(o => o.ToString("MM-dd HH:mm")).ToList().Distinct() : new List<string>();
var model = new
{
datasets = list,
labels = labels
};
return Json(model);
}
}
private string GetColor(object 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;
}
/************************************************************/
public IActionResult GetDevice(string token, string number)

@ -1,13 +1,19 @@
using Application.Domain.Entities;
using CSScriptLib;
using Hangfire;
using Infrastructure.Data;
using Infrastructure.Events;
using Infrastructure.Extensions;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Vibrant.InfluxDB.Client;
using Vibrant.InfluxDB.Client.Rows;
namespace IoTCenter.Services
{
@ -172,12 +178,14 @@ namespace IoTCenter.Services
{
this.Notify(message);
this.TiggerHandle(message);
this.LogData(message.Data);
}
public void Handle(EntityUpdatedEvent<Data> message)
{
this.Notify(message);
this.TiggerHandle(message);
this.LogData(message.Data);
}
public void Handle(EntityDeletedEvent<Data> message)
@ -277,5 +285,65 @@ namespace IoTCenter.Services
}
});
}
private void LogData(Data data)
{
using var scope = this._sp.CreateScope();
var _cfg = scope.ServiceProvider.GetRequiredService<IConfiguration>();
var url = _cfg["influxdb:url"];
var usr = _cfg["influxdb:usr"];
var pwd = _cfg["influxdb:pwd"];
var deviceRepo = scope.ServiceProvider.GetRequiredService<IRepository<Device>>();
var device = deviceRepo.ReadOnlyTable().FirstOrDefault(o => o.Id == data.DeviceId);
Task.Run(async () =>
{
try
{
if (string.IsNullOrEmpty(data.Value))
{
return;
}
if (data.Type != DeviceDataType.Int && data.Type != DeviceDataType.Float)
{
return;
}
try
{
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", device.Number);
row.Fields.Add("DeviceName", device.Name);
row.Fields.Add(data.Key, this.GetDataValue(data));
await client.WriteAsync(dbName, measurementName, new List<DynamicInfluxRow> { row });
}
catch (Exception ex)
{
ex.PrintStack();
}
}
catch (Exception ex)
{
ex.PrintStack();
}
});
}
private object GetDataValue(Data model)
{
return model.Type switch
{
DeviceDataType.Int => Convert.ToInt32(model.Value),
DeviceDataType.Float => Convert.ToSingle(model.Value),
_ => model.Value,
};
}
}
}

@ -699,6 +699,20 @@
</div>
</div>
</div>
<div class="row">
<div class="col-md-6" v-for="device in GetChartDevices()">
<div class="card" style="height:220px;">
<div class="card-header">
<div class="card-title">
{{device.DisplayName}}
</div>
</div>
<div class="card-body">
<canvas class="chart" :id="device.Number"></canvas>
</div>
</div>
</div>
</div>
</template>
</div>
@section scripts{

Binary file not shown.

@ -84,6 +84,59 @@ function UpdateCamera() {
}
}
}
function UpdateChart(deviceNumber) {
$('canvas.chart').each(function () {
var canvas = this;
var number = canvas.id;
if (!deviceNumber || deviceNumber === number) {
var device = vm.GetDevice(number);
var time = time || '30d';
var url = iotCenter + '/App/GetChartData?time=' + time + '+&number=' + number;
axios.post(url, { crossDomain: true })
.then(function (response) {
var data = response.data;
UpdateChartInternal(canvas, device.DisplayName,data);
})
.catch(function (error) {
console.log(error);
toastr.error(error)
});
}
});
}
function UpdateChartInternal(canvas, title, data) {
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
}
};
var chart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
}
}
function playHls(videoElement) {
var number = $('#camera').val();
var device = Enumerable.from(vm.model.Devices).where(function (o) { return o.Number === number; }).firstOrDefault();
@ -332,6 +385,7 @@ function init() {
connect();
this.$nextTick(function () {
UpdateCamera();
UpdateChart();
});
},
methods: {
@ -345,6 +399,17 @@ function init() {
.where(function (o) { return o.Name == name; })
.toArray();
},
GetDevice(nameOrNumber) {
return Enumerable.from(this.model.Devices)
.where(function (o) { return o.Name === nameOrNumber || o.Number === nameOrNumber; })
.firstOrDefault();
},
GetChartDevices() {
return Enumerable.from(this.model.Devices)
.where(function (o) { return o.Name === '温湿度传感器' || o.Name === '粉尘检测器' || o.Name === '光强检测器' || o.Name === '智能插座'; })
.orderBy('o=>o.ProductId')
.toArray();
},
GetDataValue(number, name) {
var device = Enumerable.from(this.model.Devices)
.where(function (o) { return o.Number === number; })

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ce079c7515beaae4fb0ed787ff8f8ed5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4cefe37c7668e1e4d9b28297ce380c40
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9c84f344a9bebe543a3721e46d8093d9
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.
Loading…
Cancel
Save