using System; using System.Collections.Generic; using System.Text; using ZigBee.Device; using System.Threading.Tasks; using Newtonsoft.Json.Linq; namespace Shared.Phone.UserCenter { /// /// 设备绑定的逻辑 /// public class HdlDeviceBindLogic { #region ■ 变量声明___________________________ /// /// 设备绑定的逻辑 /// private static HdlDeviceBindLogic m_Current = null; /// /// 设备绑定的逻辑 /// public static HdlDeviceBindLogic Current { get { if (m_Current == null) { m_Current = new HdlDeviceBindLogic(); } return m_Current; } } #endregion #region ■ 获取设备下面绑定的设备_____________ /// /// 获取设备下面绑定的设备(错误时返回null),这个是给pir传感器用的 /// /// 设备对象 /// public List GetBindTargetDevice(CommonDevice mainDevice) { var result = this.GetDeviceBindAsync(mainDevice); if (result == null || result.getAllBindResponseData == null) { //获取设备的绑定目标失败 string msg = Language.StringByID(R.MyInternationalizationString.uGetDeviceBindTargetFail); //拼接上【网关回复超时】的Msg msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result); this.ShowErrorMsg(msg); return null; } var listDevice = new List(); foreach (var data in result.getAllBindResponseData.BindList) { CommonDevice deviceTemp = Common.LocalDevice.Current.GetDevice(data.BindMacAddr, data.BindEpoint); if (deviceTemp == null) { continue; } listDevice.Add(deviceTemp); } return listDevice; } /// ///获取所有绑定 /// public BindObj.GetDeviceBindResponseAllData GetDeviceBindAsync(CommonDevice device) { //如果当前住宅是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { var listBind = ModelData.DeviceModelDataLogic.Current.GetDeviceBindList(device, "Bind/GetDeviceBind"); return new BindObj.GetDeviceBindResponseAllData() { getAllBindResponseData = new BindObj.GetDeviceBindResponseData { Result = 0, BindList = listBind } }; } var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", device.DeviceEpoint }, { "Cluster_ID", 0 }, { "Command", 5007 } }; string sendData = jObject.ToString(); //发送 var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "Bind/GetDeviceBind", sendData, "Bind/GetDeviceBind_Respon", 6); if (result.ErrorMsg != null || result.ErrorMsgDiv == 0) { return null; } var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); return new BindObj.GetDeviceBindResponseAllData() { getAllBindResponseData = tempData }; } #endregion #region ■ 执行绑定设备目标___________________ /// /// 绑定设备的目标(返回成功设置的设备,错误时,返回null) /// /// 设备对象 /// 要绑定的目标设备 /// BindCluster /// public List BindDeviceTarget(CommonDevice mainDevice, List listDevice, int BindCluster = 6) { if (listDevice.Count == 0) { return new List(); } var dicDevice = new Dictionary(); //组装数据 var addData = new IASZone.AddBindData(); addData.DeviceAddr = mainDevice.DeviceAddr; addData.Epoint = mainDevice.DeviceEpoint; foreach (var device in listDevice) { var info = new IASZone.AddBindListObj(); info.BindCluster = BindCluster; info.BindMacAddr = device.DeviceAddr; info.BindEpoint = device.DeviceEpoint; info.BindType = 0; addData.BindList.Add(info); //返回成功设备的时候使用 string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(device); dicDevice[mainkeys] = device; } //执行绑定 var result = this.AddDeviceBindAsync(addData); if (result == null || result.addedDeviceBindResponseData == null) { //绑定目标设置失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetBindTargetsFail); //拼接上【网关回复超时】的Msg msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result); this.ShowErrorMsg(msg); return null; } var listSuccess = new List(); foreach (var data in result.addedDeviceBindResponseData.BindList) { string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(data.BindMacAddr, data.BindEpoint); if (dicDevice.ContainsKey(mainkeys) == true) { listSuccess.Add(dicDevice[mainkeys]); } } if (listSuccess.Count == 0) { //绑定目标设置失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetBindTargetsFail); this.ShowTipMsg(msg); } return listSuccess; } /// ///设备绑定 /// public BindObj.AddedDeviceBindResponseAllData AddDeviceBindAsync(BindObj.AddBindData addBindData) { //如果当前住宅是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { return ModelData.DeviceModelDataLogic.Current.AddDeviceBindList(addBindData, "Bind/GetDeviceBind"); } var device = Common.LocalDevice.Current.GetDevice(addBindData.DeviceAddr, addBindData.Epoint); //获取发送的命令字符 var sendData = this.GetAddDeviceListBindCommandText(addBindData); //发送 var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "Bind/SetBind", sendData, "Bind/SetBind_Respon", 20); if (result.ErrorMsg != null || result.ErrorMsgDiv == 0) { return null; } //修改缓存 ModelData.DeviceModelDataLogic.Current.AddDeviceBindList(addBindData, "Bind/GetDeviceBind"); var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); return new BindObj.AddedDeviceBindResponseAllData() { addedDeviceBindResponseData = tempData }; } /// /// 获取添加设备绑定的命令字符 /// /// /// public string GetAddDeviceListBindCommandText(BindObj.AddBindData addBindData) { var jObject = new JObject { { "DeviceAddr", addBindData.DeviceAddr }, { "Epoint", addBindData.Epoint }, { "Cluster_ID", 0 }, { "Command", 5001 } }; var bindList = new JArray { }; foreach (var bindInfo in addBindData.BindList) { if (bindInfo.BindType == 0) { var dInfo = new JObject{{ "BindMacAddr",bindInfo.BindMacAddr},{ "BindEpoint", bindInfo.BindEpoint} , { "BindCluster", bindInfo.BindCluster} ,{ "BindType",bindInfo.BindType}}; bindList.Add(dInfo); } else if (bindInfo.BindType == 1) { var dInfo = new JObject{{ "BindCluster", bindInfo.BindCluster} ,{ "BindType",bindInfo.BindType}, { "BindScenesId", bindInfo.BindScenesId}}; bindList.Add(dInfo); } } var data = new JObject { { "BindName", addBindData.BindName }, { "BindList", bindList } }; jObject.Add("Data", data); return jObject.ToString(); } #endregion #region ■ 删除设备绑定的目标_________________ /// /// 删除设备绑定的目标 /// /// 设备对象 /// 要删除的绑定目标设备 /// BindCluster /// public bool DeleteDeviceTarget(CommonDevice mainDevice, CommonDevice deleteDevice, int BindCluster = 6) { //组装数据 var deleteData = new IASZone.DelDeviceBindData(); deleteData.DeviceAddr = mainDevice.DeviceAddr; deleteData.Epoint = mainDevice.DeviceEpoint; var info = new IASZone.RemoveBindListObj(); info.BindCluster = BindCluster; info.BindMacAddr = deleteDevice.DeviceAddr; info.BindEpoint = deleteDevice.DeviceEpoint; info.BindType = 0; deleteData.RemoveBindList.Add(info); //执行删除 var result = this.DelDeviceBindAsync(deleteData); if (result == null || result.delDeviceBindResponseData == null) { //删除绑定目标失败 string msg = Language.StringByID(R.MyInternationalizationString.uDeleteBindTargetsFail); //拼接上【网关回复超时】的Msg msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result); this.ShowErrorMsg(msg); return false; } foreach (var data in result.delDeviceBindResponseData.RemoveBindList) { //0:成功 1:设备不在绑定列表中 ,也可以代表成功 if (data.Result == 0 || data.Result == 1 || data.Result == 5) { return true; } //3:失败,在等待节点设备确认是否解除绑定成功 else if (data.Result == 3) { //其他绑定目标正在删除中,请稍后再试 string msg = Language.StringByID(R.MyInternationalizationString.uOtherBindTargetsIsDelettingPleaseWait); this.ShowErrorMsg(msg); return false; } //2:未知,由节点设备反馈发送“Bind/BindResult”主题消息确定是否成功 else if (data.Result == 2) { if (result.removeBindResultResponseData == null) { //删除绑定目标失败 string msg = Language.StringByID(R.MyInternationalizationString.uDeleteBindTargetsFail); this.ShowErrorMsg(msg); return false; } else { //成功 if (result.removeBindResultResponseData.Result == 0) { return true; } //136:控制设备本地绑定列表中无此绑定 else if (result.removeBindResultResponseData.Result == 136) { //这个可以当做成功 return true; } else { //删除绑定目标失败 string msg = Language.StringByID(R.MyInternationalizationString.uDeleteBindTargetsFail); this.ShowErrorMsg(msg); return false; } } } } return false; } /// /// 删除设备绑定的目标 /// /// 设备对象 /// 要删除的绑定目标设备 /// BindCluster /// 返回的是成功删除的设备 public List DeleteDeviceTarget(CommonDevice mainDevice, List listDeleteDevice, int BindCluster = 6) { //组装数据 var deleteData = new IASZone.DelDeviceBindData(); deleteData.DeviceAddr = mainDevice.DeviceAddr; deleteData.Epoint = mainDevice.DeviceEpoint; var dicDevice = new Dictionary(); foreach (var device in listDeleteDevice) { var info = new IASZone.RemoveBindListObj(); info.BindCluster = BindCluster; info.BindMacAddr = device.DeviceAddr; info.BindEpoint = device.DeviceEpoint; info.BindType = 0; deleteData.RemoveBindList.Add(info); //返回成功设备的时候使用 string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(device); dicDevice[mainkeys] = device; } var listSuccess = new List(); var result = this.DelDeviceBindAsync(deleteData); if (result == null || result.delDeviceBindResponseData == null) { //删除绑定目标失败 string msg = Language.StringByID(R.MyInternationalizationString.uDeleteBindTargetsFail); //拼接上【网关回复超时】的Msg msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result); this.ShowErrorMsg(msg); return listSuccess; } foreach (var data in result.delDeviceBindResponseData.RemoveBindList) { string mainkeys = Common.LocalDevice.Current.GetDeviceMainKeys(data.BindMacAddr, data.BindEpoint); //0:成功 1:设备不在绑定列表中 ,也可以代表成功 if (data.Result == 0 || data.Result == 1) { listSuccess.Add(dicDevice[mainkeys]); } //3:失败,在等待节点设备确认是否解除绑定成功 else if (data.Result == 3) { //设备名称 其他绑定目标正在删除中,请稍后再试 string msg = Common.LocalDevice.Current.GetDeviceEpointName(dicDevice[mainkeys]) + "\r\n"; msg += Language.StringByID(R.MyInternationalizationString.uOtherBindTargetsIsDelettingPleaseWait); this.ShowErrorMsg(msg); } //2:未知,由节点设备反馈发送“Bind/BindResult”主题消息确定是否成功 else if (data.Result == 2) { if (result.removeBindResultResponseData == null) { //设备名称 删除绑定目标失败 string msg = Common.LocalDevice.Current.GetDeviceEpointName(dicDevice[mainkeys]) + "\r\n"; msg += Language.StringByID(R.MyInternationalizationString.uDeleteBindTargetsFail); this.ShowErrorMsg(msg); } else { //成功 if (result.removeBindResultResponseData.Result == 0) { listSuccess.Add(dicDevice[mainkeys]); } //136:控制设备本地绑定列表中无此绑定 else if (result.removeBindResultResponseData.Result == 136) { //这个可以当做成功 listSuccess.Add(dicDevice[mainkeys]); } else { //设备名称 删除绑定目标失败 string msg = Common.LocalDevice.Current.GetDeviceEpointName(dicDevice[mainkeys]) + "\r\n"; msg += Language.StringByID(R.MyInternationalizationString.uDeleteBindTargetsFail); this.ShowErrorMsg(msg); } } } } return listSuccess; } /// /// 删除设备的绑定目标 /// /// /// public BindObj.DelDeviceBindResponseAllData DelDeviceBindAsync(BindObj.DelDeviceBindData delDeviceBindData) { //如果当前住宅是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { return ModelData.DeviceModelDataLogic.Current.DeleteDeviceBindList(delDeviceBindData); } var device = Common.LocalDevice.Current.GetDevice(delDeviceBindData.DeviceAddr, delDeviceBindData.Epoint); //获取需要发送的数据 var sendData = this.GetDeleteDeviceBindCommandText(delDeviceBindData); //发送命令 var result = this.SendDeleteBindJobjectDataToGateway(device, " Bind/RemoveBind", sendData, new List() { "Bind/RemoveBind_Respon", "Bind/RemoveBindResult" }, 6); if (result.ErrorMsg != null || result.ErrorMsgDiv == 0) { return null; } var responseData = new BindObj.DelDeviceBindResponseAllData(); if (result.listReceiptData[0] != null) { var tempData1 = Newtonsoft.Json.JsonConvert.DeserializeObject(result.listReceiptData[0]); responseData.delDeviceBindResponseData = tempData1; } if (result.listReceiptData[1] != null) { var tempData2 = Newtonsoft.Json.JsonConvert.DeserializeObject(result.listReceiptData[1]); responseData.removeBindResultResponseData = tempData2; } //修改缓存 ModelData.DeviceModelDataLogic.Current.DeleteDeviceBindList(delDeviceBindData); return responseData; } /// ///删除一个控制设备所有绑定信息 /// public BindObj.ClearBindInfoResponseAllData ClearBindInfoAsync(CommonDevice device) { //如果当前住宅是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { return ModelData.DeviceModelDataLogic.Current.ClearDeviceAllBind(device); } var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", device.DeviceEpoint }, { "Cluster_ID", 0 }, { "Command", 5006 } }; var sendData = jObject.ToString(); var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "Bind/ClearBindInfo", sendData, "Bind/ClearBindInfo_Respon", 25); if (result.ErrorMsg != null || result.ErrorMsgDiv == 0) { return null; } //修改缓存 ModelData.DeviceModelDataLogic.Current.ClearDeviceAllBind(device); var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); return new BindObj.ClearBindInfoResponseAllData { clearBindInfoResponseData = tempData }; } /// /// 获取删除设备绑定列表的命令字符 /// /// /// public string GetDeleteDeviceBindCommandText(BindObj.DelDeviceBindData delDeviceBindData) { var jObject = new JObject { { "DeviceAddr", delDeviceBindData.DeviceAddr }, { "Epoint", delDeviceBindData.Epoint }, { "Cluster_ID", 0 }, { "Command", 5003 } }; var removeBindList = new JArray { }; foreach (var removeBindInfo in delDeviceBindData.RemoveBindList) { //删除设备 if (removeBindInfo.BindType == 0) { var dInfo = new JObject{{ "BindMacAddr",removeBindInfo.BindMacAddr},{ "BindEpoint", removeBindInfo.BindEpoint} , { "BindCluster", removeBindInfo.BindCluster} ,{ "BindType",removeBindInfo.BindType}}; removeBindList.Add(dInfo); } //删除场景 else if (removeBindInfo.BindType == 1) { var dInfo = new JObject{{ "BindCluster", removeBindInfo.BindCluster} ,{ "BindType",removeBindInfo.BindType}, { "BindScenesId", removeBindInfo.BindScenesId}}; removeBindList.Add(dInfo); } } var data = new JObject { { "RemoveBindList", removeBindList } }; jObject.Add("Data", data); return jObject.ToString(); } /// /// 发送删除绑定的数据到网关,并接受网关返回的数据,listReceiptData为返回值(删除绑定的接口很特殊,需要独立出来) /// /// 设备对象 /// 发送的主题 /// 需要发送的数据 JObject.ToString()的东西 /// 指定接收哪些主题 /// 超时时间(秒) /// 网关返回的数据 private ReceiptGatewayResult SendDeleteBindJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, List listReceiptTopic, int waitTime = 3) { var reResult = new ReceiptGatewayResult(); reResult.listReceiptData = new string[listReceiptTopic.Count]; var myGateway = device.Gateway; if (myGateway == null) { //获取网关对象失败 reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail); reResult.ErrorMsgDiv = -1; return reResult; } //网关ID string gatewayID = device.Gateway.GwId; //错误主题 string errorTopic = gatewayID + "/" + "Error_Respon"; //检测对象的主题 for (int i = 0; i < listReceiptTopic.Count; i++) { listReceiptTopic[i] = gatewayID + "/" + listReceiptTopic[i]; } bool canbreak = false; BindObj.DelDeviceBindResponseData delDeviceBindData = null; BindObj.RemoveBindResultResponseData removeBindResult = null; Action receiptAction = (topic, message) => { var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); //网关回复错误 if (topic == errorTopic) { var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error); } //如果是指定的主题 for (int i = 0; i < listReceiptTopic.Count; i++) { if (topic == listReceiptTopic[i]) { string deviceMac = jobject["DeviceAddr"].ToString(); int deviceEpoint = Convert.ToInt32(jobject["Epoint"].ToString()); if (device.DeviceAddr != deviceMac) { //不是同一个东西Mac return; } if (device.DeviceEpoint != deviceEpoint && deviceEpoint != 200) { //不是同一个东西,这里应该需要特殊处理200端点 return; } reResult.listReceiptData[i] = jobject["Data"].ToString(); if (i == 0) { //"Bind/RemoveBind_Respon"主题 delDeviceBindData = Newtonsoft.Json.JsonConvert.DeserializeObject(reResult.listReceiptData[i]); } else if (i == 1) { //"Bind/RemoveBindResult"主题 removeBindResult = Newtonsoft.Json.JsonConvert.DeserializeObject(reResult.listReceiptData[i]); } if (0 < delDeviceBindData.RemoveBindList.FindAll((obj) => obj.BindType == 0 && obj.Result == 1).Count) { canbreak = true; } else if (0 < delDeviceBindData.RemoveBindList.FindAll((obj) => obj.BindType == 0 && obj.Result == 3).Count) { if (removeBindResult != null) { canbreak = true; } } else if (0 < delDeviceBindData.RemoveBindList.FindAll((obj) => obj.BindType == 0 && obj.Result == 2).Count) { if (removeBindResult != null) { canbreak = true; } } else { canbreak = true; } } } }; myGateway.Actions += receiptAction; //发送数据 myGateway.Send(sendTopic, sendData); //超时时间 int TimeOut = 0; waitTime = 20 * waitTime; while (canbreak == false && TimeOut < waitTime) { //全部接收才退出 System.Threading.Thread.Sleep(50); TimeOut++; } myGateway.Actions -= receiptAction; receiptAction = null; if (canbreak == false) { //超时 reResult.ErrorMsgDiv = 0; } else { //正常接收到网关返回的数据 if (reResult.listReceiptData.Length == 1) { //如果只有一个主题,则替换变量 reResult.ReceiptData = reResult.listReceiptData[0]; reResult.listReceiptData = null; } } return reResult; } #endregion #region ■ 配置面板功能_______________________ /// ///配置面板功能 ///value:给面板配置的模式 /// public CommonDevice.SetWritableValueResponAllData ConfigureHdlKeyValueAsync(CommonDevice device, Panel.KeyMode value, int clusterID = 6) { //如果当前住宅是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { return ModelData.DeviceModelDataLogic.Current.ConfigurePanelKeyModel(device, value, clusterID, "SetWritableValue"); } //获取发送数据 var sendData = this.GetConfigureHdlKeyCommandText(device.DeviceAddr, device.DeviceEpoint, value, clusterID); var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "SetWritableValue", sendData, "SetWritableValue_Respon"); if (result.ErrorMsg != null || result.ErrorMsgDiv == 0) { return null; } //修改缓存 ModelData.DeviceModelDataLogic.Current.ConfigurePanelKeyModel(device, value, clusterID, "SetWritableValue"); var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); return new CommonDevice.SetWritableValueResponAllData { setWritableValueResponData = tempData }; } /// /// 读取面板的配置信息 /// public Panel.PanelConfigureInfoResponAllData ReadPanelConfigureInfoAsync(CommonDevice device) { //如果当前住宅是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { return ModelData.DeviceModelDataLogic.Current.ReadPanelConfigureKeyModel(device); } var JObject = new JObject {{ "DeviceAddr",device.DeviceAddr },{ "Epoint", device.DeviceEpoint }, { "Cluster_ID", (int)Cluster_ID.HdlKey },{ "Command", 108 }}; var attriBute = new JArray { new JObject { { "AttriButeId", (int)AttriButeId.HdlKey } } }; var data = new JObject { { "AttriBute", attriBute } }; JObject.Add("Data", data); //发送数据 var sendData = JObject.ToString(); string receiptTopic = "DeviceStatusReport/" + device.DeviceAddr + "/" + device.DeviceEpoint + "/" + (int)Cluster_ID.HdlKey + "/" + (int)AttriButeId.HdlKey; var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "GetDeviceStatus", sendData, receiptTopic); if (result.ErrorMsg != null || result.ErrorMsgDiv == 0) { return null; } var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); return new Panel.PanelConfigureInfoResponAllData { deviceStatusReportData = tempData }; } /// /// 获取配置面板功能的命令字符 /// /// 设备对象 /// 键值 /// 镞ID /// public string GetConfigureHdlKeyCommandText(string DeviceAddr, int DeviceEpoint, Panel.KeyMode value, int clusterID = 6) { var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", clusterID }, { "Command", 120 } }; var data = new JObject { { "Undivided", 0 }, { "AttributeId", 6533 }, { "AttributeDataType", 33 }, { "AttributeData", (int)value } }; jObject.Add("Data", data); return jObject.ToString(); } #endregion #region ■ 一般方法___________________________ /// /// 显示错误信息窗口 /// /// private void ShowErrorMsg(string msg) { Application.RunOnMainThread(() => { var contr = new ShowMsgControl(ShowMsgType.Error, msg); contr.Show(); }); } /// /// 显示Tip信息窗口 /// /// private void ShowTipMsg(string msg) { Application.RunOnMainThread(() => { var contr = new UserCenter.ShowMsgControl(ShowMsgType.Tip, msg); contr.Show(); }); } #endregion } }