using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Linq;
namespace ZigBee.Device
{
[System.Serializable]
public class CommonDevice
{
#region 需要保存的变量
///
/// 是否是自定义图片
///
public bool IsCustomizeImage = false;
///
/// 设备图片
///
public string IconPath = string.Empty;
///
/// 设备图片--在线或者选中状态
///
/// The online icon path.
[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";
}
}
///
/// 当前网关的ID
///
public string CurrentGateWayId;
///
/// 当前设备类型
///
[Newtonsoft.Json.JsonIgnore]
public DeviceType Type = DeviceType.UnKown;
///
/// 设备的功能类型(此类型目前只针对继电器回路有效,默认未指定)
///
public DeviceFunctionType DfunctionType = DeviceFunctionType.A未定义;
///
/// MAC地址
///
public string DeviceAddr;
///
/// 设备端口号
///
public int DeviceEpoint;
///
/// 实际的设备id
/// 258:color dimmable light,调关灯
/// 10:Door lock,门锁
/// 514:Window covering device,窗帘
/// 515:Window covering controller,窗帘控制器
/// 769:Thermostat,恒温面板/空调
/// 770:Temperature Sensor,温度传感器
/// 775:Temperature Sensor,湿度传感器
/// 262:Light sensor,光照传感器
/// 1026:sensor,传感器,具体类型的传感器DeviceType来区分
///
public int DeviceID;
///
/// 2020.09.21追加:为了对应第三方设备,以及之后的多设备ID问题,追加的变量
/// 这是个特殊的,并且不保存在文件当中的ID, DeviceType由此值映射出来
/// 当设备是河东设备时,它与DeviceID相等
/// 当是真正的第三方设备时,它有可能与DeviceID不相等
/// 比如:2和256都是继电器,那么【DeviceID为2 或者 DeviceID为256】 而 【ExDeviceID固定为2】,【DeviceType为OnOffOutput】
/// 通俗来说:DeviceID是实际正确的ID,而【ExDeviceID是一种所属概念的ID】
///
[Newtonsoft.Json.JsonIgnore]
public int ExDeviceID;
///
/// 该字段主要针对IAS安防设备设立。所有IAS安防设备共用一个DeviceID为1026。所以要区分子设备类型,需要该字段。
/// 瞬间数据上报的传感器 (MomentStatus=1 TriggerZoneStatus>=1<报警>)
/// 13:Motion sensor (运动传感器)
/// 40 Fire sensor 烟雾传感器
/// 42 Water sensor 水侵传感器
/// 43 Carbon Monoxide (CO) 燃气传感器
/// 44 Personal emergency device 紧急按钮
/// 277 Key fob 钥匙扣
/// 持续数据上报(MomentStatus=0 TriggerZoneStatus>=1<报警> TriggerZoneStatus=0<取消报警>)
/// 21: Door/Window 门窗传感器(有21和22,这里没有写错)
/// 22:Door/Window 门窗传感器(有21和22,这里没有写错
///
public int IasDeviceType;
///
/// 设备名称,以设备的MAC命名
///
public string DeviceName = "UnKown";
///
/// 设备端点名称,以设备端点名称命名
///
public string DeviceEpointName = "UnKown";
///
/// 用于判断设备的zigbee协议版本。
///49246:ZLL1.0标准设备。
///260: ZHA1.2标准设备、 Z3.0标准设备。
///41440:ZGP3.0标准设备。
///265:ZSE1.4标准设备。
///
[Newtonsoft.Json.JsonIgnore]
public int Profile;
///
/// 0:设备不在线
/// 1:设备在线
///
public int IsOnline;
///
/// 1:路由设备
/// 2:终端设备,电池设备
///
public int ZigbeeType;
///
/// 固件版本
///
public int ImgVersion;
///
/// 硬件版本
///
public int HwVersion;
///
/// 当前镜像类型id
///
public int ImgTypeId;
///
/// 驱动代码。为0时,表示zigbee协调器设备。其他值表示为虚拟驱动设备
///
public int DriveCode;
///
/// 生产商名字
///
public string ManufacturerName = string.Empty;
///
/// 模块ID(这个东西也叫【型号码】)
///
public string ModelIdentifier = string.Empty;
///
/// 生产日期
///
public string ProductionDate = string.Empty;
///
/// 电源
///
public int PowerSource = -1;
///
/// 序列号
///
public string SerialNumber = string.Empty;
///
/// 输入簇列表
///
public List InClusterList = new List();
///
/// 输出簇列表
///
public List OutClusterList = new List();
///
/// 用于记录设备最新上报的属性状态信息
///
public List AttributeStatus = new List();
[Newtonsoft.Json.JsonIgnore]
public DateTime LastDateTime = DateTime.MinValue;
///
/// 是否已经读取了设备状态(此属性是给主页使用的)
///
[Newtonsoft.Json.JsonIgnore]
public bool HadReadDeviceStatu = false;
///
/// 是否是低电量(这个变量目前是给传感器用的)
///
[Newtonsoft.Json.JsonIgnore]
public bool IsBatteryDown = false;
///
/// 等待从网关接收数据的时间
///
/// The wait receive data time.
[Newtonsoft.Json.JsonIgnore]
public virtual int WaitReceiveDataTime
{
get
{
if (Device.ZbGateway.RemoteMqttClient != null && Device.ZbGateway.RemoteMqttClient.IsConnected)
{
return 10000;
}
else
{
return 3000;
}
}
}
///
/// 通过设备调用网关
///
[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;
}
}
///
/// 保存设备数据的文件名
///
[Newtonsoft.Json.JsonIgnore]
public virtual string FilePath
{
get
{
//2020.09.21 对应第三方设备可以入网,设备文件名字,去掉 deviceType
return "Device_" + DeviceAddr + "_" + DeviceEpoint.ToString().PadLeft(2, '0');
}
}
#endregion
#region 设备保存及生成
///
/// 由设备字符串比特恢复设备对象
///
/// 设备DeviceType的整型值
/// 设备Json文件转为比特后再转为的字符串
///
public static CommonDevice CommonDeviceByByteString(int intDeviceType, string strDeviceByte)
{
//这是河东的特殊端点,不需要处理
if (intDeviceType == 49408)
{
return null;
}
CommonDevice device = null;
if (intDeviceType == (int)DeviceType.DimmableLight || intDeviceType == 3)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
device.ExDeviceID = (int)DeviceType.DimmableLight;
}
else if (intDeviceType == (int)DeviceType.OnOffOutput || intDeviceType == 256)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
device.ExDeviceID = (int)DeviceType.OnOffOutput;
}
else if (intDeviceType == (int)DeviceType.ColorDimmerSwitch)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.LevelControlSwitch)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.WindowCoveringDevice)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.WindowCoveringController)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.OnOffSwitch)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.IASZone)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.OtaDevice || intDeviceType == (int)DeviceType.OtaPanelDevice)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.AirSwitch)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.Repeater)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.Thermostat)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.Transverter)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.DoorLock)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.TemperatureSensor)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.FreshAirHumiditySensor)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.FreshAir)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.PMSensor)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.ColorTemperatureLight)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.Buzzer)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.ColorDimmableLight)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else if (intDeviceType == (int)DeviceType.DimmerSwitch)
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
else
{
device = Newtonsoft.Json.JsonConvert.DeserializeObject(strDeviceByte);
}
//这是河东的特殊端点,不需要处理
if (device.DeviceEpoint == 242 && intDeviceType == 97)
{
return null;
}
if (device.ExDeviceID == 0)
{
//赋初始值
device.ExDeviceID = device.DeviceID;
}
//能少存一个变量就少存一个
device.Type = (DeviceType)device.ExDeviceID;
return device;
}
///
/// 保存设备
///
public void Save()
{
if (Shared.Common.Global.IsExistsByHomeId(FilePath))
{
return;
}
ReSave();
}
///
/// 重新保存设备
///
public void ReSave()
{
if (Shared.Common.Config.Instance.Home.IsShowTemplate == true)
{
//展示模板时,不允许保存文件(防止属性上报用的)
return;
}
if (IconPath == string.Empty)
{
//保存设备图标(这里会保存一次,下面就不用保存了)
this.SaveDeviceIcon();
return;
}
Shared.Common.Global.WriteFileByBytesByHomeId(FilePath, System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this)));
}
///
/// 保存设备图标
///
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.Phone.HdlDeviceCommonLogic.Current.GetDeviceObjectIcon(new List { this }, ref unSelectPic, ref selectPic);
IconPath = unSelectPic;
}
Shared.Common.Global.WriteFileByBytesByHomeId(FilePath, System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this)));
}
}
#endregion
#region 输入输出镞定义
///
/// 设备最新上报的属性状态信息
///
[System.Serializable]
public class AttributeStatusObj
{
///
/// 属性簇id
///
public int ClusterId;
///
/// 属性id
///
public int AttributeId;
///
/// 属性值,这个东西不需要什么高位在后低位在前,它已经是转为了10进制
///
public int AttributeData;
///
/// 属性状态最后更新的utc时间戳
///
public int ReportTime;
}
///
/// 输入簇
///
[System.Serializable]
public class InClusterObj
{
///
/// 设备支持的输入功能
/// 0:Basic,设备支持“基础属性”
/// 3:Identify,设备支持“识别功能”
/// 4:Groups,设备支持“组功能”
/// 5:Scenes,设备支持“场景功能”
/// 6:on/off,设备支持“开关功能”
/// 开关功能的设备如:调关灯/继电器/窗帘等。。。
/// 8:Level Control,设备支持“亮度调节功能”
/// 亮度调节功能的设备如:调关灯。。。
/// 257:Door Lock,设备支持“门锁功能”
/// 门锁功能的设备如:门锁。。。
/// 258:Window Covering,设备支持“窗帘控制功能”
/// 窗帘控制功能的设备如:窗帘/开合帘/卷帘。。。
/// 513:Thermostat,设备支持“恒温器功能”
/// 恒温器功能的设备如:空调。。。
/// 768:Color Control,设备支持“颜色调节功能”
/// 颜色调节功能的设备如:调光灯。。。
/// 1026:Temperature Measurement,设备支持“温度测量功能”
/// 温度测量功能的设备如:温度传感器。。。
/// 1029:Relative Humidity Measurement,设备支持“湿度测量功能”
/// 湿度测量功能的设备如:湿度传感器。。。
/// 1066:Pm2.5 Measurement,设备支持“pm2.5测量功能”
/// Pm2.5测量功能的设备如:Pm2.5传感器。。。
///
public int InCluster;
}
///
/// 输出簇
///
[System.Serializable]
public class OutClusterObj
{
///
/// 设备支持的输出功能
/// 0:Basic,设备支持“基础属性”
/// 3:Identify,设备支持“识别功能”
/// 4:Groups,设备支持“组功能”
/// 5:Scenes,设备支持“场景功能”
/// 6:on/off,设备支持“开关功能”
/// 开关功能的设备如:调关灯/继电器/窗帘等。。。
/// 8:Level Control,设备支持“亮度调节功能”
/// 亮度调节功能的设备如:调关灯。。。
/// 257:Door Lock,设备支持“门锁功能”
/// 门锁功能的设备如:门锁。。。
/// 258:Window Covering,设备支持“窗帘控制功能”
/// 窗帘控制功能的设备如:窗帘/开合帘/卷帘。。。
/// 513:Thermostat,设备支持“恒温器功能”
/// 恒温器功能的设备如:空调。。。
/// 768:Color Control,设备支持“颜色调节功能”
/// 颜色调节功能的设备如:调光灯。。。
/// 1026:Temperature Measurement,设备支持“温度测量功能”
/// 温度测量功能的设备如:温度传感器。。。
/// 1029:Relative Humidity Measurement,设备支持“湿度测量功能”
/// 湿度测量功能的设备如:湿度传感器。。。
///
public int OutCluster;
}
///
/// 支持的属性数据
///
[System.Serializable]
public class AttributeObj
{
///
/// 响应的属性ID
///
public int AttributeId;
///
/// 属性值的数据类型
///
public int AttributeType;
}
///
/// 设备上报的属性数据
///
[System.Serializable]
public class AttributeDataObj
{
///
/// 属性id
///
public int AttributeId;
///
/// 要报告属性的数据类型
///
public int AttriButeDataType;
///
/// AttriButeData占用的字节数
///
public int AttriButeDataLength;
///
/// 属性值
///
public int AttriButeData = 999;
///
/// 属性数据16进制转字符
///
public string AttriButeDataHex;
}
///
/// Command数组
///
[System.Serializable]
public class CommandObj
{
///
/// 支持的命令id
///
public int commandId;
}
#endregion
#region 获取已入网设备信息
///
/// 网关中的设备信息
///
[Newtonsoft.Json.JsonIgnore]
public DeviceInfoData DeviceInfo = null;
///
/// 网关中的设备信息
///
[System.Serializable]
public class DeviceInfoData
{
///
/// 入网设备总数。等于0时,表示没有设备信息,下面字段将不存在。
///
public int TotalNum;
///
/// 标识当前设备是发送的是第几个设备。DeviceNum从1开始每发送一个设备信息,下一个设备信息的DeviceNum将加1。直到DeviceNum等于TotalNum说明所有设备信息发送完毕。
///
public int DeviceNum;
///
/// 入网的utc时间戳
///
public int JoinTime;
///
/// 1:路由器设备
/// 2:终端设备
///
public int ZigbeeType;
///
/// 设备网络地址
///
public int NwkAddr;
///
/// 该字段主要针对IAS安防设备设立。所有IAS安防设备共用一个DeviceID为1026。所以要区分子设备类型,需要该字段。
/// 13:Motion sensor (运动传感器)
/// 43:Carbon Monoxide sensor (一氧化碳传感器)
/// 44:Personal emergency device (紧急按钮)
///
public int DeviceType;
///
/// 用于判断设备的zigbee协议版本。
///49246:ZLL1.0标准设备。
///260: ZHA1.2标准设备、 Z3.0标准设备。
///41440:ZGP3.0标准设备。
///265:ZSE1.4标准设备。
///
public int Profile;
///
/// 设备mac名称
///
public string MacName;
///
/// 设备名(Mac+断点命名的)
///
public string DeviceName;
///
/// 0:设备不在线
/// 1:设备在线
///
public int IsOnline;
///
/// 当前运行程序版本信息。 最大64字节
///
public int ImgVersion;
///
/// 硬件版本
///
public int HwVersion;
///
/// 当前镜像类型id
///
public int ImgTypeId;
///
/// 驱动代码。为0时,表示zigbee协调器设备。其他值表示为虚拟驱动设备
///
public int DriveCode;
///
/// 厂商名称
///
public string ManufacturerName = string.Empty;
///
/// 模块ID
///
public string ModelIdentifier = string.Empty;
///
/// 好像是序列号
///
public string ProductCode = string.Empty;
///
/// 设备功能类型(空气开关和继电器专用)
///
public int FunctionType = -1;
///
/// 输入簇列表
///
public List InClusterList = new List();
///
/// 输出簇列表
///
public List OutClusterList = new List();
///
/// 用于记录设备最新上报的属性状态信息。最大支持记录16个属性状态,且只记录属性值长度不大于4字节的数据。
///
public List AttributeStatus = new List();
}
#endregion
#region 错误结果定义
///
/// 网关信息错误反馈共通
///
[System.Serializable]
public class ErrorResponCommon
{
///
/// 错误信息
///
public string errorMessageBase;
///
/// 网关信息错误反馈
/// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。
///
public ErrorResponData errorResponData;
}
///
/// 网关信息错误反馈
/// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。
///
[System.Serializable]
public class ErrorResponData
{
///
/// Error参数含义
///1:网关无法解析命令数据。
///2:协调器正在升级或备份/恢复数据
///3:操作设备/组/场景不存在
///4:其他错误
///5:数据传输错误(在某次客户端向网关发送数据的过程中,网关在合理时间范围内接收客户端数据不完整导致该错误发生。如客户端向网关一次发送100个字节的数据,但网关等待接收了一秒只接收了80个字节。发生该错误,网关将主动关闭客户端连接)
///
public int Error;
}
///
/// 网关错误信息具体内容
///
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 修改设备端口名称
///
/// 重命名设备,网关反馈具体信息
///
[System.Serializable]
public class DeviceRenameAllData
{
///
/// 错误信息
///
public string errorMessageBase;
///
/// 网关信息错误反馈
/// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。
///
public ErrorResponData errorResponData;
///
/// 设备名称修改
///
public DeviceRenameResponseData deviceRenameData;
}
///
/// 设备名称修改
///
[System.Serializable]
public class DeviceRenameResponseData
{
///
/// 0:修改成功
/// 1:修改失败
///
public int Result;
///
/// 修改后的设备名称
///
public string DeviceName;
}
#endregion
#region 修改设备mac名称
///
/// 修改设备mac名称数据,网关反馈具体信息
///
[System.Serializable]
public class RenameDeviceMacNameAllData : ErrorResponCommon
{
///
/// 修改设备mac名称数据
///
public RenameDeviceMacNameData renameDeviceMacNameData;
}
///
/// 修改设备mac名称数据
///
[System.Serializable]
public class RenameDeviceMacNameData
{
///
/// 0:修改成功
/// 1:修改失败,mac不存在
///
public int Result;
///
/// 修改后的设备名称
///
public string MacName;
}
#endregion
#region 一键更新四寸屏按键属性
///
/// 同步设备功能
///
///
public async System.Threading.Tasks.Task SyncMsgToBindSource(string deviceAddr, int deviceEpoint)
{
if (Gateway == null)
{
return null;
}
return await System.Threading.Tasks.Task.Run(async () =>
{
SynchronizationDeviceResponseAllData resContent = null;
Action 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(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(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;
});
}
///
/// 同步设备,网关反馈具体信息
///
[System.Serializable]
public class SynchronizationDeviceResponseAllData
{
///
/// 错误信息
///
public string errorMessageBase;
///
/// 网关信息错误反馈
/// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。
///
public ErrorResponData errorResponData;
///
/// 同步结果
/// 0:成功:网关内部自动写入设备目标名字、设备目标功能类型、场景目标名字、utc时间写入4寸屏
/// 1:失败
///
public int result;
}
#endregion
#region 删除设备(使设备离网)
///
/// 删除设备(使设备离网)
///
/// The device async.
/// Remove data.
public async System.Threading.Tasks.Task 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 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(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(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;
});
}
///
/// 需要删除设备的数据
///
[System.Serializable]
public class RemoveDeviceData
{
///
/// 0:不强制清除。需要节点设备反馈离网确认信息后才能删除设备信息。
///1:强制清除。不需要节点设备反馈离网确认信息,直接删除设备信息。
///说明:正常情况下让节点设备离网,需要节点设备在线,节点设备反馈离网确认信息后网关方可删除该设备的设备信息。但如果设备已经损坏,或已经通过外部功能离网,此时节点设备已经无法反馈离网确认信息,面对这种情况,要删除保存在网关上的该节点设备的设备信息,需要将该字段赋值为1,网关强制删除该设备信息,不需要节点设备确认。
///
public int CompelClear = 1;
///
/// 出网设备列表
///
public List DeviceAddrList = new List();
}
///
/// 场景信息
///
public class RemoveDeviceListInfo
{
///
/// 设备mac地址
///
public string DeviceAddr;
}
///
/// 移除设备,网关反馈具体信息
///
[System.Serializable]
public class RemoveDeviceResponseAllData
{
///
/// 错误信息
///
public string errorMessageBase;
///
/// 网关信息错误反馈
/// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。
///
public ErrorResponData errorResponData;
///
/// 设备名称修改
///
public RemoveDeviceResponseData removeDeviceResponseData;
}
///
/// 删除设备回复数据
/// 返回结果Resul=,删除成功
///
[System.Serializable]
public class RemoveDeviceResponseData
{
///
/// 0:删除成功
/// 删除失败
///
public int Result = 2;
///
/// 出网设备列表
///
public List DeviceList = new List();
}
///
/// 场景信息
///
[System.Serializable]
public class DeviceListInfo
{
///
/// 设备ID
///
public int Device_ID;
///
/// 设备mac地址
///
public string MacAddr;
///
/// 设备端口号
///
public int Epoint;
}
#endregion
#region 识别设备
///
/// 识别设备
/// cluster=3,具有Identify(识别)功能,属于ZCL库
/// time:设置设备闪烁时间(秒)范围:0-65535
///
public void IdentifyControl(string deviceAddr, int deviceEpoint, int time)
{
if (Gateway == null)
{
return;
}
Action 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 设备属性状态上报
///
/// 获取设备当前属性状态
///
/// Cluster identifier.
/// Attri bute identifier.
public async void ReadAttri(Cluster_ID clusterID, AttriButeId attriButeId)
{
if (Gateway == null)
{
return;
}
await System.Threading.Tasks.Task.Run(async () =>
{
//Action 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());
});
}
///
/// 设备属性状态上报
///
[Newtonsoft.Json.JsonIgnore]
public DeviceStatusReportData DeviceStatusReport = new DeviceStatusReportData();
///
/// 设备属性状态上报
///
[System.Serializable]
public class DeviceStatusReportData
{
///
/// 属性所在CluterID
///
/// 设备支持的输入功能
/// 0:Basic,设备支持“基础属性”
/// 3:Identify,设备支持“识别功能”
/// 4:Groups,设备支持“组功能”
/// 5:Scenes,设备支持“场景功能”
/// 6:on/off,设备支持“开关功能”
/// 开关功能的设备如:调关灯/继电器/窗帘等。。。
/// 8:Level Control,设备支持“亮度调节功能”
/// 亮度调节功能的设备如:调关灯。。。
/// 257:Door Lock,设备支持“门锁功能”
/// 门锁功能的设备如:门锁。。。
/// 258:Window Covering,设备支持“窗帘控制功能”
/// 窗帘控制功能的设备如:窗帘/开合帘/卷帘。。。
/// 513:Thermostat,设备支持“恒温器功能”
/// 恒温器功能的设备如:空调。。。
/// 768:Color Control,设备支持“颜色调节功能”
/// 颜色调节功能的设备如:调光灯。。。
/// 1026:Temperature Measurement,设备支持“温度测量功能”
/// 温度测量功能的设备如:温度传感器。。。
/// 1029:Relative Humidity Measurement,设备支持“湿度测量功能”
/// 湿度测量功能的设备如:湿度传感器。。。
///
///
public int CluterID;
///
/// 属性列表
///
public List AttriBute = new List();
}
#endregion
#region 设置可写属性的值
///
/// 设置可写属性的值
///
/// The writable value async.
/// Gateway.
/// 要配置的属性所在的cluster.
/// 设置可写属性的数据
public async System.Threading.Tasks.Task 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 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(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(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;
});
}
///
/// 网关版本信息,网关反馈信息
///
[System.Serializable]
public class SetWritableValueResponAllData : ErrorResponCommon
{
///
/// 网关版本信息
///
public SetWritableValueResponData setWritableValueResponData;
}
///
/// 设置可写属性的值的数据
///
[System.Serializable]
public class SetWritableValueResponData
{
///
/// 配置属性所在的cluster
///
public int Cluster;
///
/// 0:配置成功(若配置成功,下面的AttributeId字段不存在)
///134:不支持该属性
///135:无效的属性值
///141:无效的数据类型
///
public int Status;
///
/// 配置的属性ID(当Status=0 时,该字段将不存在 ,也就是只有失败的结果才会返回该字段)
///
public int AttributeId;
}
///
/// 设置可写属性的值的数据
///
[System.Serializable]
public class SetWritableValueData
{
///
/// 是否强制写入属性
///0:否
///1:强制写属性值
///可缺省,默认为0。
///
public int Undivided;
///
/// 属性id
///
public int AttributeId;
///
/// 属性数据类型
///
public int AttributeDataType;
///
/// 写入数值
///
public int AttributeData;
}
#endregion
#region 开关
///
///开关控制(仅用于cluster=6的设备)
/// 设备支持cluster=6的设备才能调用该接口
/// command的值
///0 : 关闭
///1: 打开
///2:取反
///
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库-发现属性
///
///ZCL库-发现属性(如果返回为空,可能是设备不是标准设备,不支持这条命令)
/// 获取设备的某个Cluster所支持的Attributes
/// gateway:当前网关
/// clusterID:需要查询的cluster
/// 读Panel的属性:clusterID=6
/// 读亮度的属性:clusterID=8
///
public async System.Threading.Tasks.Task ClusterOwnAttributesAsync(ZigBee.Device.ZbGateway gateway, int clusterID)
{
if (gateway == null)
{
return null;
}
return await System.Threading.Tasks.Task.Run(async () =>
{
ClusterOwnAttributesResponAllData d = null;
Action 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(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(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(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;
});
}
///
/// 发现属性,网关反馈信息
///
[System.Serializable]
public class ClusterOwnAttributesResponAllData : ErrorResponCommon
{
///
/// 网关版本信息
///
public ClusterOwnAttributesResponData clusterOwnAttributesResponData;
}
[System.Serializable]
public class ClusterOwnAttributesResponData
{
///
/// 查询的cluste
///
public int Cluster;
///
/// 设备属性列表
///
public List AttributeList = new List();
}
#endregion
#region ZCL库-支持的Command
///
///ZCL库-设备某cluster所支持的Command ;(如果返回为空,可能是设备不是标准设备,不支持这条命令)
/// 获取设备某cluster所支持的Command
/// gateway:当前网关
/// clusterID:需要查询的cluster
///
public async System.Threading.Tasks.Task ClusterOwnCommandAsync(ZigBee.Device.ZbGateway gateway, int clusterID)
{
if (gateway == null)
{
return null;
}
return await System.Threading.Tasks.Task.Run(async () =>
{
ClusterOwnCommandResponAllData d = null;
Action 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(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(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;
});
}
///
/// 设备某cluster所支持的Command数据,网关反馈信息
///
[System.Serializable]
public class ClusterOwnCommandResponAllData : ErrorResponCommon
{
///
/// 网设备某cluster所支持的Command数据
///
public ClusterOwnCommandResponData clusterOwnCommandResponData;
}
///
/// 设备某cluster所支持的Command数据
///
[System.Serializable]
public class ClusterOwnCommandResponData
{
///
/// 查询的cluste
///
public int Cluster;
///
/// 设备属性列表
///
public List Command = new List();
}
#endregion
#region 设定OTA升级固件.;
///
/// 设定OTA升级固件
///
/// The NVA sync.
/// Gateway.
/// O TAI mage name:升级镜像名称
public async System.Threading.Tasks.Task UpgradeDeviceAsync(ZigBee.Device.ZbGateway gateway, string oTAImageName)
{
return await System.Threading.Tasks.Task.Run(async () =>
{
OTASetImageResponseAllData d = null; ;
Action 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(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(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;
});
}
///
/// 设备进行OTA升级,网关反馈具体信息
///
[System.Serializable]
public class OTASetImageResponseAllData : ErrorResponCommon
{
///
/// 保存zigbee协调器组网信息
///
public OTASetImageData otaSetImageData;
}
[System.Serializable]
public class OTASetImageData
{
///
/// 0:成功
///1:没有找到文件或打开文件失败
///2:当前有节点设备正在ota升级,原来的ota固件还在占用,不能重新设定固件。若要重新设定ota固件,则需要先用终止升级指令终止所有正在升级的节点设备。
///
public int Result;
///
/// 该ota固件的制造商ID(Result = 0时存在)
///
public int Manufacture;
///
/// 该ota固件的固件类型id(Result = 0时存在)
///
public int ImgTypeId;
///
/// 该ota固件的版本(Result = 0时存在)
///
public int FileVersion;
///
/// 固件大小
///
public int FileSize;
///
///正在升级的ota节点设备列(Result=2时,该字段才存在)
///
public List DeviceList = new List();
}
///
/// 输入簇
///
[System.Serializable]
public class OTADeviceList
{
///
/// MAC地址
///
public string MacAddr;
///
/// 设备端口号,当升级设备,HDL的设备大多数的端点默认是200
///
public int Epoint = 200;
}
#endregion
#region 启动升级;
///
/// 设定OTA升级固件
///
/// The NVA sync.
/// Gateway.
/// O TAI mage name:升级镜像名称
public async System.Threading.Tasks.Task StartDeviceUpdateAsync(ZigBee.Device.ZbGateway gateway, StartUpdateData startUpdateData)
{
return await System.Threading.Tasks.Task.Run(async () =>
{
StartDeviceUpdateResponseAllData d = null; ;
Action 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(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(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;
});
}
///
/// 启动升级,网关反馈具体信息
///
[System.Serializable]
public class StartDeviceUpdateResponseAllData
{
///
/// 错误信息
///
public string errorMessageBase;
///
/// 网关信息错误反馈
/// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。
///
public ErrorResponData errorResponData;
///
/// 保存zigbee协调器组网信息
///
public StartDeviceUpdateData startUpdateDeviceData;
}
[System.Serializable]
public class StartDeviceUpdateData
{
///
/// 0:正常
/// 1:启动失败,未设定升级固件
///
public int Result = 999;
///
///升级设备列表
///
public List DeviceList = new List();
}
///
/// 输入簇
///
[System.Serializable]
public class OTAStartUpdateList
{
///
/// MAC地址
///
public string MacAddr;
///
/// 设备端口号,当升级设备,HDL的设备大多数的端点默认是200
///
public int Epoint = 200;
///
/// 设备名称
///
public string DeviceName;
}
///
/// 启动升级
///
[Newtonsoft.Json.JsonIgnore]
public OTAScheduleResponData oTAScheduleResponData;
[System.Serializable]
public class OTAScheduleResponData
{
///
/// 0:节点设备可进行OTA升级(如果设备在线,且支持OTA升级,则设备首先会反馈该状态,说明该设备OTA升级已启动)
///1:正在升级(设备处于下载OTA升级固件状态将反馈该状
///2:升级完成(OTA升级完成,节点设备反馈该状态)
///3:升级失败,响应超时
///150:无效的OTA升级固件(下载完成后,由节点设备判断固件是否有效)
///153:客户端仍需更多的OTA升级固件
///149:升级终止
///
public int Status = 999;
///
/// 升级百分比。(当Status=1时有效)
///
public int Percent = 999;
}
[System.Serializable]
public class StartUpdateData
{
///
///升级设备列表
///
public List DeviceList = new List();
}
#endregion
#region 客户端向节点设备透传数据.
///
/// 客户端向节点设备透传数据
/// passData:透传数据(这里的值是在各个设备对象中复制好的,传进来即可)
/// 透传数据返回后,可以调用各个设备对象中获取相应的处理完成的数据
///
public async System.Threading.Tasks.Task ClientDataPassthroughAsync(ZigBee.Device.ZbGateway gateway, string passData)
{
return await System.Threading.Tasks.Task.Run(async () =>
{
ClientDataPassthroughResponseAllData d = null; ;
Action 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(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(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;
});
}
///
/// 客户端向节点设备透传数据,网关反馈具体信息
///
[System.Serializable]
public class ClientDataPassthroughResponseAllData : ErrorResponCommon
{
///
/// 客户端向节点设备透传数据
///
public ClientDataPassthroughResponseData clientDataPassthroughResponseData;
}
///
/// 客户端向节点设备透传数据
///
[Newtonsoft.Json.JsonIgnore]
public ClientDataPassthroughResponseData clientDataPassthroughResponseData = new ClientDataPassthroughResponseData();
[System.Serializable]
public class ClientDataPassthroughResponseData
{
///
/// 透传的数据,最大256个字符,也就是透传128个字节
///
public string PassData;
}
///
/// 启用或关闭节点设备透传数据上传接口,网关反馈具体信息
///
[System.Serializable]
public class OnZbDataPassthroughResponseAllData : ErrorResponCommon
{
///
/// 启用或关闭节点设备透传数据上传接口
///
public OnZbDataPassthroughData onZbDataPassthroughData;
}
[System.Serializable]
public class OnZbDataPassthroughData
{
///
/// 已经转换成字符格式的16进制的透传数据
///
public string PassData;
}
#endregion
#region 下载云端固件.
///
/// 下载云端设备固件
///
/// The file async.
/// Gateway:当前网关
/// Distributed mark:固件唯一标识
/// Image name:固件版本
public async System.Threading.Tasks.Task 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 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(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(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;
});
}
///
/// 网关系统升级,网关反馈具体信息
///
[System.Serializable]
public class DownloadFileResponAllData : ErrorResponCommon
{
///
/// 下载云端固件
///
public DownloadFileResponData downloadFileResponData;
}
///
/// 下载云端固件
///
[System.Serializable]
public class DownloadFileResponData
{
///
/// 下载固件的唯一标识
///
public string DistributeMark;
///
/// 0:成功,开启启动下载。
///1:失败,文件创建失败。
///2:失败,云端没有找到该标识文件。
///3:网关未能连接云端。
///4:其他错误。
///
public int Result;
}
///
/// 下载进度
///
[Newtonsoft.Json.JsonIgnore]
public DownloadFileProgressResponData downloadFileProgressResponData;
///
/// 下载进度
///
[System.Serializable]
public class DownloadFileProgressResponData
{
///
/// 下载固件的唯一标识
///
public string DistributeMark;
///
///0:下载成功
///1:正在下载
///2:下载失败
///
public int Status;
///
///文件总大小
///
public int TotalSize;
///
///当前已经下载文件大小
///
public int DownloadSize;
///
///下载进度,百分比。每百分之十反馈一次
///
public int DownloadPercent;
}
#endregion
#region 终止设备升级;
///
/// 终止设备升级
///
/// The NVA sync.
/// Gateway.
/// O TAI mage name:升级镜像名称
public async System.Threading.Tasks.Task KillUpdateAsync(ZigBee.Device.ZbGateway gateway, int deviceEpoint = 200)
{
return await System.Threading.Tasks.Task.Run(async () =>
{
KillUpdateResponseAllData d = null; ;
Action 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(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(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;
});
}
///
/// 终止设备升级,网关反馈具体信息
///
[System.Serializable]
public class KillUpdateResponseAllData : ErrorResponCommon
{
///
/// 终止设备升级
///
public KillUpdateData killUpdateData;
}
[System.Serializable]
public class KillUpdateData
{
///
///0:终止成功
///1:终止失败,设备并不处于OTA升级状态。
///
public int Result;
}
#endregion
#region 私有协议网关和设备的默认回复
[System.Serializable]
public class ResponseAllData : ErrorResponCommon
{
///
/// 按键指示灯颜色信息
///
public ResponseData responseData;
}
///
/// 私有协议网关和设备的默认回复
///
[System.Serializable]
public class ResponseData
{
///
///响应操作码(0-ffff)
///
public string command;
///
/// 状态值
/// 0--成功 1--失败 ff--无效
///
public int status = -1;
}
#endregion
#region ■ 调试打印
///
/// 调试时打开打印信息,true:打印,false:不打印
///
/// Message.
/// If set to true flage.
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
}
}