Former-commit-id: 1c1f4eceb07a085aea5033ba0ebdad7c36e2a6a4
TangShanKaiPing
wanggang 6 years ago
parent 82d337381c
commit 6fdf16c3c5

@ -7,23 +7,14 @@ namespace Application.Domain.Entities
[Display(Name = "整数")]
Int = 10,
[Display(Name = "长整数")]
Long = 20,
[Display(Name = "浮点数")]
Float = 30,
[Display(Name = "布尔")]
Bool = 40,
[Display(Name = "实数")]
Float = 20,
[Display(Name = "字符串")]
String = 50,
[Display(Name = "日期")]
Date = 60,
[Display(Name = "时间")]
DateTime = 70,
[Display(Name = "布尔")]
Bool = 40,
[Display(Name = "键值对")]
SelectList = 80

@ -1239,15 +1239,16 @@ namespace IoT.Shared.DeviceServices.FBee
{
var state = BitConverter.ToInt16(props[0x0080]);
var data1 = device.CreateData(Keys.Warning, state == 1 ? "警报" : "正常", DeviceDataType.String, "状态");
var data2 = device.CreateData(Keys.UnderVoltage, new BitArray(props[0x0080])[3], DeviceDataType.Int, "低电量");
device.AddorUpdateData(data1);
device.AddorUpdateData(data2);
var dto1 = data1.To<EditDataModel>();
dto1.DeviceNumber = device.Number;
var dto2 = data2.To<EditDataModel>();
dto2.DeviceNumber = device.Number;
device.AddorUpdateData(data1);
dataList.Add(dto1);
dataList.Add(dto2);
//var data2 = device.CreateData(Keys.UnderVoltage, new BitArray(props[0x0080])[3], DeviceDataType.Int, "低电量");
//device.AddorUpdateData(data2);
//var dto2 = data2.To<EditDataModel>();
//dto2.DeviceNumber = device.Number;
//dataList.Add(dto2);
}
else if (clusterId == ClusterId.pm25)
{
@ -1305,7 +1306,7 @@ namespace IoT.Shared.DeviceServices.FBee
tempBytes.Add(0x00);
var electricity = BitConverter.ToInt64(tempBytes.ToArray()) / 1000f;
var data1 = device.CreateData(Keys.Electricity, electricity, DeviceDataType.Long, "电量", "kw/h");
var data1 = device.CreateData(Keys.Electricity, electricity, DeviceDataType.Float, "电量", "kw/h");
device.AddorUpdateData(data1);
var dto1 = data1.To<EditDataModel>();
dto1.DeviceNumber = device.Number;

@ -163,7 +163,7 @@ namespace IoTCenter.Controllers
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.Long || o.Type == DeviceDataType.Float)
.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;
@ -171,7 +171,7 @@ namespace IoTCenter.Controllers
.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 == DeviceDataType.Int || o.Type == DeviceDataType.Long || o.Type == DeviceDataType.Float))
foreach (var data in device.Data.Where(o => o.Type == DeviceDataType.Int || o.Type == DeviceDataType.Float))
{
list.Add(new
{

@ -1,24 +1,35 @@
using System;
using System.Linq;
using Application.Domain.Entities;
using Infrastructure.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
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 HomeController : Controller
{
private readonly IConfiguration _cfg;
private readonly IRepository<Node> _nodeRepo;
private readonly IRepository<Device> _deviceRepo;
private readonly IRepository<Data> _dataRepo;
private readonly IRepository<Category> _categoryRepo;
private readonly IRepository<Product> _productRepo;
public HomeController(IRepository<Node> nodeRepo, IRepository<Device> deviceRepo, IRepository<Data> dataRepo, IRepository<Category> categoryRepo, IRepository<Product> productRepo)
public HomeController(IConfiguration cfg,
IRepository<Node> nodeRepo,
IRepository<Device> deviceRepo,
IRepository<Data> dataRepo,
IRepository<Category> categoryRepo,
IRepository<Product> productRepo)
{
this._cfg = cfg;
this._nodeRepo = nodeRepo;
this._deviceRepo = deviceRepo;
this._dataRepo = dataRepo;
@ -32,7 +43,7 @@ namespace IoTCenter.Controllers
return View();
}
public IActionResult GetNodeList()
public JsonResult GetNodeList()
{
var categorys = this._deviceRepo.ReadOnlyTable()
.GroupBy(o => o.Product.Category.Name)
@ -86,21 +97,13 @@ namespace IoTCenter.Controllers
return Json(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
}
//public IActionResult GetNodes()
//{
// var model = this._nodeRepo.ReadOnlyTable()
// .Include(o => o.Devices)
// .ToList();
// return Json(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
//}
[Route("/Node")]
public IActionResult Node(string number)
{
return View(model: number);
}
public IActionResult GetNode(string number)
public JsonResult GetNode(string number)
{
var model = this._nodeRepo.ReadOnlyTable()
.Include(o => o.Scenes)
@ -110,14 +113,27 @@ namespace IoTCenter.Controllers
return Json(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
}
//public IActionResult GetNode(Guid id)
//{
// var model = this._nodeRepo.ReadOnlyTable()
// .Include(o => o.Scenes)
// .Include(o => o.Devices).ThenInclude(o => o.Data)
// //.Include(o => o.Devices).ThenInclude(o => o.Apis).ThenInclude(o => o.Parameters)
// .FirstOrDefault(o => o.Id == id);
// return Json(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
//}
public JsonResult GetChartData(string number, string key, string time)
{
var device = this._deviceRepo.ReadOnlyTable().Include(o => o.Node).Include(o => o.Data).FirstOrDefault(o => o.Number == number);
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 list = new List<object>();
using (var client = new InfluxClient(new Uri(url), usr, pwd))
{
var query = $"select {key} 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>();
var data = rows?.Select(o => o.GetField(key)).ToList() ?? new List<object>();
var model = new { labels, data };
return Json(model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
}
}
}
}

@ -6,11 +6,14 @@ using Infrastructure.Web.SignalR;
using IoT.Shared.Services;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Readers;
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
{
@ -64,10 +67,6 @@ namespace IoTCenter.Services
{
this.DeleteDevice(message);
}
else if (method == Methods.EditDataResponse)
{
this.UpdateData(message);
}
else if (method == Methods.DeleteDataResponse)
{
this.DeleteData(message);
@ -242,6 +241,10 @@ namespace IoTCenter.Services
}
deviceRepo.SaveChanges();
this.Clients.Group("page").SendAsync("UpdateDevice", device.ToJson());
foreach (var dataDto in dataDtoList)
{
this.LogToInfluxdbAsync(dataDto);
}
}
}
}
@ -396,5 +399,61 @@ namespace IoTCenter.Services
this.ServerToClient(connectionId, Methods.ApiCallback, message);
}
}
private async Task LogToInfluxdbAsync(EditDataModel model)
{
if (string.IsNullOrEmpty(model.Value))
{
return;
}
if (model.Type != DeviceDataType.Int && model.Type != DeviceDataType.Float)
{
return;
}
using (var scope = this._applicationService.CreateScope())
{
try
{
var cfg = scope.ServiceProvider.GetService<IConfiguration>();
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)
{
switch (model.Type)
{
case DeviceDataType.Int:
return Convert.ToInt32(model.Value);
case DeviceDataType.Float:
return Convert.ToSingle(model.Value);
default:
return model.Value;
}
}
}
}

@ -168,6 +168,38 @@
</div>
</div>
<div class="row" v-if="ViewModel">
<div class="col-md-6">
<div class="box box-solid">
<div class="box-body row">
<div class="col-md-12">
<canvas id="TemperatureHumidityChart" style="width:100%;height:250px;" :data-device-number="GetDeviceNumber('温湿度传感器')"></canvas>
<div class="description-block">
<span class="description-text">温湿度</span>
</div>
</div>
</div>
</div>
<div class="box box-solid">
<div class="box-body row">
<div class="col-md-12">
<canvas id="EnergyChart" style="width:100%;height:250px;"></canvas>
<div class="description-block">
<span class="description-text">光照</span>
</div>
</div>
</div>
</div>
<div class="box box-solid">
<div class="box-body row">
<div class="col-md-12">
<canvas id="EnergyChart" style="width:100%;height:250px;"></canvas>
<div class="description-block">
<span class="description-text">用电</span>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="box box-solid btns">
<div class="row">
@ -177,13 +209,21 @@
</div>
<hr style="margin: 0;" />
<div class="row">
<div class="col-md-3" v-for="device in ViewModel.Devices">
<button class="btn btn-block btn-info">{{device.Name}}</button>
<div class="col-md-3" v-for="device in GetDevices('三路开关')">
<div class="row" style="background-color:#fff;border:1px solid #eee;border-radius:5px;text-align:center;margin:10px 0;">
<img v-if="GetDataValue(device.Number,'L1状态')=='开'" src="/images/on.png" />
<img v-if="GetDataValue(device.Number,'L1状态')=='关'" src="/images/off.png" />
<img v-if="GetDataValue(device.Number,'L2状态')=='开'" src="/images/on.png" />
<img v-if="GetDataValue(device.Number,'L2状态')=='关'" src="/images/off.png" />
<img v-if="GetDataValue(device.Number,'L3状态')=='开'" src="/images/on.png" />
<img v-if="GetDataValue(device.Number,'L3状态')=='关'" src="/images/off.png" />
</div>
<div class="row" style="text-align:center;">
{{device.Name||device.DisplayName}}
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="box box-solid btns">
<div class="row">
<div class="col-md-2"><span style="display:inline-block;line-height:70px;">插座:</span></div>
@ -192,8 +232,14 @@
</div>
<hr style="margin: 0;" />
<div class="row">
<div class="col-md-3" v-for="device in ViewModel.Devices">
<button class="btn btn-block btn-info">{{device.Name}}</button>
<div class="col-md-3" v-for="device in GetDevices('智能插座')">
<div class="row" style="background-color:#fff;border:1px solid #eee;border-radius:5px;text-align:center;margin:10px 0;">
<img v-if="GetDataValue(device.Number,'状态')=='开'" src="/images/on.png" />
<img v-if="GetDataValue(device.Number,'状态')=='关'" src="/images/off.png" />
</div>
<div class="row" style="text-align:center;">
{{device.Name||device.DisplayName}}
</div>
</div>
</div>
</div>
@ -267,6 +313,47 @@
});
}
</script>
<script>
function UpdateTemperatureHumidityChart() {
var number = $('#TemperatureHumidityChart').attr('data-device-number');
var key = "Temperature";
var time = '30d';
var url = '/Home/GetChartData?number=' + number + '&key=' + key + '&time=' + time;
$.get(url, function (data) {
alert(data);
});
}
function UpdateChart(id, title, data, labels, colors, type) {
var ctx = document.getElementById(id).getContext('2d');
colors = colors || $.map(data, function (item) { return Color16(item); });
var data = {
datasets: [{
label: title,
data: data,
backgroundColor: colors
}],
labels: labels
};
var options = {
responsive: true,
legend: {
position: 'right',
},
title: {
display: true,
text: title
},
animation: {
duration: 0
}
};
var chart = new Chart(ctx, {
type: type,
data: data,
options: options
});
}
</script>
<script>
$('body').on('click', 'button.ajax', function (e) {
var data = $.map($('.switch:checked').toArray(), function (o) { return $(o).attr('data-node-number'); });
@ -378,6 +465,7 @@
onMessage();
connect();
UpdateCamera();
UpdateTemperatureHumidityChart();
});
});
},
@ -414,6 +502,39 @@
var device = Enumerable.from(vm.ViewModel.Devices).where(function (o) { return o.Number === number; }).firstOrDefault();
var data = Enumerable.from(device.Data).where(o => o.Name === '缩放支持').firstOrDefault().Value;
return data === '是';
},
GetDevices(name) {
return Enumerable.from(vm.ViewModel.Devices)
.where(function (o) { return o.Name == name; })
.toArray();
},
GetDevice(name, tag) {
var query = Enumerable.from(vm.ViewModel.Devices);
if (name) {
query = query.where(function (o) { return o.Name === name; });
}
if (tag) {
query = query.where(function (o) { return o.Tag === tag; });
}
return query.firstOrDefault();
},
GetDeviceNumber(name, tag) {
var device = vm.GetDevice(name, tag);
return device == null ? null : device.Number;
},
GetDataValue(number, name) {
var device = Enumerable.from(vm.ViewModel.Devices)
.where(function (o) { return o.Number === number; })
.firstOrDefault();
if (device != null) {
var data = Enumerable.from(device.Data)
.where(function (o) { return o.Name == name })
.firstOrDefault();
if (data != null) {
return data.Value;
}
}
return null;
}
},
destroy() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

