Former-commit-id: 299ce789cb272ab624b66b87718cf0e9da56915c
TangShanKaiPing
wanggang 6 years ago
parent a4626b8825
commit bbdb4dc259

@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Infrastructure.Extensions
{
@ -8,5 +11,38 @@ namespace Infrastructure.Extensions
{
return Convert.ToString(@byte, 2).PadLeft(8, '0');
}
public static int ToInt(this IEnumerable<byte> bytes)
{
return BitConverter.ToInt16(bytes.ToArray());
}
public static int ReadInt(this Stream bytes)
{
var buffer = new byte[2];
bytes.Read(buffer);
return BitConverter.ToInt16(buffer);
}
public static string ReadASIIString(this Stream bytes, int length)
{
var buffer = new byte[length];
bytes.Read(buffer);
return new string(buffer.Select(o => (char)o).ToArray());
}
public static string ReadHexString(this Stream bytes, int length)
{
var buffer = new byte[length];
bytes.Read(buffer);
return BitConverter.ToString(buffer).Replace("-", "").ToLower();
}
public static byte[] Read(this Stream bytes, int length)
{
var buffer = new byte[length];
bytes.Read(buffer);
return buffer;
}
}
}

@ -0,0 +1,43 @@
namespace Application.Domain.Entities
{
public enum DataType
{
uint1 = 0x20,
uint2,
uint3,
uint4,
uint5,
uint6,
uint7,
uint8,
int1,
int2,
int3,
int4,
int5,
int6,
int7,
int8,
enum1,
enum2,
float2 = 0x38,
float4,
float8,
bitstring = 0x41,
characterstring,
longbitstring,
longcharacterstring,
sequence = 0x4c,
set = 0x50,
bag,
time4 = 0xe0,
date4,
utctime4,
cluster2 = 0xe8,
attribute2,
bacnet4,
ieee1 = 0xf0,
m16,
unknown = 0xff
}
}

@ -0,0 +1,20 @@
using Infrastructure.Domain;
using System.Collections.Generic;
namespace Application.Domain.Entities
{
public class DeviceId : BaseEntity
{
public static List<DeviceId> List { get; set; } = new List<DeviceId>();
static DeviceId()
{
List.Add(new DeviceId { Name = "外挂式插座", Category = "电器", Icon = "socket", RawCategory = "Generic", RawName = "Smart plug", RawDeviceId = 0x0051 });
}
public string Name { get; set; }
public string Icon { get; set; }
public string Category { get; set; }
public int RawDeviceId { get; set; }
public string RawCategory { get; set; }
public string RawName { get; set; }
}
}

@ -0,0 +1,63 @@
using Infrastructure.Domain;
using Infrastructure.Extensions;
using System;
using System.IO;
namespace Application.Domain.Entities
{
public class FBeeDevice : BaseEntity
{
public int DataType { get; set; }
public int DataLength { get; set; }
public int Address { get; set; }
public int Endpoint { get; set; }
public int ProfileId { get; set; }
public int DeviceId { get; set; }
public int Status { get; set; }
public int NameLength { get; set; }
public string RawName { get; set; }
public int Online { get; set; }
public string IEEE { get; set; }
public int SNLength { get; set; }
public string RawSN { get; set; }
public int ZoneType { get; set; }
public int Power { get; set; }
public string Data { get; set; }
public string Safe { get; set; }
public string RawValue { get; set; }
//
public string Sn { get; set; }
public string Name { get; set; }
public int Number { get; set; }
public string Icon { get; set; }
public int CategoryNumber { get; set; }
public string CategoryName { get; set; }
public void Update(byte[] data)
{
using (var ms = new MemoryStream(data))
{
this.DataType = ms.ReadByte();
this.DataLength = ms.ReadByte();
this.Address = ms.ReadInt();
this.Endpoint = ms.ReadByte();
this.ProfileId = ms.ReadInt();
this.DeviceId = ms.ReadInt();
this.Status = ms.ReadByte();
this.NameLength = ms.ReadByte();
this.RawName = ms.ReadASIIString(this.NameLength);
this.Online = ms.ReadByte();
this.IEEE = ms.ReadHexString(8);
this.SNLength = ms.ReadByte();
this.RawSN = ms.ReadHexString(this.SNLength);
this.ZoneType = ms.ReadByte();
this.Power = ms.ReadByte();
this.Data = ms.ReadHexString(4);
this.Safe = ms.ReadHexString(2);
this.RawValue = BitConverter.ToString(data);
}
}
}
}

@ -0,0 +1,10 @@
namespace Application.Domain.Entities
{
public class MessageType
{
public const int DeviceResponse = 0x01;
public const int DevicePowerResponse = 0x07;
public const int DeviceNotify = 0x70;
public const int DeviceNotiryExt = 0x72;
}
}

