using System;
|
using System.Collections.Generic;
|
using System.Text;
|
using Newtonsoft.Json.Linq;
|
|
namespace ZigBee.Device
|
{
|
[System.Serializable]
|
public class CommonDevice
|
{
|
#region 需要保存的变量
|
|
/// <summary>
|
/// 是否是自定义图片
|
/// </summary>
|
public bool IsCustomizeImage = false;
|
/// <summary>
|
/// 设备图片
|
/// </summary>
|
public string IconPath = string.Empty;
|
/// <summary>
|
/// 设备图片--在线或者选中状态
|
/// </summary>
|
/// <value>The online icon path.</value>
|
[Newtonsoft.Json.JsonIgnore]
|
public string OnlineIconPath
|
{
|
get
|
{
|
if (string.IsNullOrEmpty(IconPath))
|
{
|
return string.Empty;
|
}
|
var pathArr = IconPath.Split('.');
|
if (pathArr == null || string.IsNullOrEmpty(pathArr[0]))
|
{
|
return string.Empty;
|
}
|
return $"{pathArr[0]}Selected.png";
|
}
|
}
|
/// <summary>
|
/// 当前网关的ID
|
/// </summary>
|
public string CurrentGateWayId;
|
/// <summary>
|
/// 当前设备类型
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public DeviceType Type = DeviceType.UnKown;
|
/// <summary>
|
/// 设备的功能类型(此类型目前只针对继电器回路有效,默认未指定)
|
/// </summary>
|
public DeviceFunctionType DfunctionType = DeviceFunctionType.A未定义;
|
/// <summary>
|
/// MAC地址
|
/// </summary>
|
public string DeviceAddr;
|
/// <summary>
|
/// 设备端口号
|
/// </summary>
|
public int DeviceEpoint;
|
/// <summary>
|
/// 设备id
|
/// <para>258:color dimmable light,调关灯 </para>
|
/// <para>10:Door lock,门锁</para>
|
/// <para>514:Window covering device,窗帘</para>
|
/// <para>515:Window covering controller,窗帘控制器</para>
|
/// <para>769:Thermostat,恒温面板/空调</para>
|
/// <para>770:Temperature Sensor,温度传感器</para>
|
/// <para>775:Temperature Sensor,湿度传感器</para>
|
/// <para>262:Light sensor,光照传感器</para>
|
/// <para>1026:sensor,传感器,具体类型的传感器DeviceType来区分</para>
|
/// </summary>
|
public int DeviceID;
|
/// <summary>
|
/// 该字段主要针对IAS安防设备设立。所有IAS安防设备共用一个DeviceID为1026。所以要区分子设备类型,需要该字段。
|
/// 瞬间数据上报的传感器 (MomentStatus=1 TriggerZoneStatus>=1<报警>)
|
/// <para>13:Motion sensor (运动传感器)</para>
|
/// <para>40 Fire sensor 烟雾传感器</para>
|
/// <para>42 Water sensor 水侵传感器</para>
|
/// <para>43 Carbon Monoxide (CO) 燃气传感器</para>
|
/// <para>44 Personal emergency device 紧急按钮</para>
|
/// <para>277 Key fob 钥匙扣</para>
|
/// <para>持续数据上报(MomentStatus=0 TriggerZoneStatus>=1<报警> TriggerZoneStatus=0<取消报警>)</para>
|
/// <para>21: Door/Window 门窗传感器(有21和22,这里没有写错)</para>
|
/// <para>22:Door/Window 门窗传感器(有21和22,这里没有写错</para>
|
/// <para>541 球型移动传感器</para>
|
/// </summary>
|
public int IasDeviceType;
|
/// <summary>
|
/// 设备名称,以设备的MAC命名
|
/// </summary>
|
public string DeviceName = "UnKown";
|
/// <summary>
|
/// 设备端点名称,以设备端点名称命名
|
/// </summary>
|
public string DeviceEpointName = "UnKown";
|
/// <summary>
|
/// 用于判断设备的zigbee协议版本。
|
///<para>49246:ZLL1.0标准设备。</para>
|
///<para>260: ZHA1.2标准设备、 Z3.0标准设备。</para>
|
///<para>41440:ZGP3.0标准设备。</para>
|
///<para>265:ZSE1.4标准设备。</para>
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public int Profile;
|
/// <summary>
|
/// 0:设备不在线
|
/// <para>1:设备在线</para>
|
/// </summary>
|
public int IsOnline;
|
/// <summary>
|
/// 1:路由设备
|
/// <para>2:终端设备,电池设备</para>
|
/// </summary>
|
public int ZigbeeType;
|
/// <summary>
|
/// 当前运行程序版本信息。 最大64字节
|
/// </summary>
|
public int ImgVersion;
|
/// <summary>
|
/// 硬件版本
|
/// </summary>
|
public int HwVersion;
|
/// <summary>
|
/// 当前镜像类型id
|
/// </summary>
|
public int ImgTypeId;
|
/// <summary>
|
/// 驱动代码。为0时,表示zigbee协调器设备。其他值表示为虚拟驱动设备
|
/// </summary>
|
public int DriveCode;
|
/// <summary>
|
/// 生产商名字
|
/// </summary>
|
public string ManufacturerName = string.Empty;
|
/// <summary>
|
/// 模块ID(这个东西也叫【型号码】)
|
/// </summary>
|
public string ModelIdentifier = string.Empty;
|
/// <summary>
|
/// 生产日期
|
/// </summary>
|
public string ProductionDate = string.Empty;
|
/// <summary>
|
/// 电源
|
/// </summary>
|
public int PowerSource = -1;
|
/// <summary>
|
/// 序列号
|
/// </summary>
|
public string SerialNumber = string.Empty;
|
/// <summary>
|
/// 输入簇列表
|
/// </summary>
|
public List<InClusterObj> InClusterList = new List<InClusterObj>();
|
/// <summary>
|
/// 输出簇列表
|
/// </summary>
|
public List<OutClusterObj> OutClusterList = new List<OutClusterObj>();
|
|
[Newtonsoft.Json.JsonIgnore]
|
public DateTime LastDateTime = DateTime.MinValue;
|
/// <summary>
|
/// 是否已经读取了设备状态(此属性是给主页使用的)
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public bool HadReadDeviceStatu = false;
|
|
/// <summary>
|
/// 等待从网关接收数据的时间
|
/// </summary>
|
/// <value>The wait receive data time.</value>
|
[Newtonsoft.Json.JsonIgnore]
|
public virtual int WaitReceiveDataTime
|
{
|
get
|
{
|
if (Device.ZbGateway.RemoteMqttClient != null && Device.ZbGateway.RemoteMqttClient.IsConnected)
|
{
|
return 10000;
|
}
|
else
|
{
|
return 3000;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 通过设备调用网关
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public ZbGateway Gateway
|
{
|
get
|
{
|
if (string.IsNullOrEmpty(CurrentGateWayId))
|
{
|
return null;
|
}
|
var gateWay = ZbGateway.GateWayList.Find(obj => (obj != null) && (obj.GwId == CurrentGateWayId));
|
if (gateWay == null)
|
{
|
gateWay = new ZbGateway { IsVirtual = true, };
|
gateWay.GwId = CurrentGateWayId;
|
gateWay.HomeId = Shared.Common.Config.Instance.HomeId;
|
ZbGateway.GateWayList.Add(gateWay);
|
}
|
|
return gateWay;
|
}
|
}
|
|
/// <summary>
|
/// 保存设备数据的文件名
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public virtual string FilePath
|
{
|
get
|
{
|
var deviceType = Type.ToString();
|
var fileName = "Device_" + deviceType + "_" + DeviceAddr;
|
fileName += "_" + (DeviceEpoint.ToString().Length < 2 ? "0" + DeviceEpoint.ToString() : DeviceEpoint.ToString());
|
return fileName;
|
}
|
}
|
|
#endregion
|
|
#region 设备保存及生成
|
|
/// <summary>
|
/// 由设备字符串比特恢复设备对象
|
/// </summary>
|
/// <param name="strDeviceType">设备DeviceType的字符串类型</param>
|
/// <param name="strDeviceByte">设备Json文件转为比特后再转为的字符串</param>
|
/// <returns></returns>
|
public static CommonDevice CommonDeviceByByteString(string strDeviceType, string strDeviceByte)
|
{
|
CommonDevice device = null;
|
if (strDeviceType == ZigBee.Device.DeviceType.DimmableLight.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<DimmableLight>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.OnOffOutput.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<ToggleLight>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.ColorDimmerSwitch.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<ColorDimmerSwitch>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.LevelControlSwitch.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<LevelControlSwitch>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.WindowCoveringDevice.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<Rollershade>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.WindowCoveringController.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<WindowCoveringController>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.OnOffSwitch.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<Panel>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.IASZone.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<IASZone>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.OtaDevice.ToString() || strDeviceType == ZigBee.Device.DeviceType.OtaPanelDevice.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<OTADevice>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.AirSwitch.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<AirSwitch>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.Repeater.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<Repeater>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.Thermostat.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<AC>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.Transverter.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<Transverter>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.DoorLock.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<DoorLock>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.TemperatureSensor.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<TemperatureSensor>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.FreshAirHumiditySensor.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<HumiditySensor>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.FreshAir.ToString())
|
{
|
device = Newtonsoft.Json.JsonConvert.DeserializeObject<FreshAir>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.PMSensor.ToString())
|
{
|
return Newtonsoft.Json.JsonConvert.DeserializeObject<PMSensor>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.ColorTemperatureLight.ToString())
|
{
|
return Newtonsoft.Json.JsonConvert.DeserializeObject<ColorTemperatureLight>(strDeviceByte);
|
}
|
else if (strDeviceType == ZigBee.Device.DeviceType.Buzzer.ToString())
|
{
|
return Newtonsoft.Json.JsonConvert.DeserializeObject<Buzzer>(strDeviceByte);
|
}
|
else { return null; }
|
//能少存一个变量就少存一个
|
device.Type = (DeviceType)device.DeviceID;
|
|
return device;
|
}
|
|
/// <summary>
|
/// 由设备路径恢复设备对象
|
/// </summary>
|
/// <returns>The device by file path.</returns>
|
/// <param name="deviceFilePath">Device file path.</param>
|
public static CommonDevice CommonDeviceByFilePath(string deviceFilePath)
|
{
|
var v = deviceFilePath.Split('_');
|
if (v.Length < 3)
|
{
|
return null;
|
}
|
return CommonDeviceByByteString(v[1], System.Text.Encoding.UTF8.GetString(Shared.Common.Global.ReadFileByHomeId(deviceFilePath)));
|
}
|
|
/// <summary>
|
/// 保存设备
|
/// </summary>
|
public void Save()
|
{
|
if (Shared.Common.Global.IsExistsByHomeId(FilePath))
|
{
|
return;
|
}
|
ReSave();
|
}
|
|
/// <summary>
|
/// 重新保存设备
|
/// </summary>
|
public void ReSave()
|
{
|
if (IconPath == string.Empty)
|
{
|
//保存设备图标(这里会保存一次,下面就不用保存了)
|
this.SaveDeviceIcon();
|
return;
|
}
|
Shared.Common.Global.WriteFileByBytesByHomeId(FilePath, System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this)));
|
}
|
|
/// <summary>
|
/// 保存设备图标
|
/// </summary>
|
private void SaveDeviceIcon()
|
{
|
if (IconPath == string.Empty)
|
{
|
//干接点
|
if (this.Type == DeviceType.OnOffSwitch)
|
{
|
IconPath = "Device/DryContact.png";
|
}
|
else if (this.Type == DeviceType.ColorDimmableLight)
|
{
|
//彩灯
|
IconPath = "Device/ColorLight.png";
|
}
|
else if (this.Type == DeviceType.DimmableLight)
|
{
|
//调光器
|
IconPath = "Device/Light.png";
|
}
|
else if (this.Type == DeviceType.ColorTemperatureLight)
|
{
|
//色温灯
|
IconPath = "Device/ColorLightTemperature.png";
|
}
|
else if (this.Type == DeviceType.OnOffOutput)
|
{
|
//继电器
|
IconPath = "Device/RelayEpoint.png";
|
}
|
else if (this.Type == DeviceType.Thermostat)
|
{
|
//空调
|
IconPath = "Device/AirConditionerEpoint.png";
|
}
|
else if (this.Type == DeviceType.FreshAir)
|
{
|
//新风
|
IconPath = "Device/FreshAirEpoint.png";
|
}
|
else if (this.Type == DeviceType.PMSensor)
|
{
|
//PM2.5空气质量传感器
|
IconPath = "Device/AirQualitySensorEpoint.png";
|
}
|
else if (this.Type == DeviceType.FreshAirHumiditySensor)
|
{
|
//湿度传感器
|
IconPath = "Device/SensorHumidity.png";
|
}
|
else if (this.Type == DeviceType.TemperatureSensor)
|
{
|
if (((TemperatureSensor)this).SensorDiv == 1)
|
{
|
//温度传感器
|
IconPath = "Device/SensorTemperature.png";
|
}
|
else if (((TemperatureSensor)this).SensorDiv == 2)
|
{
|
//湿度传感器
|
IconPath = "Device/SensorHumidity.png";
|
}
|
}
|
else if (this.Type != DeviceType.UnKown)
|
{
|
//其他的图标有点特殊
|
string unSelectPic = string.Empty;
|
string selectPic = string.Empty;
|
Shared.Common.LocalDevice.Current.GetDeviceObjectIcon(new List<CommonDevice> { this }, ref unSelectPic, ref selectPic);
|
IconPath = unSelectPic;
|
}
|
Shared.Common.Global.WriteFileByBytesByHomeId(FilePath, System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this)));
|
}
|
}
|
|
#endregion
|
|
#region 输入输出镞定义
|
|
/// <summary>
|
/// 设备最新上报的属性状态信息
|
/// </summary>
|
[System.Serializable]
|
public class AttributeStatusObj
|
{
|
/// <summary>
|
/// 属性簇id
|
/// </summary>
|
public int ClusterId;
|
/// <summary>
|
/// 属性id
|
/// </summary>
|
public int AttributeId;
|
/// <summary>
|
/// 属性值,最大占用4个字节
|
/// </summary>
|
public int AttributeData;
|
/// <summary>
|
/// 属性状态最后更新的utc时间戳
|
/// </summary>
|
public int ReportTime;
|
}
|
|
/// <summary>
|
/// 输入簇
|
/// </summary>
|
[System.Serializable]
|
public class InClusterObj
|
{
|
/// <summary>
|
/// 设备支持的输入功能
|
/// <para>0:Basic,设备支持“基础属性” </para>
|
/// <para>3:Identify,设备支持“识别功能”</para>
|
/// <para>4:Groups,设备支持“组功能”</para>
|
/// <para>5:Scenes,设备支持“场景功能”</para>
|
/// <para>6:on/off,设备支持“开关功能”</para>
|
/// 开关功能的设备如:调关灯/继电器/窗帘等。。。
|
/// <para>8:Level Control,设备支持“亮度调节功能”</para>
|
/// 亮度调节功能的设备如:调关灯。。。
|
/// <para>257:Door Lock,设备支持“门锁功能”</para>
|
/// 门锁功能的设备如:门锁。。。
|
/// <para>258:Window Covering,设备支持“窗帘控制功能”</para>
|
/// 窗帘控制功能的设备如:窗帘/开合帘/卷帘。。。
|
/// <para>513:Thermostat,设备支持“恒温器功能”</para>
|
/// 恒温器功能的设备如:空调。。。
|
/// <para>768:Color Control,设备支持“颜色调节功能”</para>
|
/// 颜色调节功能的设备如:调光灯。。。
|
/// <para>1026:Temperature Measurement,设备支持“温度测量功能”</para>
|
/// 温度测量功能的设备如:温度传感器。。。
|
/// <para>1029:Relative Humidity Measurement,设备支持“湿度测量功能”</para>
|
/// 湿度测量功能的设备如:湿度传感器。。。
|
/// <para>1066:Pm2.5 Measurement,设备支持“pm2.5测量功能”</para>
|
/// Pm2.5测量功能的设备如:Pm2.5传感器。。。
|
/// </summary>
|
public int InCluster;
|
}
|
|
/// <summary>
|
/// 输出簇
|
/// </summary>
|
[System.Serializable]
|
public class OutClusterObj
|
{
|
/// <summary>
|
/// 设备支持的输出功能
|
/// <para>0:Basic,设备支持“基础属性” </para>
|
/// <para>3:Identify,设备支持“识别功能”</para>
|
/// <para>4:Groups,设备支持“组功能”</para>
|
/// <para>5:Scenes,设备支持“场景功能”</para>
|
/// <para>6:on/off,设备支持“开关功能”</para>
|
/// 开关功能的设备如:调关灯/继电器/窗帘等。。。
|
/// <para>8:Level Control,设备支持“亮度调节功能”</para>
|
/// 亮度调节功能的设备如:调关灯。。。
|
/// <para>257:Door Lock,设备支持“门锁功能”</para>
|
/// 门锁功能的设备如:门锁。。。
|
/// <para>258:Window Covering,设备支持“窗帘控制功能”</para>
|
/// 窗帘控制功能的设备如:窗帘/开合帘/卷帘。。。
|
/// <para>513:Thermostat,设备支持“恒温器功能”</para>
|
/// 恒温器功能的设备如:空调。。。
|
/// <para>768:Color Control,设备支持“颜色调节功能”</para>
|
/// 颜色调节功能的设备如:调光灯。。。
|
/// <para>1026:Temperature Measurement,设备支持“温度测量功能”</para>
|
/// 温度测量功能的设备如:温度传感器。。。
|
/// <para>1029:Relative Humidity Measurement,设备支持“湿度测量功能”</para>
|
/// 湿度测量功能的设备如:湿度传感器。。。
|
/// </summary>
|
public int OutCluster;
|
}
|
|
/// <summary>
|
/// 支持的属性数据
|
/// </summary>
|
[System.Serializable]
|
public class AttributeObj
|
{
|
/// <summary>
|
/// 响应的属性ID
|
/// </summary>
|
public int AttributeId;
|
/// <summary>
|
/// 属性值的数据类型
|
/// </summary>
|
public int AttributeType;
|
}
|
|
/// <summary>
|
/// 设备上报的属性数据
|
/// </summary>
|
[System.Serializable]
|
public class AttributeDataObj
|
{
|
/// <summary>
|
/// 属性id
|
/// </summary>
|
public int AttributeId;
|
/// <summary>
|
/// 要报告属性的数据类型
|
/// </summary>
|
public int AttriButeDataType;
|
/// <summary>
|
/// AttriButeData占用的字节数
|
/// </summary>
|
public int AttriButeDataLength;
|
/// <summary>
|
/// 属性值
|
/// </summary>
|
public int AttriButeData = 999;
|
/// <summary>
|
/// 属性数据16进制转字符
|
/// </summary>
|
public string AttriButeDataHex;
|
}
|
|
/// <summary>
|
/// Command数组
|
/// </summary>
|
[System.Serializable]
|
public class CommandObj
|
{
|
/// <summary>
|
/// 支持的命令id
|
/// </summary>
|
public int commandId;
|
}
|
|
#endregion
|
|
#region 获取已入网设备信息
|
|
/// <summary>
|
/// 网关中的设备信息
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public DeviceInfoData DeviceInfo = null;
|
/// <summary>
|
/// 网关中的设备信息
|
/// </summary>
|
[System.Serializable]
|
public class DeviceInfoData
|
{
|
/// <summary>
|
/// 入网设备总数。等于0时,表示没有设备信息,下面字段将不存在。
|
/// </summary>
|
public int TotalNum;
|
/// <summary>
|
/// 标识当前设备是发送的是第几个设备。DeviceNum从1开始每发送一个设备信息,下一个设备信息的DeviceNum将加1。直到DeviceNum等于TotalNum说明所有设备信息发送完毕。
|
/// </summary>
|
public int DeviceNum;
|
/// <summary>
|
/// 入网的utc时间戳
|
/// </summary>
|
public int JoinTime;
|
/// <summary>
|
/// 1:路由器设备
|
/// <para>2:终端设备</para>
|
/// </summary>
|
public int ZigbeeType;
|
/// <summary>
|
/// 设备网络地址
|
/// </summary>
|
public int NwkAddr;
|
/// <summary>
|
/// 该字段主要针对IAS安防设备设立。所有IAS安防设备共用一个DeviceID为1026。所以要区分子设备类型,需要该字段。
|
/// <para>13:Motion sensor (运动传感器)</para>
|
/// <para>43:Carbon Monoxide sensor (一氧化碳传感器)</para>
|
/// <para>44:Personal emergency device (紧急按钮)</para>
|
/// </summary>
|
public int DeviceType;
|
/// <summary>
|
/// 用于判断设备的zigbee协议版本。
|
///<para>49246:ZLL1.0标准设备。</para>
|
///<para>260: ZHA1.2标准设备、 Z3.0标准设备。</para>
|
///<para>41440:ZGP3.0标准设备。</para>
|
///<para>265:ZSE1.4标准设备。</para>
|
/// </summary>
|
public int Profile;
|
/// <summary>
|
/// 设备mac名称
|
/// </summary>
|
public string MacName;
|
/// <summary>
|
/// 设备名(Mac+断点命名的)
|
/// </summary>
|
public string DeviceName;
|
/// <summary>
|
/// 0:设备不在线
|
/// <para>1:设备在线</para>
|
/// </summary>
|
public int IsOnline;
|
/// <summary>
|
/// 当前运行程序版本信息。 最大64字节
|
/// </summary>
|
public int ImgVersion;
|
/// <summary>
|
/// 硬件版本
|
/// </summary>
|
public int HwVersion;
|
/// <summary>
|
/// 当前镜像类型id
|
/// </summary>
|
public int ImgTypeId;
|
/// <summary>
|
/// 驱动代码。为0时,表示zigbee协调器设备。其他值表示为虚拟驱动设备
|
/// </summary>
|
public int DriveCode;
|
/// <summary>
|
/// 厂商名称
|
/// </summary>
|
public string ManufacturerName = string.Empty;
|
/// <summary>
|
/// 模块ID
|
/// </summary>
|
public string ModelIdentifier = string.Empty;
|
/// <summary>
|
/// 好像是序列号
|
/// </summary>
|
public string ProductCode = string.Empty;
|
/// <summary>
|
/// 设备功能类型(空气开关和继电器专用)
|
/// </summary>
|
public int FunctionType = -1;
|
/// <summary>
|
/// 输入簇列表
|
/// </summary>
|
public List<InClusterObj> InClusterList = new List<InClusterObj>();
|
/// <summary>
|
/// 输出簇列表
|
/// </summary>
|
public List<OutClusterObj> OutClusterList = new List<OutClusterObj>();
|
/// <summary>
|
/// 用于记录设备最新上报的属性状态信息。最大支持记录16个属性状态,且只记录属性值长度不大于4字节的数据。
|
/// </summary>
|
public List<AttributeStatusObj> AttributeStatus = new List<AttributeStatusObj>();
|
|
}
|
|
#endregion
|
|
#region 错误结果定义
|
|
/// <summary>
|
/// 网关信息错误反馈共通
|
/// </summary>
|
[System.Serializable]
|
public class ErrorResponCommon
|
{
|
/// <summary>
|
/// 错误信息
|
/// </summary>
|
public string errorMessageBase;
|
/// <summary>
|
/// 网关信息错误反馈
|
/// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
|
/// </summary>
|
public ErrorResponData errorResponData;
|
}
|
|
/// <summary>
|
/// 网关信息错误反馈
|
/// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
|
/// </summary>
|
[System.Serializable]
|
public class ErrorResponData
|
{
|
/// <summary>
|
/// Error参数含义
|
///<para>1:网关无法解析命令数据。</para>
|
///<para>2:协调器正在升级或备份/恢复数据
|
///<para>3:操作设备/组/场景不存在</para>
|
///<para>4:其他错误</para>
|
///<para>5:数据传输错误(在某次客户端向网关发送数据的过程中,网关在合理时间范围内接收客户端数据不完整导致该错误发生。如客户端向网关一次发送100个字节的数据,但网关等待接收了一秒只接收了80个字节。发生该错误,网关将主动关闭客户端连接)</para>
|
/// </summary>
|
public int Error;
|
}
|
|
/// <summary>
|
/// 网关错误信息具体内容
|
/// </summary>
|
public static string ErrorMess(int err)
|
{
|
string message = "";
|
switch (err)
|
{
|
case 1:
|
message = " 网关无法解析命令数据。";
|
break;
|
case 2:
|
message = " 协调器正在升级或备份 / 恢复数据。";
|
break;
|
case 3:
|
message = "操作设备 / 组 / 场景不存在";
|
break;
|
case 4:
|
message = " 其他错误";
|
break;
|
case 5:
|
message = " 数据传输错误(在某次客户端向网关发送数据的过程中,网关在合理时间范围内接收客户端数据不完整导致该错误发生。如客户端向网关一次发送100个字节的数据,但网关等待接收了一秒只接收了 个字节。发生该错误,网关将主动关闭客户端连接)";
|
break;
|
default:
|
break;
|
}
|
return message;
|
}
|
|
#endregion
|
|
#region 修改设备端口名称
|
|
/// <summary>
|
/// 重命名设备,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class DeviceRenameAllData
|
{
|
/// <summary>
|
/// 错误信息
|
/// </summary>
|
public string errorMessageBase;
|
/// <summary>
|
/// 网关信息错误反馈
|
/// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
|
/// </summary>
|
public ErrorResponData errorResponData;
|
/// <summary>
|
/// 设备名称修改
|
/// </summary>
|
public DeviceRenameResponseData deviceRenameData;
|
}
|
|
/// <summary>
|
/// 设备名称修改
|
/// </summary>
|
[System.Serializable]
|
public class DeviceRenameResponseData
|
{
|
/// <summary>
|
/// 0:修改成功
|
/// <para>1:修改失败</para>
|
/// </summary>
|
public int Result;
|
/// <summary>
|
/// 修改后的设备名称
|
/// </summary>
|
public string DeviceName;
|
}
|
#endregion
|
|
#region 修改设备mac名称
|
|
/// <summary>
|
/// 修改设备mac名称数据,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class RenameDeviceMacNameAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 修改设备mac名称数据
|
/// </summary>
|
public RenameDeviceMacNameData renameDeviceMacNameData;
|
}
|
|
/// <summary>
|
/// 修改设备mac名称数据
|
/// </summary>
|
[System.Serializable]
|
public class RenameDeviceMacNameData
|
{
|
/// <summary>
|
/// 0:修改成功
|
/// <para>1:修改失败,mac不存在</para>
|
/// </summary>
|
public int Result;
|
/// <summary>
|
/// 修改后的设备名称
|
/// </summary>
|
public string MacName;
|
}
|
#endregion
|
|
#region 一键更新四寸屏按键属性
|
/// <summary>
|
/// 同步设备功能
|
/// </summary>
|
/// <returns></returns>
|
public async System.Threading.Tasks.Task<SynchronizationDeviceResponseAllData> SyncMsgToBindSource(string deviceAddr, int deviceEpoint)
|
{
|
if (Gateway == null)
|
{
|
return null;
|
}
|
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
SynchronizationDeviceResponseAllData resContent = null;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
resContent = new SynchronizationDeviceResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
else
|
{
|
resContent = new SynchronizationDeviceResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "Bind/SyncMsgToBindSourceRespon")
|
{
|
var res = Newtonsoft.Json.JsonConvert.DeserializeObject<int>(jobject["Data"]["Result"].ToString());
|
if (res == null)
|
{
|
resContent = new SynchronizationDeviceResponseAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
resContent = new SynchronizationDeviceResponseAllData { result = res };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
Gateway.Actions = action;
|
DebugPrintLog("Bind/SyncMsgToBindSourceRespon_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "DeviceAddr", deviceAddr }, { "Epoint", deviceEpoint }, { "Cluster_ID", 0 }, { "Command", 5010 } };
|
Gateway.Send("Bind/SyncMsgToBindSource", jObject.ToString());
|
}
|
catch { }
|
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (resContent != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
resContent = new SynchronizationDeviceResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
|
}
|
Gateway.Actions -= action;
|
DebugPrintLog("Bind/SyncMsgToBindSource_Actions 退出" + System.DateTime.Now.ToString());
|
|
return resContent;
|
});
|
|
}
|
|
/// <summary>
|
/// 同步设备,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class SynchronizationDeviceResponseAllData
|
{
|
/// <summary>
|
/// 错误信息
|
/// </summary>
|
public string errorMessageBase;
|
/// <summary>
|
/// 网关信息错误反馈
|
/// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
|
/// </summary>
|
public ErrorResponData errorResponData;
|
/// <summary>
|
/// 同步结果
|
/// 0:成功:网关内部自动写入设备目标名字、设备目标功能类型、场景目标名字、utc时间写入4寸屏
|
/// 1:失败
|
/// </summary>
|
public int result;
|
}
|
#endregion
|
|
#region 删除设备(使设备离网)
|
/// <summary>
|
/// 删除设备(使设备离网)
|
/// </summary>
|
/// <returns>The device async.</returns>
|
/// <param name="removeData">Remove data.</param>
|
public async System.Threading.Tasks.Task<RemoveDeviceResponseAllData> DeleteDeviceAsync(ZigBee.Device.CommonDevice.RemoveDeviceData removeData)
|
{
|
if (Gateway == null || removeData == null)
|
{
|
return null;
|
}
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
RemoveDeviceResponseAllData d = null;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new RemoveDeviceResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
else
|
{
|
d = new RemoveDeviceResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "RemoveDeviceRespon")
|
{
|
var removeDeviceResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.RemoveDeviceResponseData>(jobject["Data"].ToString());
|
|
if (removeDeviceResponseData == null)
|
{
|
d = new RemoveDeviceResponseAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new RemoveDeviceResponseAllData { removeDeviceResponseData = removeDeviceResponseData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
Gateway.Actions += action;
|
DebugPrintLog("RemoveDevice_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
if (removeData != null)
|
{
|
var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 99 } };
|
var deviceAddrList = new JArray { };
|
foreach (var a in removeData.DeviceAddrList)
|
{
|
var dd = new JObject { { "DeviceAddr", a.DeviceAddr } };
|
deviceAddrList.Add(dd);
|
}
|
|
var data = new JObject {
|
{ "CompelClear", removeData.CompelClear },
|
{ "DeviceAddrList", deviceAddrList }
|
};
|
jObject.Add("Data", data);
|
Gateway.Send(("RemoveDevice"), jObject.ToString());
|
}
|
}
|
catch { }
|
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
d = new RemoveDeviceResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
|
}
|
Gateway.Actions -= action;
|
DebugPrintLog("RemoveDevice_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 需要删除设备的数据
|
/// </summary>
|
[System.Serializable]
|
public class RemoveDeviceData
|
{
|
/// <summary>
|
/// 0:不强制清除。需要节点设备反馈离网确认信息后才能删除设备信息。
|
///<para>1:强制清除。不需要节点设备反馈离网确认信息,直接删除设备信息。</para>
|
///<para>说明:正常情况下让节点设备离网,需要节点设备在线,节点设备反馈离网确认信息后网关方可删除该设备的设备信息。但如果设备已经损坏,或已经通过外部功能离网,此时节点设备已经无法反馈离网确认信息,面对这种情况,要删除保存在网关上的该节点设备的设备信息,需要将该字段赋值为1,网关强制删除该设备信息,不需要节点设备确认。</para>
|
/// </summary>
|
public int CompelClear = 1;
|
/// <summary>
|
/// 出网设备列表
|
/// </summary>
|
public List<RemoveDeviceListInfo> DeviceAddrList = new List<RemoveDeviceListInfo>();
|
}
|
|
/// <summary>
|
/// 场景信息
|
/// </summary>
|
public class RemoveDeviceListInfo
|
{
|
/// <summary>
|
/// 设备mac地址
|
/// </summary>
|
public string DeviceAddr;
|
}
|
|
/// <summary>
|
/// 移除设备,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class RemoveDeviceResponseAllData
|
{
|
/// <summary>
|
/// 错误信息
|
/// </summary>
|
public string errorMessageBase;
|
/// <summary>
|
/// 网关信息错误反馈
|
/// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
|
/// </summary>
|
public ErrorResponData errorResponData;
|
/// <summary>
|
/// 设备名称修改
|
/// </summary>
|
public RemoveDeviceResponseData removeDeviceResponseData;
|
}
|
|
/// <summary>
|
/// 删除设备回复数据
|
/// <para>返回结果Resul=,删除成功</para>
|
/// </summary>
|
[System.Serializable]
|
public class RemoveDeviceResponseData
|
{
|
/// <summary>
|
/// 0:删除成功
|
/// <para>删除失败</para>
|
/// </summary>
|
public int Result = 2;
|
/// <summary>
|
/// 出网设备列表
|
/// </summary>
|
public List<DeviceListInfo> DeviceList = new List<DeviceListInfo>();
|
}
|
|
/// <summary>
|
/// 场景信息
|
/// </summary>
|
[System.Serializable]
|
public class DeviceListInfo
|
{
|
/// <summary>
|
/// 设备ID
|
/// </summary>
|
public int Device_ID;
|
|
/// <summary>
|
/// 设备mac地址
|
/// </summary>
|
public string MacAddr;
|
|
/// <summary>
|
/// 设备端口号
|
/// </summary>
|
public int Epoint;
|
|
}
|
#endregion
|
|
#region 识别设备
|
///<summary >
|
/// 识别设备
|
/// <para>cluster=3,具有Identify(识别)功能,属于ZCL库</para>
|
/// <para>time:设置设备闪烁时间(秒)范围:0-65535</para>
|
/// </summary>
|
public void IdentifyControl(string deviceAddr, int deviceEpoint, int time)
|
{
|
if (Gateway == null)
|
{
|
return;
|
}
|
Action<string, string> action = (topic, message) => { };
|
Gateway.Actions += action;
|
System.Console.WriteLine("Identify_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "DeviceAddr", deviceAddr }, { "Epoint", deviceEpoint }, { "Cluster_ID", 3 }, { "Command", 0 }, { "SendMode", 2 } };
|
var data = new JObject { { "Time", time } };
|
jObject.Add("Data", data);
|
Gateway.Send(("Identify"), jObject.ToString());
|
}
|
catch { }
|
|
Gateway.Actions -= action;
|
System.Console.WriteLine("Identify_Actions 退出" + System.DateTime.Now.ToString());
|
|
}
|
#endregion
|
|
#region 设备属性状态上报
|
/// <summary>
|
/// 获取设备当前属性状态
|
/// </summary>
|
/// <param name="clusterID">Cluster identifier.</param>
|
/// <param name="attriButeId">Attri bute identifier.</param>
|
public async void ReadAttri(Cluster_ID clusterID, AttriButeId attriButeId)
|
{
|
if (Gateway == null)
|
{
|
return;
|
}
|
await System.Threading.Tasks.Task.Run(async () =>
|
{
|
//Action<string, string> action = (topic, message) => { };
|
|
// Gateway.Actions += action;
|
System.Console.WriteLine("GetDeviceStatus_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var JObject = new JObject {
|
{ "DeviceAddr",DeviceAddr },
|
{ "Epoint", DeviceEpoint },
|
{ "Cluster_ID", (int)clusterID },
|
{ "Command", 108 }
|
};
|
var attriBute = new JArray{
|
new JObject {
|
{ "AttriButeId", (int)attriButeId}
|
}
|
};
|
var data = new JObject { { "AttriBute", attriBute } };
|
JObject.Add("Data", data);
|
Gateway?.Send(("GetDeviceStatus"), JObject.ToString());
|
}
|
catch { }
|
|
// Gateway.Actions -= action;
|
System.Console.WriteLine("GetDeviceStatus_Actions 退出" + System.DateTime.Now.ToString());
|
});
|
}
|
|
/// <summary>
|
/// 设备属性状态上报
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public DeviceStatusReportData DeviceStatusReport = new DeviceStatusReportData();
|
/// <summary>
|
/// 设备属性状态上报
|
/// </summary>
|
[System.Serializable]
|
public class DeviceStatusReportData
|
{
|
/// <summary>
|
/// 属性所在CluterID
|
/// <summary>
|
/// 设备支持的输入功能
|
/// <para>0:Basic,设备支持“基础属性” </para>
|
/// <para>3:Identify,设备支持“识别功能”</para>
|
/// <para>4:Groups,设备支持“组功能”</para>
|
/// <para>5:Scenes,设备支持“场景功能”</para>
|
/// <para>6:on/off,设备支持“开关功能”</para>
|
/// 开关功能的设备如:调关灯/继电器/窗帘等。。。
|
/// <para>8:Level Control,设备支持“亮度调节功能”</para>
|
/// 亮度调节功能的设备如:调关灯。。。
|
/// <para>257:Door Lock,设备支持“门锁功能”</para>
|
/// 门锁功能的设备如:门锁。。。
|
/// <para>258:Window Covering,设备支持“窗帘控制功能”</para>
|
/// 窗帘控制功能的设备如:窗帘/开合帘/卷帘。。。
|
/// <para>513:Thermostat,设备支持“恒温器功能”</para>
|
/// 恒温器功能的设备如:空调。。。
|
/// <para>768:Color Control,设备支持“颜色调节功能”</para>
|
/// 颜色调节功能的设备如:调光灯。。。
|
/// <para>1026:Temperature Measurement,设备支持“温度测量功能”</para>
|
/// 温度测量功能的设备如:温度传感器。。。
|
/// <para>1029:Relative Humidity Measurement,设备支持“湿度测量功能”</para>
|
/// 湿度测量功能的设备如:湿度传感器。。。
|
/// </summary>
|
/// </summary>
|
public int CluterID;
|
/// <summary>
|
/// 属性列表
|
/// </summary>
|
public List<AttributeDataObj> AttriBute = new List<AttributeDataObj>();
|
}
|
#endregion
|
|
#region 设置可写属性的值
|
/// <summary>
|
/// 设置可写属性的值
|
/// </summary>
|
/// <returns>The writable value async.</returns>
|
/// <param name="gateway">Gateway.</param>
|
/// <param name="clusterID">要配置的属性所在的cluster.</param>
|
/// <param name="setWritableValue">设置可写属性的数据</param>
|
public async System.Threading.Tasks.Task<SetWritableValueResponAllData> SetWritableValueAsync(ZigBee.Device.ZbGateway gateway, int clusterID, SetWritableValueData setWritableValue)
|
{
|
if (gateway == null || setWritableValue == null)
|
{
|
return null;
|
}
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
SetWritableValueResponAllData d = null;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new SetWritableValueResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
else
|
{
|
d = new SetWritableValueResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "SetWritableValue_Respon")
|
{
|
var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<SetWritableValueResponData>(jobject["Data"].ToString());
|
|
if (tempData == null)
|
{
|
d = new SetWritableValueResponAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new SetWritableValueResponAllData { setWritableValueResponData = tempData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
gateway.Actions += action;
|
System.Console.WriteLine("SetWritableValue_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", clusterID }, { "Command", 120 } };
|
var data = new JObject { { "Undivided", setWritableValue.Undivided }, { "AttributeId", setWritableValue.AttributeId }, { "AttributeDataType", setWritableValue.AttributeDataType }, { "AttributeData", setWritableValue.AttributeData } };
|
jObject.Add("Data", data);
|
gateway.Send("SetWritableValue", jObject.ToString());
|
}
|
catch { }
|
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
d = new SetWritableValueResponAllData { errorMessageBase = " 回复超时,请重新操作" };
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("SetWritableValue_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 网关版本信息,网关反馈信息
|
/// </summary>
|
[System.Serializable]
|
public class SetWritableValueResponAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 网关版本信息
|
/// </summary>
|
public SetWritableValueResponData setWritableValueResponData;
|
}
|
|
/// <summary>
|
/// 设置可写属性的值的数据
|
/// </summary>
|
[System.Serializable]
|
public class SetWritableValueResponData
|
{
|
/// <summary>
|
/// 配置属性所在的cluster
|
/// </summary>
|
public int Cluster;
|
/// <summary>
|
/// 0:配置成功(若配置成功,下面的AttributeId字段不存在)
|
///<para>134:不支持该属性</para>
|
///<para>135:无效的属性值</para>
|
///<para>141:无效的数据类型</para>
|
/// </summary>
|
public int Status;
|
/// <summary>
|
/// 配置的属性ID(当Status=0 时,该字段将不存在 ,也就是只有失败的结果才会返回该字段)
|
/// </summary>
|
public int AttributeId;
|
|
}
|
|
/// <summary>
|
/// 设置可写属性的值的数据
|
/// </summary>
|
[System.Serializable]
|
public class SetWritableValueData
|
{
|
/// <summary>
|
/// 是否强制写入属性
|
///<para>0:否</para>
|
///<para>1:强制写属性值</para>
|
///<para>可缺省,默认为0。</para>
|
/// </summary>
|
public int Undivided;
|
/// <summary>
|
/// 属性id
|
/// </summary>
|
public int AttributeId;
|
/// <summary>
|
/// 属性数据类型
|
/// </summary>
|
public int AttributeDataType;
|
/// <summary>
|
/// 写入数值
|
/// </summary>
|
public int AttributeData;
|
|
}
|
#endregion
|
|
#region 开关
|
///<summary >
|
///开关控制(仅用于cluster=6的设备)
|
/// <para>设备支持cluster=6的设备才能调用该接口</para>
|
/// <para>command的值</para>
|
///<para>0 : 关闭</para>
|
///<para>1: 打开</para>
|
///<para>2:取反</para>
|
/// </summary>
|
public void SwitchControl(int command)
|
{
|
try
|
{
|
var jobject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 6 }, { "Command", command }, { "SendMode", 2 } };
|
Gateway?.Send(("DeviceControl"), jobject.ToString());
|
System.Console.WriteLine("SwitchControl_发送数据" + "_" + jobject.ToString() + "_" + System.DateTime.Now.ToString());
|
|
}
|
catch { }
|
}
|
#endregion
|
|
#region ZCL库-发现属性
|
/// <summary>
|
///ZCL库-发现属性(如果返回为空,可能是设备不是标准设备,不支持这条命令)
|
/// <para>获取设备的某个Cluster所支持的Attributes</para>
|
/// <para> gateway:当前网关</para>
|
/// <para> clusterID:需要查询的cluster</para>
|
/// <para>读Panel的属性:clusterID=6</para>
|
/// <para>读亮度的属性:clusterID=8</para>
|
/// </summary>
|
public async System.Threading.Tasks.Task<ClusterOwnAttributesResponAllData> ClusterOwnAttributesAsync(ZigBee.Device.ZbGateway gateway, int clusterID)
|
{
|
if (gateway == null)
|
{
|
return null;
|
}
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
ClusterOwnAttributesResponAllData d = null;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new ClusterOwnAttributesResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
else
|
{
|
d = new ClusterOwnAttributesResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "Cluster/OwnAttributes_Respon")
|
{
|
var clusterOwnAttributesResponData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ClusterOwnAttributesResponData>(jobject["Data"].ToString());
|
var tempAttributes = Newtonsoft.Json.Linq.JArray.Parse(jobject["Data"]["Attribute"].ToString());
|
for (int m = 0; tempAttributes != null && m < tempAttributes.Count; m++)
|
{
|
var tempAttribute = tempAttributes[m];
|
clusterOwnAttributesResponData.AttributeList.Add(Newtonsoft.Json.JsonConvert.DeserializeObject<AttributeObj>(tempAttribute.ToString()));
|
}
|
|
if (clusterOwnAttributesResponData == null)
|
{
|
d = new ClusterOwnAttributesResponAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new ClusterOwnAttributesResponAllData { clusterOwnAttributesResponData = clusterOwnAttributesResponData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
|
}
|
}
|
};
|
gateway.Actions += action;
|
System.Console.WriteLine("Cluster/OwnAttributes_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", clusterID }, { "Command", 301 } };
|
gateway.Send("Cluster/OwnAttributes", jObject.ToString());
|
}
|
catch { }
|
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
d = new ClusterOwnAttributesResponAllData { errorMessageBase = " 回复超时,请重新操作" };
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("Cluster/OwnAttributes_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 发现属性,网关反馈信息
|
/// </summary>
|
[System.Serializable]
|
public class ClusterOwnAttributesResponAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 网关版本信息
|
/// </summary>
|
public ClusterOwnAttributesResponData clusterOwnAttributesResponData;
|
}
|
|
[System.Serializable]
|
public class ClusterOwnAttributesResponData
|
{
|
/// <summary>
|
/// 查询的cluste
|
/// </summary>
|
public int Cluster;
|
/// <summary>
|
/// 设备属性列表
|
/// </summary>
|
public List<AttributeObj> AttributeList = new List<AttributeObj>();
|
|
}
|
#endregion
|
|
#region ZCL库-支持的Command
|
/// <summary>
|
///ZCL库-设备某cluster所支持的Command ;(如果返回为空,可能是设备不是标准设备,不支持这条命令)
|
/// <para>获取设备某cluster所支持的Command</para>
|
/// <para> gateway:当前网关</para>
|
/// <para> clusterID:需要查询的cluster</para>
|
/// </summary>
|
public async System.Threading.Tasks.Task<ClusterOwnCommandResponAllData> ClusterOwnCommandAsync(ZigBee.Device.ZbGateway gateway, int clusterID)
|
{
|
if (gateway == null)
|
{
|
return null;
|
}
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
ClusterOwnCommandResponAllData d = null;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new ClusterOwnCommandResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
else
|
{
|
d = new ClusterOwnCommandResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
|
}
|
}
|
|
if (topic == gatewayID + "/" + "Cluster/OwnCommand_Respon")
|
{
|
var clusterOwnCommandResponData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClusterOwnCommandResponData>(jobject["Data"].ToString());
|
|
if (clusterOwnCommandResponData == null)
|
{
|
d = new ClusterOwnCommandResponAllData { errorMessageBase = "网关返回的数据为空" };
|
|
}
|
else
|
{
|
d = new ClusterOwnCommandResponAllData { clusterOwnCommandResponData = clusterOwnCommandResponData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
gateway.Actions += action;
|
System.Console.WriteLine("Cluster/OwnCommand_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", clusterID }, { "Command", 302 } };
|
gateway.Send("Cluster/OwnCommand", jObject.ToString());
|
}
|
catch { }
|
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
d = new ClusterOwnCommandResponAllData { errorMessageBase = " 回复超时,请重新操作" };
|
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("Cluster/OwnCommand_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 设备某cluster所支持的Command数据,网关反馈信息
|
/// </summary>
|
[System.Serializable]
|
public class ClusterOwnCommandResponAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 网设备某cluster所支持的Command数据
|
/// </summary>
|
public ClusterOwnCommandResponData clusterOwnCommandResponData;
|
}
|
|
/// <summary>
|
/// 设备某cluster所支持的Command数据
|
/// </summary>
|
[System.Serializable]
|
public class ClusterOwnCommandResponData
|
{
|
/// <summary>
|
/// 查询的cluste
|
/// </summary>
|
public int Cluster;
|
/// <summary>
|
/// 设备属性列表
|
/// </summary>
|
public List<CommandObj> Command = new List<CommandObj>();
|
|
}
|
#endregion
|
|
#region 设定OTA升级固件.;
|
/// <summary>
|
/// 设定OTA升级固件
|
/// </summary>
|
/// <returns>The NVA sync.</returns>
|
/// <param name="gateway">Gateway.</param>
|
/// <param name="oTAImageName">O TAI mage name:升级镜像名称</param>
|
public async System.Threading.Tasks.Task<OTASetImageResponseAllData> UpgradeDeviceAsync(ZigBee.Device.ZbGateway gateway, string oTAImageName)
|
{
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
OTASetImageResponseAllData d = null; ;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new OTASetImageResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
|
else
|
{
|
d = new OTASetImageResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "OTA/SetImage_Respon")
|
{
|
var oTASetImageData = Newtonsoft.Json.JsonConvert.DeserializeObject<OTASetImageData>(jobject["Data"].ToString());
|
|
if (oTASetImageData == null)
|
{
|
d = new OTASetImageResponseAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new OTASetImageResponseAllData { otaSetImageData = oTASetImageData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
gateway.Actions += action;
|
System.Console.WriteLine("OTA/SetImage_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "Cluster_ID", 25 }, { "Command", 30 } };
|
var data = new JObject { { "OTAImageName", oTAImageName }, { "OTAImagePath", "/tmp" } };
|
jObject.Add("Data", data);
|
gateway.Send(("OTA/SetImage"), jObject.ToString());
|
}
|
catch
|
{ }
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
d = new OTASetImageResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("OTA/SetImage_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 设备进行OTA升级,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class OTASetImageResponseAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 保存zigbee协调器组网信息
|
/// </summary>
|
public OTASetImageData otaSetImageData;
|
}
|
|
[System.Serializable]
|
public class OTASetImageData
|
{
|
/// <summary>
|
/// 0:成功
|
///<para>1:没有找到文件或打开文件失败</para>
|
///<para>2:当前有节点设备正在ota升级,原来的ota固件还在占用,不能重新设定固件。若要重新设定ota固件,则需要先用终止升级指令终止所有正在升级的节点设备。</para>
|
/// </summary>
|
public int Result;
|
|
/// <summary>
|
/// 该ota固件的制造商ID(Result = 0时存在)
|
/// </summary>
|
public int Manufacture;
|
|
/// <summary>
|
/// 该ota固件的固件类型id(Result = 0时存在)
|
/// </summary>
|
public int ImgTypeId;
|
|
/// <summary>
|
/// 该ota固件的版本(Result = 0时存在)
|
/// </summary>
|
public int FileVersion;
|
|
/// <summary>
|
/// 固件大小
|
/// </summary>
|
public int FileSize;
|
|
/// <summary>
|
///正在升级的ota节点设备列(Result=2时,该字段才存在)
|
/// </summary>
|
public List<OTADeviceList> DeviceList = new List<OTADeviceList>();
|
}
|
|
/// <summary>
|
/// 输入簇
|
/// </summary>
|
[System.Serializable]
|
public class OTADeviceList
|
{
|
/// <summary>
|
/// MAC地址
|
/// </summary>
|
public string MacAddr;
|
|
/// <summary>
|
/// 设备端口号,当升级设备,HDL的设备大多数的端点默认是200
|
/// </summary>
|
public int Epoint = 200;
|
}
|
#endregion
|
|
#region 启动升级;
|
/// <summary>
|
/// 设定OTA升级固件
|
/// </summary>
|
/// <returns>The NVA sync.</returns>
|
/// <param name="gateway">Gateway.</param>
|
/// <param name="oTAImageName">O TAI mage name:升级镜像名称</param>
|
public async System.Threading.Tasks.Task<StartDeviceUpdateResponseAllData> StartDeviceUpdateAsync(ZigBee.Device.ZbGateway gateway, StartUpdateData startUpdateData)
|
{
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
StartDeviceUpdateResponseAllData d = null; ;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new StartDeviceUpdateResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
|
else
|
{
|
d = new StartDeviceUpdateResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "OTA/StartUpdate_Respon")
|
{
|
var startUpdateDeviceData = Newtonsoft.Json.JsonConvert.DeserializeObject<StartDeviceUpdateData>(jobject["Data"].ToString());
|
|
if (startUpdateDeviceData == null)
|
{
|
d = new StartDeviceUpdateResponseAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new StartDeviceUpdateResponseAllData { startUpdateDeviceData = startUpdateDeviceData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
gateway.Actions += action;
|
System.Console.WriteLine("OTA/StartUpdate_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
if (startUpdateData != null)
|
{
|
var jObject = new JObject { { "Cluster_ID", 25 }, { "Command", 0 } };
|
var deviceList = new JArray { };
|
foreach (var de in startUpdateData.DeviceList)
|
{
|
var dInfo = new JObject{
|
{ "MacAddr",de.MacAddr},
|
{ "Epoint", de.Epoint}
|
};
|
deviceList.Add(dInfo);
|
}
|
var data = new JObject { { "DeviceList", deviceList } };
|
jObject.Add("Data", data);
|
gateway.Send(("OTA/StartUpdate"), jObject.ToString());
|
}
|
}
|
catch
|
{ }
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < 30 * 1000)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > 30 * 1000)
|
{
|
d = new StartDeviceUpdateResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
|
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("OTA/StartUpdate_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 启动升级,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class StartDeviceUpdateResponseAllData
|
{
|
/// <summary>
|
/// 错误信息
|
/// </summary>
|
public string errorMessageBase;
|
/// <summary>
|
/// 网关信息错误反馈
|
/// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
|
/// </summary>
|
public ErrorResponData errorResponData;
|
/// <summary>
|
/// 保存zigbee协调器组网信息
|
/// </summary>
|
public StartDeviceUpdateData startUpdateDeviceData;
|
}
|
|
[System.Serializable]
|
public class StartDeviceUpdateData
|
{
|
/// <summary>
|
/// 0:正常
|
/// <para>1:启动失败,未设定升级固件</para>
|
/// </summary>
|
public int Result = 999;
|
|
/// <summary>
|
///升级设备列表
|
/// </summary>
|
public List<OTAStartUpdateList> DeviceList = new List<OTAStartUpdateList>();
|
}
|
|
/// <summary>
|
/// 输入簇
|
/// </summary>
|
[System.Serializable]
|
public class OTAStartUpdateList
|
{
|
/// <summary>
|
/// MAC地址
|
/// </summary>
|
public string MacAddr;
|
|
/// <summary>
|
/// 设备端口号,当升级设备,HDL的设备大多数的端点默认是200
|
/// </summary>
|
public int Epoint = 200;
|
|
/// <summary>
|
/// 设备名称
|
/// </summary>
|
public string DeviceName;
|
}
|
|
/// <summary>
|
/// 启动升级
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public OTAScheduleResponData oTAScheduleResponData;
|
|
[System.Serializable]
|
public class OTAScheduleResponData
|
{
|
/// <summary>
|
/// 0:节点设备可进行OTA升级(如果设备在线,且支持OTA升级,则设备首先会反馈该状态,说明该设备OTA升级已启动)
|
///<para>1:正在升级(设备处于下载OTA升级固件状态将反馈该状</para>
|
///<para>2:升级完成(OTA升级完成,节点设备反馈该状态)</para>
|
///<para>3:升级失败,响应超时</para>
|
///<para>150:无效的OTA升级固件(下载完成后,由节点设备判断固件是否有效)</para>
|
///<para>153:客户端仍需更多的OTA升级固件</para>
|
///<para>149:升级终止</para>
|
/// </summary>
|
public int Status = 999;
|
|
/// <summary>
|
/// 升级百分比。(当Status=1时有效)
|
/// </summary>
|
public int Percent = 999;
|
}
|
|
[System.Serializable]
|
public class StartUpdateData
|
{
|
/// <summary>
|
///升级设备列表
|
/// </summary>
|
public List<OTADeviceList> DeviceList = new List<OTADeviceList>();
|
}
|
|
#endregion
|
|
#region 客户端向节点设备透传数据.
|
/// <summary>
|
/// 客户端向节点设备透传数据
|
/// <para>passData:透传数据(这里的值是在各个设备对象中复制好的,传进来即可)</para>
|
/// <para>透传数据返回后,可以调用各个设备对象中获取相应的处理完成的数据</para>
|
/// </summary>
|
public async System.Threading.Tasks.Task<ClientDataPassthroughResponseAllData> ClientDataPassthroughAsync(ZigBee.Device.ZbGateway gateway, string passData)
|
{
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
ClientDataPassthroughResponseAllData d = null; ;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new ClientDataPassthroughResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
|
else
|
{
|
d = new ClientDataPassthroughResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "ZbDataPassthrough")
|
{
|
var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
|
|
if (clientDataPassthroughResponseData == null)
|
{
|
d = new ClientDataPassthroughResponseAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new ClientDataPassthroughResponseAllData { clientDataPassthroughResponseData = clientDataPassthroughResponseData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
gateway.Actions += action;
|
System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
|
var data = new JObject { { "PassData", passData } };
|
jObject.Add("Data", data);
|
gateway.Send("ClientDataPassthrough", jObject.ToString());
|
}
|
catch
|
{ }
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
d = new ClientDataPassthroughResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 客户端向节点设备透传数据,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class ClientDataPassthroughResponseAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 客户端向节点设备透传数据
|
/// </summary>
|
public ClientDataPassthroughResponseData clientDataPassthroughResponseData;
|
}
|
/// <summary>
|
/// 客户端向节点设备透传数据
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public ClientDataPassthroughResponseData clientDataPassthroughResponseData = new ClientDataPassthroughResponseData();
|
|
[System.Serializable]
|
public class ClientDataPassthroughResponseData
|
{
|
/// <summary>
|
/// 透传的数据,最大256个字符,也就是透传128个字节
|
/// </summary>
|
public string PassData;
|
}
|
|
/// <summary>
|
/// 启用或关闭节点设备透传数据上传接口,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class OnZbDataPassthroughResponseAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 启用或关闭节点设备透传数据上传接口
|
/// </summary>
|
public OnZbDataPassthroughData onZbDataPassthroughData;
|
}
|
|
[System.Serializable]
|
public class OnZbDataPassthroughData
|
{
|
/// <summary>
|
/// 已经转换成字符格式的16进制的透传数据
|
/// </summary>
|
public string PassData;
|
}
|
#endregion
|
|
#region 下载云端固件.
|
/// <summary>
|
/// 下载云端设备固件
|
/// </summary>
|
/// <returns>The file async.</returns>
|
/// <param name="gateway">Gateway:当前网关</param>
|
/// <param name="distributedMark">Distributed mark:固件唯一标识</param>
|
/// <param name="imageName">Image name:固件版本</param>
|
public async System.Threading.Tasks.Task<DownloadFileResponAllData> DownloadFileAsync(ZigBee.Device.ZbGateway gateway, string distributedMark, string imageName)
|
{
|
if (gateway == null)
|
{
|
return null;
|
}
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
DownloadFileResponAllData d = null; ;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new DownloadFileResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
else
|
{
|
d = new DownloadFileResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "DownloadFile_Respon")
|
{
|
var downloadFileResponData = Newtonsoft.Json.JsonConvert.DeserializeObject<DownloadFileResponData>(jobject["Data"].ToString());
|
|
if (downloadFileResponData == null)
|
{
|
d = new DownloadFileResponAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new DownloadFileResponAllData { downloadFileResponData = downloadFileResponData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
gateway.Actions += action;
|
try
|
{
|
var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 6000 } };
|
var data = new JObject {
|
{ "DistributeMark", distributedMark},
|
{ "DownloadPath", "/tmp" },
|
{ "FileName", imageName }
|
};
|
jObject.Add("Data", data);
|
gateway.Send("DownloadFile", jObject.ToString());
|
}
|
catch
|
{
|
}
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < 30 * 1000)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > 30 * 1000)
|
{
|
d = new DownloadFileResponAllData { errorMessageBase = " 回复超时,请重新操作" };
|
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("DownloadFile_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
|
}
|
|
/// <summary>
|
/// 网关系统升级,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class DownloadFileResponAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 下载云端固件
|
/// </summary>
|
public DownloadFileResponData downloadFileResponData;
|
}
|
|
/// <summary>
|
/// 下载云端固件
|
/// </summary>
|
[System.Serializable]
|
public class DownloadFileResponData
|
{
|
/// <summary>
|
/// 下载固件的唯一标识
|
/// </summary>
|
public string DistributeMark;
|
/// <summary>
|
/// 0:成功,开启启动下载。
|
///<para>1:失败,文件创建失败。</para>
|
///<para>2:失败,云端没有找到该标识文件。</para>
|
///<para>3:网关未能连接云端。</para>
|
///<para>4:其他错误。</para>
|
/// </summary>
|
public int Result;
|
}
|
|
/// <summary>
|
/// 下载进度
|
/// </summary>
|
[Newtonsoft.Json.JsonIgnore]
|
public DownloadFileProgressResponData downloadFileProgressResponData;
|
/// <summary>
|
/// 下载进度
|
/// </summary>
|
[System.Serializable]
|
public class DownloadFileProgressResponData
|
{
|
/// <summary>
|
/// 下载固件的唯一标识
|
/// </summary>
|
public string DistributeMark;
|
/// <summary>
|
///<para>0:下载成功</para>
|
///<para>1:正在下载</para>
|
///<para>2:下载失败</para>
|
/// </summary>
|
public int Status;
|
/// <summary>
|
///文件总大小
|
/// </summary>
|
public int TotalSize;
|
/// <summary>
|
///当前已经下载文件大小
|
/// </summary>
|
public int DownloadSize;
|
/// <summary>
|
///下载进度,百分比。每百分之十反馈一次
|
/// </summary>
|
public int DownloadPercent;
|
}
|
|
#endregion
|
|
#region 终止设备升级;
|
/// <summary>
|
/// 终止设备升级
|
/// </summary>
|
/// <returns>The NVA sync.</returns>
|
/// <param name="gateway">Gateway.</param>
|
/// <param name="oTAImageName">O TAI mage name:升级镜像名称</param>
|
public async System.Threading.Tasks.Task<KillUpdateResponseAllData> KillUpdateAsync(ZigBee.Device.ZbGateway gateway, int deviceEpoint = 200)
|
{
|
return await System.Threading.Tasks.Task.Run(async () =>
|
{
|
KillUpdateResponseAllData d = null; ;
|
Action<string, string> action = (topic, message) =>
|
{
|
var gatewayID = topic.Split('/')[0];
|
var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
|
|
if (topic == gatewayID + "/" + "Error_Respon")
|
{
|
var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
|
|
if (temp == null)
|
{
|
d = new KillUpdateResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
|
}
|
|
else
|
{
|
d = new KillUpdateResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
|
}
|
}
|
|
if (topic == gatewayID + "/" + "OTA/KillUpdate_Respon")
|
{
|
var killUpdateData = Newtonsoft.Json.JsonConvert.DeserializeObject<KillUpdateData>(jobject["Data"].ToString());
|
|
if (killUpdateData == null)
|
{
|
d = new KillUpdateResponseAllData { errorMessageBase = "网关返回的数据为空" };
|
}
|
else
|
{
|
d = new KillUpdateResponseAllData { killUpdateData = killUpdateData };
|
System.Console.WriteLine($"UI收到通知后的主题_{ topic}");
|
}
|
}
|
};
|
gateway.Actions += action;
|
System.Console.WriteLine("OTA/KillUpdate_Actions 启动" + "_" + System.DateTime.Now.ToString());
|
|
try
|
{
|
var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", deviceEpoint }, { "Cluster_ID", 25 }, { "Command", 5 } };
|
gateway.Send("OTA/KillUpdate", jObject.ToString());
|
}
|
catch
|
{ }
|
var dateTime = DateTime.Now;
|
while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
|
{
|
await System.Threading.Tasks.Task.Delay(10);
|
if (d != null)
|
{
|
break;
|
}
|
}
|
if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
|
{
|
d = new KillUpdateResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
|
}
|
gateway.Actions -= action;
|
System.Console.WriteLine("OTA/KillUpdate_Actions 退出" + System.DateTime.Now.ToString());
|
|
return d;
|
});
|
}
|
|
/// <summary>
|
/// 终止设备升级,网关反馈具体信息
|
/// </summary>
|
[System.Serializable]
|
public class KillUpdateResponseAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 终止设备升级
|
/// </summary>
|
public KillUpdateData killUpdateData;
|
}
|
|
[System.Serializable]
|
public class KillUpdateData
|
{
|
/// <summary>
|
///0:终止成功
|
///<para>1:终止失败,设备并不处于OTA升级状态。</para>
|
/// </summary>
|
public int Result;
|
}
|
#endregion
|
|
#region 私有协议网关和设备的默认回复
|
|
[System.Serializable]
|
public class ResponseAllData : ErrorResponCommon
|
{
|
/// <summary>
|
/// 按键指示灯颜色信息
|
/// </summary>
|
public ResponseData responseData;
|
}
|
|
/// <summary>
|
/// 私有协议网关和设备的默认回复
|
/// </summary>
|
[System.Serializable]
|
public class ResponseData
|
{
|
/// <summary>
|
///响应操作码(0-ffff)
|
/// </summary>
|
public string command;
|
/// <summary>
|
/// 状态值
|
/// <para>0--成功 1--失败 ff--无效</para>
|
/// </summary>
|
public int status = -1;
|
}
|
#endregion
|
|
#region ■ 调试打印
|
|
/// <summary>
|
/// 调试时打开打印信息,true:打印,false:不打印
|
/// </summary>
|
/// <param name="msg">Message.</param>
|
/// <param name="flage">If set to <c>true</c> flage.</param>
|
public static void DebugPrintLog(string msg, bool flage = true)
|
{
|
#if DEBUG
|
if (flage == true)
|
{
|
if (msg.Contains("DeviceStatusReport") == false)
|
{
|
System.Console.WriteLine(msg + " " + System.DateTime.Now.ToLongTimeString() + " " + System.DateTime.Now.Millisecond);
|
}
|
}
|
#endif
|
}
|
|
#endregion
|
}
|
}
|