HDL Home App 第二版本 旧平台金堂用 正在使用
黄学彪
2020-01-09 fa6bcb2e9907772480f99205f36ec2a1ce735a22
ZigbeeApp/Shared/Phone/ZigBee/Device/AC.cs
@@ -91,11 +91,15 @@
        /// </summary>
        public List<FanMode> fanModes = new List<FanMode> { };
        /// <summary>
        /// <para>自定义空调支持的模式(默认全关)</para>
        /// <para>自定义空调支持的模式(默认全开)</para>
        /// <para>数组索引 -> 0:制冷 1:制热 2:送风 3:除湿 4:自动</para>
        /// <para>值 -> 1:代表使用  0:代表不使用</para>
        /// </summary>
        public int[] listSupportMode = new int[5] { 0, 0, 0, 0, 0 };
        public int[] listSupportMode = new int[5] { 1, 1, 1, 1, 1 };
        /// <summary>
        /// 是否启用摆风功能 false:不使用摆风功能 true:使用摆风功能
        /// </summary>
        public bool UseSwingFunction = true;
        /// <summary>
        /// 过滤网清洗状态
@@ -189,6 +193,14 @@
        public void ReadCleanStatu()
        {
            ReadAttri(Device.Cluster_ID.Thermostat, AttriButeId.CleanStatu);
        }
        /// <summary>
        /// 获取是否启用空调摆风模式的状态(打开 或者 关闭)
        /// </summary>
        public void ReadUseSwingFunctionStatu()
        {
            ReadAttri(Device.Cluster_ID.FanControl, AttriButeId.UseAcSwingFunctionStatu);
        }
        /// <summary>