@ -7,7 +7,7 @@ using Infrastructure.Web.Mvc;
using Microsoft.AspNetCore.Mvc;
using SPService.Applicaiton.Models;
namespace LiChuangService.Areas.Controllers
namespace FBeeService.Areas.Controllers
{
[Area("Admin")]
public class HomeController : CrudController<Gateway, PagedListModel<EditGatewayModel>, EditGatewayModel, EditGatewayModel>

@ -13,17 +13,17 @@ using Polly;
using SPService.Applicaiton.Models;
using Swashbuckle.AspNetCore.Annotations;
namespace LiChuangService.Controllers
namespace FBeeService.Controllers
{
public class HomeController : Controller
{
private readonly IRepository<Gateway> _cameraRepo;
private readonly IRepository<FBeeDevice> _repo;
private readonly IHttpClientFactory _httpClientFactory;
private readonly DeviceService _deviceService;
public HomeController(IHttpClientFactory httpClientFactory, DeviceService deviceService, IRepository<Gateway> cameraRepo)
public HomeController(IHttpClientFactory httpClientFactory, DeviceService deviceService, IRepository<FBeeDevice> repo)
{
this._cameraRepo = cameraRepo;
this._repo = repo;
this._httpClientFactory = httpClientFactory;
this._deviceService = deviceService;
}
@ -34,7 +34,7 @@ namespace LiChuangService.Controllers
{
this._deviceService.Notify();
});
return View();
return View(this._repo.ReadOnlyTable().ToList());
}
#region api

@ -17,4 +17,6 @@
<ProjectReference Include="..\..\IoT.Shared\IoT.Shared.csproj" />
<ProjectReference Include="..\..\IoT.UI.Shard\IoT.UI.Shard.csproj" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties libman_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project>

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
namespace LiChuangService
namespace FBeeService
{
public static class CommandHelper
{

@ -1,4 +1,4 @@
namespace LiChuangService
namespace FBeeService
{
public static class Crc16
{

@ -1,5 +1,8 @@
using Application.Domain.Entities;
using Application.Models;
using Application.Domain.Entities;
using Infrastructure.Data;
using Infrastructure.Extensions;
using Infrastructure.Models;
@ -9,6 +12,7 @@ using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
@ -19,7 +23,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace LiChuangService
namespace FBeeService
{
public class DeviceService : IDisposable
{
@ -194,7 +198,7 @@ namespace LiChuangService
var gateway = repo.Table().FirstOrDefault(o => o.Sn == sn);
if (gateway == null)
{
gateway = new Gateway { Sn = sn, Ip = ip };
gateway = new Gateway { Sn = sn, Ip = ip, Enable = true };
repo.Add(gateway);
repo.SaveChanges();
}
@ -220,8 +224,8 @@ namespace LiChuangService
if (client.Client.Connected)
{
client.Client.Close();
this.Connect(gateway.Sn, client);
}
this.Connect(gateway.Sn, client);
}
else
{
@ -256,10 +260,6 @@ namespace LiChuangService
private void Connect(string sn, TcpClientWrapper client)
{
if (client.Client.Connected)
{
client.Client.Close();
}
try
{
client.Client.Connect(client.Ip, 8001);
@ -275,6 +275,9 @@ namespace LiChuangService
var buffer = new byte[512];
var length = stream.Read(buffer);
var data = buffer.ToList().Take(length).ToArray();
Console.WriteLine($"response:{BitConverter.ToString(data)}");
var test = new byte[] {
0x16,0x00, 0x34, 0xF5, 0x41, 0x11, 0xFE, 0x82, 0x0D, 0x02, 0x42 ,0x20 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x01 ,0x00 ,0x00 ,0x00 };
this.Handle(sn, data);
}
catch (Exception ex)
@ -311,113 +314,115 @@ namespace LiChuangService
private void Handle(string sn, byte[] data)
{
Console.WriteLine($"response:{BitConverter.ToString(data)}");
if (data[0] == 0x01)//获取设备返回值
var length = 2 + data[1];
if (data.Length > length)
{
var length = Convert.ToInt32(data[1]);
Handle(sn, data.Skip(length).ToArray());
}
if (data[0] == 0x70)//设备上报
else
{
this.HandleInternal(sn, data.Take(length).ToArray());
}
//var list = new List<byte[]>();
//for (int i = 0; i < data.Length; i++)
//{
// if ((i + 3) < data.Length && data[i] == 0xfe && data[i + 1] == 0xa5)
// {
// var length = data[i + 3];
// this.HandleInternal(data.Skip(i).Take(5 + length).ToArray());
// }
//}
}
private void HandleInternal(byte[] data)
private void HandleInternal(string sn, byte[] data)
{
Console.WriteLine($"read:{BitConverter.ToString(data).Replace("-", " ")}");
var type = data[2];
var command = data[4];
if (command == 0x0c)//16位地址
{
this._address = this._address ?? data.ToList().Skip(5).Take(8).ToArray();
this._addressValue = BitConverter.ToString(this._address).Replace("-", "");
this.SearchNodeStatus();
}
else if (command == 0x15)//节点状态
{
var status = data.ToList().Skip(14).Take(100).ToArray();
for (int i = 0; i < 100; i++)
{
if (status[i] == 0x01)
{
Console.WriteLine($"node {i + 1} online");
this.SearchNodeType(i + 1);
}
else if (status[i] == 0x02)
{
Console.WriteLine($"node {i + 1} offline");
}
}
}
else if (command == 0x17)//读取
using (var ms = new MemoryStream(data))
{
var nodeNumber = data[14];
if (data.Length == 22 && data[18] == 0xff)//读类型命令返回值
var responseType = ms.ReadByte();
var dataLength = ms.ReadByte();
var deviceNumber = ms.ReadInt();
var endpoint = ms.ReadByte();
using (var scope = _applicationServices.CreateScope())
{
var nodeType = data[17];
this._types[nodeNumber] = nodeType;
if (nodeType == 0x02)
var deviceRepo = scope.ServiceProvider.GetService<IRepository<FBeeDevice>>();
var device = deviceRepo.Table().FirstOrDefault(o => o.Number == deviceNumber);
if (device == null)
{
Console.WriteLine($"node {nodeNumber} is switch 2");
this.SearchSwitchStatus(nodeNumber, 0x02);
Console.WriteLine($"{deviceNumber} dose not save in database");
}
else if (nodeType == 0x03)
if (responseType == MessageType.DeviceResponse)//获取设备返回值
{
Console.WriteLine($"node {nodeNumber} is socket 1");
this.SearchSwitchStatus(nodeNumber, 0x10);
}
else if (nodeType == 0x04)
{
Console.WriteLine($"node {nodeNumber} is socket 2");
this.SearchSwitchStatus(nodeNumber, 0x10);
}
else
{
Console.WriteLine($"unknown type:{nodeType}");
}
}
if (data[15] == 0x01)
{
var nodeType = this._types[nodeNumber];
var statusData = data[17];
NotifyModel model = null;
if (nodeType == 0x02)
{
Console.WriteLine($"~~~node {nodeNumber},switch 2 status:{statusData}");
var switchStatus = statusData.ToBitString();
model = CreateModel("二路灯开关", this._addressValue + "-" + nodeNumber, "switch2", "switch");
model.Data.Add(new DataModel { Type = DataValueType.Text.ToString(), Key = "status1", Name = "L1状态", Value = switchStatus[7] == '1' ? "开" : "关", DisplayOrder = 1 });
model.Data.Add(new DataModel { Type = DataValueType.Text.ToString(), Key = "status2", Name = "L2状态", Value = switchStatus[6] == '1' ? "开" : "关", DisplayOrder = 2 });
}
else if (nodeType == 0x03)
{
Console.WriteLine($"~~~node {nodeNumber},socket 1 status:{statusData}");
model = CreateModel("一路插座", this._addressValue + "-" + nodeNumber, "socket1", "socket");
model.Data.Add(new DataModel { Type = DataValueType.Text.ToString(), Key = "status", Name = "状态", Value = statusData == 0x01 ? "开" : "关", DisplayOrder = 1 });
}
else if (nodeType == 0x04)
{
Console.WriteLine($"~~~node {nodeNumber},socket 2 status:{statusData}");
model = CreateModel("二路插座", this._addressValue + "-" + nodeNumber, "socket2", "socket");
model.Data.Add(new DataModel { Type = DataValueType.Text.ToString(), Key = "status", Name = "状态", Value = statusData == 0x01 ? "开" : "关", DisplayOrder = 1 });
var profileId = ms.ReadInt();
var deviceId = ms.ReadInt();
var deviceType = DeviceId.List.FirstOrDefault(o => o.RawDeviceId == deviceId);
if (deviceType == null)
{
Console.WriteLine($"{deviceId} dose not config in database");
}
else
{
if (device == null)
{
device = new FBeeDevice
{
Sn = sn,
Number = deviceNumber,
Name = deviceType.Name,
Icon = deviceType.Icon,
CategoryNumber = deviceType.RawDeviceId,
CategoryName = deviceType.Category
};
deviceRepo.Add(device);
}
device.Update(data);
}
}
else
else if (responseType == MessageType.DeviceNotify || responseType == MessageType.DeviceNotiryExt)//设备上报
{
Console.WriteLine($"unknown type:{nodeType}");
var clusterId = ms.ReadInt();
if (device != null)
{
var reportCount = ms.ReadByte();
var props = new Dictionary<int, byte[]>();
for (int i = 0; i < reportCount; i++)
{
var propId = ms.ReadInt();
var propDataTypeValue = ms.ReadByte();
int propDataLength;
if (Enum.IsDefined(typeof(DataType), propDataTypeValue))
{
var propDataType = (DataType)propDataTypeValue;
if (propDataType == DataType.bitstring || propDataType == DataType.characterstring)
{
propDataLength = ms.ReadByte();
}
else if (propDataType == DataType.longbitstring || propDataType == DataType.longcharacterstring)
{
propDataLength = ms.ReadInt();
}
else if (propDataType == DataType.sequence || propDataType == DataType.set || propDataType == DataType.bag)
{
propDataLength = ms.ReadInt();
}
else if (propDataType == DataType.unknown)
{
propDataLength = 0;
}
else
{
propDataLength = Convert.ToInt32(Regex.Match(propDataType.GetName(), @"\d+").Groups[1].Value);
}
}
else
{
propDataLength = 1;
}
var propData = ms.Read(propDataLength);
props.Add(propId, propData);
}
}
}
if (model != null)
else if (responseType == MessageType.DevicePowerResponse)
{
this.NotifyServer(model);
var powerStatus = ms.ReadByte();
if (device != null)
{
device.Power = powerStatus;
}
}
deviceRepo.SaveChanges();
}
}
}
@ -519,8 +524,15 @@ namespace LiChuangService
private void Write(TcpClient client, byte[] command)
{
Console.WriteLine($"write:{BitConverter.ToString(command).Replace("-", " ")}");
client.GetStream().Write(command);
if (client.Connected)
{
Console.WriteLine($"write:{BitConverter.ToString(command).Replace("-", " ")}");
client.GetStream().Write(command);
}
else
{
Console.WriteLine($"can not write:{BitConverter.ToString(command).Replace("-", " ")}");
}
}
private NotifyModel CreateModel(string name, string number, string path, string icon)

@ -5,7 +5,7 @@ using Infrastructure.Extensions;
using Infrastructure.Web.Hosting;
using Microsoft.AspNetCore;
namespace LiChuangService
namespace FBeeService
{
public class Program
{

@ -6,8 +6,9 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
namespace LiChuangService
namespace FBeeService
{
public class Startup : ShardStartup
{
@ -31,6 +32,11 @@ namespace LiChuangService
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Gateway>().HasIndex(o => o.Sn).IsUnique();
modelBuilder.Entity<FBeeDevice>().HasIndex(o => new { o.Sn, o.Number }).IsUnique();
}
public override void Seed(DbContext dbContext, IServiceProvider serviceProvider, IConfiguration configuration)
{
}
}
}

@ -0,0 +1,25 @@
@model List<FBeeDevice>
<table>
<tr>
<th>Sn</th>
<th>地址</th>
<th>开关</th>
<th>RawValue</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Sn</td>
<td>@item.Address</td>
<td>@item.Power</td>
<td>@item.RawValue</td>
</tr>
}
</table>
@section styles{
<style>
td {
padding: 5px 1em;
}
</style>
}

@ -7,7 +7,7 @@ using Infrastructure.Web.Mvc;
using Microsoft.AspNetCore.Mvc;
using SPService.Applicaiton.Models;
namespace LiChuangService.Areas.Controllers
namespace FBeeService.Areas.Controllers
{
[Area("Admin")]
public class HomeController : CrudController<Button, PagedListModel<EditButtonModel>, EditButtonModel, EditButtonModel>

@ -13,7 +13,7 @@ using Polly;
using SPService.Applicaiton.Models;
using Swashbuckle.AspNetCore.Annotations;
namespace LiChuangService.Controllers
namespace FBeeService.Controllers
{
public class HomeController : Controller
{

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
namespace LiChuangService
namespace FBeeService
{
public static class CommandHelper
{

@ -1,4 +1,4 @@
namespace LiChuangService
namespace FBeeService
{
public static class Crc16
{

@ -11,7 +11,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace LiChuangService
namespace FBeeService
{
public class DeviceService : IDisposable
{

@ -5,7 +5,7 @@ using Infrastructure.Extensions;
using Infrastructure.Web.Hosting;
using Microsoft.AspNetCore;
namespace LiChuangService
namespace FBeeService
{
public class Program
{

@ -7,7 +7,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace LiChuangService
namespace FBeeService
{
public class Startup : ShardStartup
{

Loading…
Cancel
Save