using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using ZigBee.Device; namespace Shared.Phone { /// /// 空调的逻辑 /// public class HdlDeviceAirConditionerLogic { #region ■ 变量声明___________________________ /// /// 空调的逻辑 /// private static HdlDeviceAirConditionerLogic m_Current = null; /// /// 空调的逻辑 /// public static HdlDeviceAirConditionerLogic Current { get { if (m_Current == null) { m_Current = new HdlDeviceAirConditionerLogic(); } return m_Current; } } #endregion #region ■ 打开空调___________________________ /// /// 打开空调 /// /// 空调对象 /// public async Task OpenAirConditioner(AC device) { var result = await device.Open(); //检测网关返回的共通错误状态码 string error = HdlCheckLogic.Current.CheckGatewayErrorCode(result); if (error != null) { this.ShowTipMsg(error); return false; } if (result == null || result.setWritableValueResponData == null || result.setWritableValueResponData.Status != 0) { //打开空调失败 string msg = Language.StringByID(R.MyInternationalizationString.uOpenAirConditionerFail); //拼接上【网关回复超时】的Msg msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result); this.ShowTipMsg(msg); return false; } if (result.setWritableValueResponData.Status != 0) { //打开空调失败 string msg = Language.StringByID(R.MyInternationalizationString.uOpenAirConditionerFail); this.ShowTipMsg(msg); return false; } return true; } #endregion #region ■ 关闭空调___________________________ /// /// 关闭空调 /// /// 空调对象 /// public async Task CloseAirConditioner(AC device) { var result = await device.Close(); //检测网关返回的共通错误状态码 string error = HdlCheckLogic.Current.CheckGatewayErrorCode(result); if (error != null) { this.ShowTipMsg(error); return false; } if (result == null || result.setWritableValueResponData == null || result.setWritableValueResponData.Status != 0) { //关闭空调失败 string msg = Language.StringByID(R.MyInternationalizationString.uCloseAirConditionerFail); //拼接上【网关回复超时】的Msg msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result); this.ShowTipMsg(msg); return false; } if (result.setWritableValueResponData.Status != 0) { //关闭空调失败 string msg = Language.StringByID(R.MyInternationalizationString.uCloseAirConditionerFail); this.ShowTipMsg(msg); return false; } return true; } #endregion #region ■ 设置空调的自定义模式_______________ /// /// 设置空调的自定义模式 ☆☆☆☆☆ /// /// 空调对象 /// 从二进制转换的十进制值 /// public bool SetAcModeSupport(AC device, int data) { //如果是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { //直接添加缓存 HdlTemplateDeviceDataLogic.Current.SetAcModeSupport(device, data, null); return true; } //发送数据 string sendData = HdlDeviceAttributeLogic.Current.GetWriteDeviceAttributeText(device.DeviceAddr, device.DeviceEpoint, 513, 4099, 25, data); var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "SetWritableValue", sendData, "SetWritableValue_Respon"); if (result.ErrorMsg != null) { this.ShowTipMsg(result.ErrorMsg); return false; } if (result.ErrorMsgDiv == 0) { //设置空调模式失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetAcModeFail); //拼接上【网关回复超时】的Msg msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result); this.ShowTipMsg(msg); ; return false; } var responeData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); if (responeData.Status != 0) { //设置空调模式失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetAcModeFail); this.ShowTipMsg(msg); return false; } //添加缓存 HdlTemplateDeviceDataLogic.Current.SetAcModeSupport(device, data, result.JsonData[0]); return true; } #endregion #region ■ 设置启用空调的摆风功能_____________ /// /// 设置启用空调的摆风功能 ☆☆☆☆☆ /// /// 空调对象 /// 从二进制转换的十进制值 /// public bool SetUseAcSwingFunctionStatu(AC device, int data) { //如果是虚拟住宅 if (Common.Config.Instance.Home.IsVirtually == true) { //直接添加缓存 HdlTemplateDeviceDataLogic.Current.SetAcSwingModeSupport(device, data, null); return true; } //发送数据 string sendData = HdlDeviceAttributeLogic.Current.GetWriteDeviceAttributeText(device.DeviceAddr, device.DeviceEpoint, 514, 4097, 25, data); var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "SetWritableValue", sendData, "SetWritableValue_Respon"); if (result.ErrorMsg != null) { this.ShowTipMsg(result.ErrorMsg); return false; } if (result.ErrorMsgDiv == 0) { //设置空调摆风失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetAirConditionerSwingFunctionFail); //拼接上【网关回复超时】的Msg msg = HdlCommonLogic.Current.CombineGatewayTimeOutMsg(msg, result); this.ShowTipMsg(msg); return false; } var responeData = Newtonsoft.Json.JsonConvert.DeserializeObject(result.ReceiptData); if (responeData.Status != 0) { //设置空调摆风失败 string msg = Language.StringByID(R.MyInternationalizationString.uSetAirConditionerSwingFunctionFail); this.ShowTipMsg(msg); return false; } //添加缓存 HdlTemplateDeviceDataLogic.Current.SetAcSwingModeSupport(device, data, result.JsonData[0]); return true; } #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 ShowMsgControl(ShowMsgType.Tip, msg); contr.Show(); }); } #endregion #region ■ 升级空调第三方模块的接口___________ #region 读取IRACC模块固件版本(APP -> Zigbee MCU) /// ///读取IRACC模块固件版本 /// public async System.Threading.Tasks.Task ReadACFirewareVersionAsync(CommonDevice device) { ReadACFirewareVersionResponAllData result = null; var Gateway = device.Gateway; if (Gateway == null) { result = new ReadACFirewareVersionResponAllData { errorMessageBase = "当前没有网关" }; return result; } return await System.Threading.Tasks.Task.Run(async () => { Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); if (topic == gatewayID + "/" + "ZbDataPassthrough") { var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (clientDataPassthroughResponseData == null) { result = new ReadACFirewareVersionResponAllData { errorMessageBase = "网关返回的数据为空" }; } else { if (clientDataPassthroughResponseData?.PassData != null) { var data = clientDataPassthroughResponseData.PassData; var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString(); if (command == "0259") { var tempD = new ReadACFirewareVersionResponData(); tempD.Status = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16); if (data.Length == 82) { var firewareString = data.Substring(12); var aa = firewareString.Length; firewareVersion = firewareString; var bytes = new byte[firewareString.Length / 2]; for (int i = 0; i < bytes.Length; i++) { bytes[i] = Convert.ToByte(firewareString.Substring(i * 2, 2), 16); } var firewareVersionTemp = System.Text.Encoding.ASCII.GetString(bytes); tempD.FirewareVersion = firewareVersionTemp.Replace('\0', ' ').Trim(); } result = new ReadACFirewareVersionResponAllData { readACFirewareVersionResponData = tempD }; System.Console.WriteLine($"UI收到通知后的主题_command:0258_{topic}"); } } } } }; Gateway.Actions += action; System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString()); try { var passData = ReadACFirewareVersionData("01"); var jObject = new JObject { { "DeviceAddr", device.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 < 3000) { await System.Threading.Tasks.Task.Delay(10); if (result != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 3000) { result = new ReadACFirewareVersionResponAllData { errorMessageBase = " 回复超时,请重新操作" }; } Gateway.Actions -= action; System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } /// /// 读取IRACC模块固件版本 /// string ReadACFirewareVersionData(string reserve) { string data = ""; string dataLength = "05"; string dataComand1 = "58"; string dataComand2 = "02"; string dataSerialNum = "01"; string addDataLength = "01"; string reserveData = reserve; try { data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength + reserveData; } catch { }; return data; } /// /// IRACC模块固件版本,网关反馈信息 /// public ReadACFirewareVersionResponAllData readACFirewareVersionResponAllData; /// /// IRACC模块固件版本,网关反馈信息 /// [System.Serializable] public class ReadACFirewareVersionResponAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public CommonDevice.ErrorResponData errorResponData; /// /// IRACC模块固件版本信息 /// public ReadACFirewareVersionResponData readACFirewareVersionResponData; } /// /// IRACC模块固件版本的数据 /// [System.Serializable] public class ReadACFirewareVersionResponData { /// /// 状态 ///0--成功 ///1--失败 ///ff--无效 /// public int Status; /// /// 固件版本 /// public string FirewareVersion; } #endregion #region 升级IRACC模块通知(APP -> Zigbee MCU) /// ///升级IRACC模块通知 /// firewareVer:固件版本 /// firewareSize:固件大小 /// public async System.Threading.Tasks.Task UpggradeACNotificationAsync(CommonDevice device, string firewareVer, long firewareSize) { ResponseAllData result = null; var Gateway = device.Gateway; if (Gateway == null) { result = new ResponseAllData { errorMessageBase = "当前没有网关" }; return result; } return await System.Threading.Tasks.Task.Run(async () => { Action action = (topic, message) => { var gatewayID = topic.Split('/')[0]; var jobject = Newtonsoft.Json.Linq.JObject.Parse(message); if (topic == gatewayID + "/" + "ZbDataPassthrough") { var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (clientDataPassthroughResponseData == null) { result = new ResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { if (clientDataPassthroughResponseData?.PassData != null) { var data = clientDataPassthroughResponseData.PassData; var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString(); if (command == "025b") { var tempD = new ResponseData(); if (data.Length == 12) { tempD.status = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16); } result = new ResponseAllData { responseData = tempD }; System.Console.WriteLine($"UI收到通知后的主题_{ topic}"); } } } } }; Gateway.Actions += action; System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString()); try { var passData = UpggradeACNotificationData(firewareVer, firewareSize); var jObject = new JObject { { "DeviceAddr", device.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 < 3000) { await System.Threading.Tasks.Task.Delay(10); if (result != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 3000) { result = new ResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } Gateway.Actions -= action; System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); return result; }); } private string firewareVersion = string.Empty; /// /// 升级IRACC模块通知返回 /// string UpggradeACNotificationData(string firewareVer, long firewareSize) { string data = ""; string dataLength = "2C"; string dataComand1 = "5A"; string dataComand2 = "02"; string dataSerialNum = "01"; string addDataLength = "28"; string deviceUpgradeMethod = "01"; string firewareVersionData = ""; string firewareSizeData = ""; try { //固件版本 var firewareVerBytes = System.Text.Encoding.ASCII.GetBytes(firewareVer); for (int i = 0; i < firewareVerBytes.Length; i++) { var fw = Convert.ToString(firewareVerBytes[i], 16); if (fw.Length == 1) { fw = "0" + fw; } firewareVersionData += fw; } var aa = firewareVersionData.Length; firewareVersionData = firewareVersionData.PadRight(70, '0'); //固件尺寸 var tempFwSize = Convert.ToString(firewareSize, 16); tempFwSize = tempFwSize.PadLeft(8, '0'); for (int i = 6; i >= 0; i = i - 2) { firewareSizeData += tempFwSize.Substring(i, 2); } data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength + deviceUpgradeMethod + firewareVersionData + firewareSizeData; } catch { }; return data; } /// ///升级IRACC模块通知回复 /// public ResponseAllData keyColorDataResponseAllData; [System.Serializable] public class ResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public CommonDevice.ErrorResponData errorResponData; /// /// 升级IRACC模块通知信息 /// public ResponseData responseData; } /// /// 升级IRACC模块通知回复(Zigbee MCU -> APP) /// [System.Serializable] public class ResponseData { /// /// 状态值 /// 0--版本号不一致(可以升级 /// 1--版本号一致(不用升级 /// 2--预留(暂时不用到 /// ff--无效(暂时不用到) /// public int status = -1; } #endregion #region 设备请求APP获取升级数据 (Zigbee MCU -> APP,主动上报) /// ///设备请求APP获取升级数据(Zigbee MCU -> APP,主动上报) /// [System.Serializable] public class DeviceRequestUpgradeResponseData { /// /// 数据偏移量,每个分包偏移量+(1-43) /// public string offset = string.Empty; /// /// 数据长度len /// public int dataLength = -1; } #endregion #region 发升级数据到设备(APP -> Zigbee MCU) /// ///读取IRACC模块固件版本 /// reserve:0-ff /// public void UpgradeAsync(CommonDevice device, SendUpgradeData upgradeData) { var Gateway = device.Gateway; if (Gateway == null) { return; } Action action = (topic, message) => { }; Gateway.Actions += action; System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString()); try { string passData = ""; if (upgradeData != null) { passData = SendUpgrade(upgradeData); } var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } }; var data = new JObject { { "PassData", passData } }; jObject.Add("Data", data); Gateway.Send(("ClientDataPassthrough"), jObject.ToString()); } catch { } Gateway.Actions -= action; System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); } /// /// 发升级数据到设备 /// string SendUpgrade(SendUpgradeData upgradeData) { string data = ""; string dataLength = ""; string dataComand1 = "5D"; string dataComand2 = "02"; string dataSerialNum = "01"; string addDataLength = ""; string status = ""; string offset = ""; string upgradeDataLength = ""; string dataString = ""; try { var len = 4 + 1 + 4 + 1 + upgradeData.dataLength; dataLength = Convert.ToString(len, 16); if (dataLength.Length == 1) { dataLength = "0" + dataLength; } addDataLength = Convert.ToString(6 + upgradeData.dataLength, 16); if (addDataLength.Length == 1) { addDataLength = "0" + addDataLength; } if (upgradeData.status == 0) { status = "00"; } else if (upgradeData.status == 1) { status = "01"; } else { status = "ff"; } offset = upgradeData.offset; var dl = Convert.ToString(upgradeData.dataLength, 16); if (dl.Length == 1) { upgradeDataLength = "0" + dl; } else { upgradeDataLength = dl; } for (int i = 0; i < upgradeData.databytes.Length; i++) { var dataB = Convert.ToString(upgradeData.databytes[i], 16); if (dataB.Length == 1) { dataB = "0" + dataB; } dataString += dataB; } data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength + status + offset + upgradeDataLength + dataString; } catch { }; return data; } /// /// 发送升级数据到设备(APP -> Zigbee MCU) /// [System.Serializable] public class SendUpgradeData { /// /// 0--成功 ///1--失败 ///ff--无效 /// public int status = 0; /// /// 数据偏移量,每个分包偏移量+(1-43) /// public string offset; /// /// 数据长度len /// public int dataLength = -1; /// /// 分包数据 /// public byte[] databytes; } #endregion #region 分包结束(Zigbee MCU -> APP,主动上报) /// /// 设备请求APP获取分包结束命令(Zigbee MCU -> APP) /// [System.Serializable] public class DeviceRequestFinishResponseData { /// /// 0-ff /// public int reserve = -1; } #endregion #region 分包结束(APP -> Zigbee MCU) /// ///读取IRACC模块固件版本 /// status:0--成功;1--失败;ff--无效 . /// public void SendFinishAsync(CommonDevice device, int status) { var Gateway = device.Gateway; if (Gateway == null) { return; } Action action = (topic, message) => { }; Gateway.Actions += action; System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString()); try { var passData = SendFinishDataString(status); var jObject = new JObject { { "DeviceAddr", device.DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } }; var data = new JObject { { "PassData", passData } }; jObject.Add("Data", data); Gateway.Send(("ClientDataPassthrough"), jObject.ToString()); } catch { } Gateway.Actions -= action; System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString()); } /// /// 发升级数据到设备 /// string SendFinishDataString(int status) { string data = ""; string dataLength = "05"; string dataComand1 = "5F"; string dataComand2 = "02"; string dataSerialNum = "01"; string addDataLength = "01"; string statusString = ""; try { if (status == 0) { statusString = "00"; } else if (status == 1) { statusString = "01"; } else { statusString = "ff"; } data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength + statusString; } catch { }; return data; } /// /// 分包结束返回(APP -> Zigbee MCU /// //[System.Serializable] public class SendFinishData { /// /// 状态:成功/失败 ///0--成功< ///1--失败< ///ff--无效< /// public int status = -1; } #endregion #endregion } }