@@ -811,618 +823,5 @@
        {
            return await SetSystemModeAsync(acMode);
        }
        #region 升级空调第三方模块的接口
        #region 读取IRACC模块固件版本(APP -> Zigbee MCU)
        ///<summary >
        ///读取IRACC模块固件版本
        /// <para>reserve:0-ff</para>
        /// </summary>
        public async System.Threading.Tasks.Task<ReadACFirewareVersionResponAllData> ReadACFirewareVersionAsync(string reserve = "01")
        {
            ReadACFirewareVersionResponAllData result = null;
            if (Gateway == null)
            {
                result = new ReadACFirewareVersionResponAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                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 gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new ReadACFirewareVersionResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new ReadACFirewareVersionResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new ReadACFirewareVersionResponAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.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(reserve);
                    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 (result != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
                {
                    result = new ReadACFirewareVersionResponAllData { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        /// <summary>
        /// 读取IRACC模块固件版本
        /// </summary>
        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;
        }
        /// <summary>
        /// IRACC模块固件版本,网关反馈信息
        /// </summary>
        public ReadACFirewareVersionResponAllData readACFirewareVersionResponAllData;
        /// <summary>
        /// IRACC模块固件版本,网关反馈信息
        /// </summary>
        [System.Serializable]
        public class ReadACFirewareVersionResponAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// IRACC模块固件版本信息
            /// </summary>
            public ReadACFirewareVersionResponData readACFirewareVersionResponData;
        }
        /// <summary>
        /// IRACC模块固件版本的数据
        /// </summary>
        [System.Serializable]
        public class ReadACFirewareVersionResponData
        {
            /// <summary>
            /// 状态
            ///<para>0--成功</para>
            ///<para>1--失败</para>
            ///<para>ff--无效</para>
            /// </summary>
            public int Status;
            /// <summary>
            /// 固件版本
            /// </summary>
            public string FirewareVersion;
        }
        #endregion
        #region 升级IRACC模块通知(APP -> Zigbee MCU)
        ///<summary >
        ///升级IRACC模块通知
        /// <para>firewareVer:固件版本</para>
        /// <para>firewareSize:固件大小</para>
        /// </summary>
        public async System.Threading.Tasks.Task<ResponseAllData> UpggradeACNotificationAsync(string firewareVer, long firewareSize)
        {
            ResponseAllData result = null;
            if (Gateway == null)
            {
                result = new ResponseAllData { errorMessageBase = "当前没有网关" };
                return result;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                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 gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            result = new ResponseAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            result = new ResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "ZbDataPassthrough")
                    {
                        var gatewayTemp = new ZbGateway() { DataID = jobject.Value<int>("Data_ID") };
                        gatewayTemp.clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                        if (gatewayTemp.clientDataPassthroughResponseData == null)
                        {
                            result = new ResponseAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            if (gatewayTemp.clientDataPassthroughResponseData?.PassData != null)
                            {
                                var data = gatewayTemp.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", 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 (result != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
                {
                    result = new ResponseAllData { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
                return result;
            });
        }
        private string firewareVersion = string.Empty;
        /// <summary>
        /// 升级IRACC模块通知返回
        /// </summary>
        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;
        }
        /// <summary>
        ///升级IRACC模块通知回复
        /// </summary>
        public ResponseAllData keyColorDataResponseAllData;
        [System.Serializable]
        public class ResponseAllData
        {
            /// <summary>
            /// 错误信息
            /// </summary>
            public string errorMessageBase;
            /// <summary>
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public ErrorResponData errorResponData;
            /// <summary>
            /// 升级IRACC模块通知信息
            /// </summary>
            public ResponseData responseData;
        }
        /// <summary>
        /// 升级IRACC模块通知回复(Zigbee MCU -> APP)
        /// </summary>
        [System.Serializable]
        public class ResponseData
        {
            /// <summary>
            /// 状态值
            /// <para>0--版本号不一致(可以升级</para>
            /// <para>1--版本号一致(不用升级</para>
            /// <para>2--预留(暂时不用到</para>
            /// <para>ff--无效(暂时不用到)</para>
            /// </summary>
            public int status = -1;
        }
        #endregion
        #region 设备请求APP获取升级数据 (Zigbee MCU -> APP,主动上报)
        /// <summary>
        ///设备请求APP获取升级数据(Zigbee MCU -> APP,主动上报)
        /// </summary>
        [System.Serializable]
        public class DeviceRequestUpgradeResponseData
        {
            /// <summary>
            /// 数据偏移量,每个分包偏移量+(1-43)
            /// </summary>
            public string offset = string.Empty;
            /// <summary>
            /// 数据长度len
            /// </summary>
            public int dataLength = -1;
        }
        #endregion
        #region 发升级数据到设备(APP -> Zigbee MCU)
        ///<summary >
        ///读取IRACC模块固件版本
        /// <para>reserve:0-ff</para>
        /// </summary>
        public async void UpgradeAsync(SendUpgradeData upgradeData)
        {
            if (Gateway == null)
            {
                return;
            }
            Action<string, string> 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", 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());
        }
        /// <summary>
        /// 发升级数据到设备
        /// </summary>
        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;
        }
        /// <summary>
        /// 发送升级数据到设备(APP -> Zigbee MCU)
        /// </summary>
        [System.Serializable]
        public class SendUpgradeData
        {
            /// <summary>
            /// 0--成功
            ///<para>1--失败</para>
            ///<para>ff--无效</para>
            /// </summary>
            public int status = 0;
            /// <summary>
            /// 数据偏移量,每个分包偏移量+(1-43)
            /// </summary>
            public string offset;
            /// <summary>
            /// 数据长度len
            /// </summary>
            public int dataLength = -1;
            /// <summary>
            /// 分包数据
            /// </summary>
            public byte[] databytes;
        }
        #endregion
        #region 分包结束(Zigbee MCU -> APP,主动上报)
        /// <summary>
        /// 设备请求APP获取分包结束命令(Zigbee MCU -> APP)
        /// </summary>
        [System.Serializable]
        public class DeviceRequestFinishResponseData
        {
            /// <summary>
            /// 0-ff
            /// </summary>
            public int reserve = -1;
        }
        #endregion
        #region 分包结束(APP -> Zigbee MCU)
        ///<summary >
        ///读取IRACC模块固件版本
        /// <para>status:0--成功;1--失败;ff--无效 .</para>
        /// </summary>
        public async void SendFinishAsync(int status)
        {
            if (Gateway == null)
            {
                return;
            }
            Action<string, string> 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", 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());
        }
        /// <summary>
        /// 发升级数据到设备
        /// </summary>
        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;
        }
        /// <summary>
        /// 分包结束返回(APP -> Zigbee MCU
        /// </summary>
        //[System.Serializable]
        public class SendFinishData
        {
            /// <summary>
            /// 状态:成功/失败
            ///<para>0--成功<<para>
            ///<para>1--失败<<para>
            ///<para>ff--无效<<para>
            /// </summary>
            public int status = -1;
        }
        #endregion
        #endregion
    }
}