@ -23,8 +23,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiChuangService", "IoT\IoTS
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaService", "IoT\IoTServices\MediaService\MediaService.csproj", "{AA841C16-1411-46AA-B755-E838FFF8D2F1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerialPortService", "IoT\IoTServices\SerialPortService\SerialPortService.csproj", "{413D6AE3-690F-4AF7-8FEC-F42399C547E1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SingalDemo", "IoT\IoTServices\SingalDemo\SingalDemo.csproj", "{47208375-960F-41A4-A0EA-0D76F62B9123}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinService", "IoT\IoTServices\WinService\WinService.csproj", "{871CD7E8-19F4-48F9-8124-66F69398C694}"
@ -143,18 +141,6 @@ Global
{AA841C16-1411-46AA-B755-E838FFF8D2F1}.Release|iPhone.Build.0 = Release|Any CPU
{AA841C16-1411-46AA-B755-E838FFF8D2F1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{AA841C16-1411-46AA-B755-E838FFF8D2F1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Debug|iPhone.Build.0 = Debug|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Release|Any CPU.Build.0 = Release|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Release|iPhone.ActiveCfg = Release|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Release|iPhone.Build.0 = Release|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{413D6AE3-690F-4AF7-8FEC-F42399C547E1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{47208375-960F-41A4-A0EA-0D76F62B9123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47208375-960F-41A4-A0EA-0D76F62B9123}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47208375-960F-41A4-A0EA-0D76F62B9123}.Debug|iPhone.ActiveCfg = Debug|Any CPU
@ -225,7 +211,6 @@ Global
{81F8D3B6-6033-45D7-BF23-8FA293FF7D9B} = {2A80F0AD-9ADB-464C-BF31-06E505D1793B}
{7ED73838-258D-4D06-AD34-2B69FA8B703B} = {2A80F0AD-9ADB-464C-BF31-06E505D1793B}
{AA841C16-1411-46AA-B755-E838FFF8D2F1} = {2A80F0AD-9ADB-464C-BF31-06E505D1793B}
{413D6AE3-690F-4AF7-8FEC-F42399C547E1} = {2A80F0AD-9ADB-464C-BF31-06E505D1793B}
{47208375-960F-41A4-A0EA-0D76F62B9123} = {2A80F0AD-9ADB-464C-BF31-06E505D1793B}
{871CD7E8-19F4-48F9-8124-66F69398C694} = {2A80F0AD-9ADB-464C-BF31-06E505D1793B}
{775041E3-9B61-4B22-ABED-EAB48F54C900} = {B39CEABB-9A42-4BA2-A167-665349113986}

Loading…
Cancel
Save