|
|
|
@ -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)
|
|
|
|
|