黄学彪
2020-09-22 ade5917841b0fdcb1df7353ef7c56b1a1bdc9282
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
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>
        /// 设备的共通逻辑
        /// </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;
            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];
            }
 
            //接收数
            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;
            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";
            //检测对象的主题
            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
    }
}