HDL Home App 第二版本 旧平台金堂用 正在使用
chenqiyang
2022-06-22 dc0309e64f02227d8e1468b7326c07955f804612
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlDeviceCommonLogic.cs
old mode 100755 new mode 100644
@@ -1,272 +1,336 @@
using System;
using System.Collections.Generic;
using System.Text;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
    /// <summary>
    /// 设备的共通逻辑
    /// </summary>
    public class HdlDeviceCommonLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 设备的共通逻辑
using System;
using System.Collections.Generic;
using System.Text;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
    /// <summary>
    /// 设备的共通逻辑
    /// </summary>
    public class HdlDeviceCommonLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 设备的共通逻辑
        /// </summary>
        private static HdlDeviceCommonLogic m_Current = null;
        /// <summary>
        /// 设备的共通逻辑
        private static HdlDeviceCommonLogic m_Current = null;
        /// <summary>
        /// 设备的共通逻辑
        /// </summary>
        public static HdlDeviceCommonLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlDeviceCommonLogic();
                }
                return m_Current;
            }
            set
            {
                m_Current = value;
            }
        }
        #endregion
        #region ■ 发送数据___________________________
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(非透传,ReceiptData为返回值)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendTopic">发送的主题</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="receiptTopic">指定接收哪个主题</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, string receiptTopic, int waitTime = 5)
        {
            //发送数据到网关,并接受网关返回的数据
            return this.SendJobjectDataToGateway(device, sendTopic, sendData, new List<string>() { receiptTopic }, waitTime);
        }
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(非透传),listReceiptData为返回值(全部主题全部接收得到,才会返回,不然会返回超时)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendTopic">发送的主题</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="listReceiptTopic">指定接收哪些主题</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, List<string> listReceiptTopic, int waitTime = 5)
        {
            var reResult = new ReceiptGatewayResult();
            reResult.listReceiptData = new string[listReceiptTopic.Count];
            var myGateway = device.Gateway;
        public static HdlDeviceCommonLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlDeviceCommonLogic();
                }
                return m_Current;
            }
            set
            {
                m_Current = value;
            }
        }
        #endregion
        #region ■ 发送数据___________________________
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(非透传,ReceiptData为返回值)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendTopic">发送的主题</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="receiptTopic">指定接收哪个主题</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, string receiptTopic, int waitTime = 5)
        {
            //发送数据到网关,并接受网关返回的数据
            return this.SendJobjectDataToGateway(device, sendTopic, sendData, new List<string>() { receiptTopic }, waitTime);
        }
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(非透传),listReceiptData为返回值(全部主题全部接收得到,才会返回,不然会返回超时)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendTopic">发送的主题</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="listReceiptTopic">指定接收哪些主题</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, List<string> listReceiptTopic, int waitTime = 5)
        {
            var reResult = new ReceiptGatewayResult();
            reResult.listReceiptData = new string[listReceiptTopic.Count];
            reResult.JsonData = new string[listReceiptTopic.Count];
            var myGateway = device.Gateway;
            if (myGateway == null)
            {
                //获取网关对象失败
                reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
                reResult.ErrorMsgDiv = -1;
                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];
            }
            //接收数
            int receiptCount = 0;
            Action<string, string> receiptAction = (topic, message) =>
            {
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                //网关回复错误
                if (topic == errorTopic)
                {
                    var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(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 = 200;
                        if (jobject.Property("Epoint") != null)
                        {
                            //拥有此键值
                            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();
                        receiptCount++;
                    }
                }
            };
            myGateway.Actions += receiptAction;
            //发送数据
            myGateway.Send(sendTopic, sendData);
            //超时时间
            int TimeOut = 0;
            waitTime = 20 * waitTime;
            while (receiptCount != listReceiptTopic.Count && TimeOut < waitTime)
            {
                //全部接收才退出
                System.Threading.Thread.Sleep(50);
                TimeOut++;
            }
            myGateway.Actions -= receiptAction;
            receiptAction = null;
            if (receiptCount != listReceiptTopic.Count)
            {
                reResult.ErrorMsgDiv = 0;
            }
            else
            {
                //正常接收到网关返回的数据
                if (reResult.listReceiptData.Length == 1)
                {
                    //如果只有一个主题,则替换变量
                    reResult.ReceiptData = reResult.listReceiptData[0];
                    reResult.listReceiptData = null;
                }
            }
            return reResult;
        }
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(透传专用)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="receiptCommand">指定接收命令符</param>
        /// <param name="receiptDataLength">指定接收数据的长度</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <param name="listReceiptLength">附加检测数据接收长度,当接收的长度在这列表里面时,代表接收成功(旨在对应新旧设备,透传回复的长度可能不同)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway2(CommonDevice device, string sendData, string receiptCommand, int receiptDataLength,
            int waitTime = 5, List<int> listReceiptLength = null)
        {
            var reResult = new ReceiptGatewayResult();
            var myGateway = device.Gateway;
            }
            //网关ID
            string gatewayID = device.Gateway.GwId;
            //错误主题
            string errorTopic = gatewayID + "/" + "Error_Respon";
            //检测对象的主题
            for (int i = 0; i < listReceiptTopic.Count; i++)
            {
                listReceiptTopic[i] = gatewayID + "/" + listReceiptTopic[i];
            }
            //蓝才刚整了个同一个主题可能会推送多个过来的机能
            var listCheckTopic = new HashSet<string>();
            Action<string, string> receiptAction = (topic, message) =>
            {
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                //网关回复错误
                if (topic == errorTopic)
                {
                    var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                    reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error);
                }
                //如果是指定的主题
                for (int i = 0; i < listReceiptTopic.Count; i++)
                {
                    if (topic == listReceiptTopic[i])
                    {
                        if (listCheckTopic.Contains(topic) == true)
                        {
                            //这里写这个东西是有点用处的
                            continue;
                        }
                        string deviceMac = jobject["DeviceAddr"].ToString();
                        int deviceEpoint = 200;
                        if (jobject.Property("Epoint") != null)
                        {
                            //拥有此键值
                            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 (jobject.Property("Time") != null)
                        {
                            //需要移除time这个字段
                            jobject.Remove("Time");
                        }
                        reResult.JsonData[i] = jobject.ToString();
                        if (listCheckTopic.Contains(topic) == false)
                        {
                            //加到检测主题对象中
                            listCheckTopic.Add(topic);
                        }
                    }
                }
            };
            myGateway.Actions += receiptAction;
            //发送数据
            myGateway.Send(sendTopic, sendData);
            //超时时间
            int TimeOut = 0;
            waitTime = 20 * waitTime;
            while (listCheckTopic.Count != listReceiptTopic.Count && TimeOut < waitTime)
            {
                //全部接收才退出
                System.Threading.Thread.Sleep(50);
                TimeOut++;
            }
            myGateway.Actions -= receiptAction;
            receiptAction = null;
            int receveCount = listCheckTopic.Count;
            if (receveCount > 1)
            {
                //看看里面有没有重复的
                var listTemp = new HashSet<string>();
                foreach (var value in listCheckTopic)
                {
                    if (listTemp.Contains(value) == false)
                    {
                        listTemp.Add(value);
                    }
                }
                receveCount = listTemp.Count;
            }
            if (receveCount != listReceiptTopic.Count)
            {
                reResult.ErrorMsgDiv = 0;
            }
            else
            {
                //正常接收到网关返回的数据
                if (reResult.listReceiptData.Length == 1)
                {
                    //如果只有一个主题,则替换变量
                    reResult.ReceiptData = reResult.listReceiptData[0];
                }
            }
            return reResult;
        }
        /// <summary>
        /// 发送数据到网关,并接受网关返回的数据(透传专用)
        /// </summary>
        /// <param name="device">设备对象</param>
        /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
        /// <param name="receiptCommand">指定接收命令符</param>
        /// <param name="receiptDataLength">指定接收数据的长度</param>
        /// <param name="waitTime">超时时间(秒)</param>
        /// <param name="listReceiptLength">附加检测数据接收长度,当接收的长度在这列表里面时,代表接收成功(旨在对应新旧设备,透传回复的长度可能不同)</param>
        /// <returns>网关返回的数据</returns>
        public ReceiptGatewayResult SendJobjectDataToGateway2(CommonDevice device, string sendData, string receiptCommand, int receiptDataLength,
            int waitTime = 5, List<int> listReceiptLength = null)
        {
            var reResult = new ReceiptGatewayResult();
            var myGateway = device.Gateway;
            if (myGateway == null)
            {
                //获取网关对象失败
                reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
                reResult.ErrorMsgDiv = -1;
                reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
                reResult.ErrorMsgDiv = -1;
                return reResult;
            }
            //网关ID
            string gatewayID = device.Gateway.GwId;
            //错误主题
            string errorTopic = gatewayID + "/" + "Error_Respon";
            //检测对象的主题
            string checkTopic = gatewayID + "/ZbDataPassthrough";
            Action<string, string> receiptAction = (topic, message) =>
            {
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                //网关回复错误
                if (topic == errorTopic)
                {
                    var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                    reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error);
                }
                //如果是指定的主题
                if (topic == checkTopic)
                {
                    string deviceMac = jobject["DeviceAddr"].ToString();
                    int deviceEpoint = 200;
                    if (jobject.Property("Epoint") != null)
                    {
                        //拥有此键值
                        deviceEpoint = Convert.ToInt32(jobject["Epoint"].ToString());
                    }
                    if (device.DeviceAddr != deviceMac)
                    {
                        //不是同一个东西Mac
                        return;
                    }
                    if (device.DeviceEpoint != deviceEpoint && deviceEpoint != 200)
                    {
                        //不是同一个东西,这里应该需要特殊处理200端点
                        return;
                    }
                    var responseData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                    //长度不一致
                    if (responseData.PassData.Length != receiptDataLength)
                    {
                        if (listReceiptLength == null)
                        {
                            //如果没有附加检测长度,则直接返回
                            return;
                        }
                        if (listReceiptLength.Contains(responseData.PassData.Length) == false)
                        {
                            //如果附加的检测长度里面,还不存在的话,直接返回
                            return;
                        }
                    }
                    var command = responseData.PassData[4].ToString()
                        + responseData.PassData[5].ToString()
                        + responseData.PassData[2].ToString()
                        + responseData.PassData[3].ToString();
                    //并且是这个命令
                    if (command == receiptCommand)
                    {
                        reResult.ReceiptData = responseData.PassData;
                    }
                }
            };
            myGateway.Actions += receiptAction;
            //发送数据
            myGateway.Send("ClientDataPassthrough", sendData);
            //超时时间
            int TimeOut = 0;
            waitTime = 20 * waitTime;
            while (reResult.ReceiptData == null && TimeOut < waitTime)
            {
                System.Threading.Thread.Sleep(50);
                TimeOut++;
            }
            myGateway.Actions -= receiptAction;
            receiptAction = null;
            if (reResult.ReceiptData == null)
            {
                //超时
                reResult.ErrorMsgDiv = 0;
            }
            return reResult;
        }
        #endregion
    }
}
            }
            //网关ID
            string gatewayID = device.Gateway.GwId;
            //错误主题
            string errorTopic = gatewayID + "/" + "Error_Respon";
            //检测对象的主题
            string checkTopic = gatewayID + "/ZbDataPassthrough";
            Action<string, string> receiptAction = (topic, message) =>
            {
                var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                //网关回复错误
                if (topic == errorTopic)
                {
                    var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
                    reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error);
                }
                //如果是指定的主题
                if (topic == checkTopic)
                {
                    string deviceMac = jobject["DeviceAddr"].ToString();
                    int deviceEpoint = 200;
                    if (jobject.Property("Epoint") != null)
                    {
                        //拥有此键值
                        deviceEpoint = Convert.ToInt32(jobject["Epoint"].ToString());
                    }
                    if (device.DeviceAddr != deviceMac)
                    {
                        //不是同一个东西Mac
                        return;
                    }
                    if (device.DeviceEpoint != deviceEpoint && deviceEpoint != 200)
                    {
                        //不是同一个东西,这里应该需要特殊处理200端点
                        return;
                    }
                    var responseData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ClientDataPassthroughResponseData>(jobject["Data"].ToString());
                    //长度不一致
                    if (responseData.PassData.Length != receiptDataLength)
                    {
                        if (listReceiptLength == null)
                        {
                            //如果没有附加检测长度,则直接返回
                            return;
                        }
                        if (listReceiptLength.Contains(responseData.PassData.Length) == false)
                        {
                            //如果附加的检测长度里面,还不存在的话,直接返回
                            return;
                        }
                    }
                    var command = responseData.PassData[4].ToString()
                        + responseData.PassData[5].ToString()
                        + responseData.PassData[2].ToString()
                        + responseData.PassData[3].ToString();
                    //并且是这个命令
                    if (command == receiptCommand)
                    {
                        reResult.ReceiptData = responseData.PassData;
                        reResult.JsonData = new string[1];
                        if (jobject.Property("Time") != null)
                        {
                            //需要移除time这个字段
                            jobject.Remove("Time");
                        }
                        reResult.JsonData[0] = jobject.ToString();
                    }
                }
            };
            myGateway.Actions += receiptAction;
            //发送数据
            myGateway.Send("ClientDataPassthrough", sendData);
            //超时时间
            int TimeOut = 0;
            waitTime = 20 * waitTime;
            while (reResult.ReceiptData == null && TimeOut < waitTime)
            {
                System.Threading.Thread.Sleep(50);
                TimeOut++;
            }
            myGateway.Actions -= receiptAction;
            receiptAction = null;
            if (reResult.ReceiptData == null)
            {
                //超时
                reResult.ErrorMsgDiv = 0;
            }
            return reResult;
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 计算灯的亮度值所占的百分比(例如:返回35,代表是35%)
        /// </summary>
        /// <param name="i_Level">灯的亮度值</param>
        /// <returns></returns>
        public int CalculateLightLevelPersent(decimal i_Level)
        {
            return (int)((i_Level / 255) * 100);
        }
        /// <summary>
        /// 计算指定百分比对应灯的亮度值
        /// </summary>
        /// <param name="i_Persent">百分比值(比如35,代表35%)</param>
        /// <returns></returns>
        public int CalculateLightLevel(decimal i_Persent)
        {
            //需要向上取整,才能得出
            return (int)Math.Ceiling((i_Persent / 100) * 255);
        }
        #endregion
    }
}