panlili2024
2024-09-19 071a8328823a2861f93ce556a4da3e4119cab1a3
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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
package com.hdl.sdk.ttl.HDLDeviceManger.Bean;
 
import java.util.ArrayList;
import java.util.Calendar;
 
import com.hdl.sdk.ttl.Config.Global;
import com.hdl.sdk.ttl.HDLDeviceManger.Core.Crc;
 
import java.net.InetAddress;
 
public class SendDatas {
    // finish
    public static final int FINISH = 10;
    public static final int SEND_ONLY_ONCE = 0;
    public static final int SEND_MAX = 3;
    /**
     * 重发列表
     */
    private static ArrayList<SendDatas> RetransmissionDateList = new ArrayList<SendDatas>();
    /**
     * 只发送一次,发送完就移除
     */
    public static ArrayList<SendDatas> sendDataArrayList = new ArrayList<SendDatas>(100);
    // 已经发送出去的次数
    public int SendCount = 0;
    public Calendar StartCalendar =null;
    // 子网号
    public int DesSubnetID;
    // 设备号
    public int DesDeviceID;
    // 发送出去的附加数据
    public byte[] AddBytes = new byte[]{};
    // 获取发送出去的数据,每调用这个方法的时候,数据都会重新排列一下,得到真实的数据
    public InetAddress InetAddress;
    public int Port;
    public InetAddress TargetAddress;
 
    /**
     * 设备协议类型
     */
    public int protocolType;
 
    public byte[] GetSendBytes() {
 
        // 要计算CRC的数据和CRC两个字节
        byte[] crcBytes = new byte[9 + this.AddBytes.length + 2];
 
        // 发送出去的数据
        byte[] sendBytes = new byte[16 + crcBytes.length];
 
        /*String[] ip = Net.CurrentNet.getPsdnIp().split("\\.");
        // IP地址
        sendBytes[0] = (byte) GetStringToInteger(ip[0]);
        sendBytes[1] = (byte) GetStringToInteger(ip[1]);
        sendBytes[2] = (byte) GetStringToInteger(ip[2]);
        sendBytes[3] = (byte) GetStringToInteger(ip[3]);*/
 
        // HDL--HOTEL
        if (this.Port == 6006) {
 
            sendBytes[4] = (byte) 0x48;
            sendBytes[5] = (byte) 0x44;
            sendBytes[6] = (byte) 0x4c;
            sendBytes[7] = (byte) 0x4d;
            sendBytes[8] = (byte) 0x49;
            sendBytes[9] = (byte) 0x52;
            sendBytes[10] = (byte) 0x41;
            sendBytes[11] = (byte) 0x43;
            sendBytes[12] = (byte) 0x4c;
            sendBytes[13] = (byte) 0x45;
        } else {
            // HDLMIRACLE
            sendBytes[4] = (byte) 0x48;
            sendBytes[5] = (byte) 0x44;
            sendBytes[6] = (byte) 0x4c;
            sendBytes[7] = (byte) 0x4d;
            sendBytes[8] = (byte) 0x49;
            sendBytes[9] = (byte) 0x52;
            sendBytes[10] = (byte) 0x41;
            sendBytes[11] = (byte) 0x43;
            sendBytes[12] = (byte) 0x4c;
            sendBytes[13] = (byte) 0x45;
        }
        // 引导码
        sendBytes[14] = (byte) 0xAA;
        sendBytes[15] = (byte) 0xAA;
 
        // 16 数据包长度 11-78
        crcBytes[0] = (byte) crcBytes.length;
        // 17 源子网地址 0-254
        crcBytes[1] = (byte) Global.subnetID;
        // 18 源设备地址 0-254
        crcBytes[2] = (byte) Global.deviceID;
        // 19 源设备类型高位
        crcBytes[3] = (byte) (Global.DeviceType / 256);
        // 20 源设备类型低位
        crcBytes[4] = (byte) (Global.DeviceType % 256);
        // 21 操作码高位
        crcBytes[5] = (byte) (this.Command / 256);
        // 22 操作码低位
        crcBytes[6] = (byte) (this.Command % 256);
        // 23 目标子网地址 0-254
        crcBytes[7] = (byte) this.DesSubnetID;
        // 24 目标设备地址 0-254
        crcBytes[8] = (byte) this.DesDeviceID;
        // 25~n附加数据
        System.arraycopy(this.AddBytes, 0, crcBytes, 9, this.AddBytes.length);
        // CRC校验
        Crc.ConCRC(crcBytes, crcBytes.length - 2);
 
        // 复制CRC数据到发送数据里面
        System.arraycopy(crcBytes, 0, sendBytes, 16, crcBytes.length);
 
        /*
         * int sss[] = new int[sendBytes.length]; for(int i
         * =0;i<sendBytes.length;i++){ sss[i] =
         * Global.GetByteToUbyte(sendBytes[i]); }
         */
 
        return sendBytes;
 
    }
 
    /**
     * 获取串口发送数据
     *
     * @return -
     */
    public byte[] GetSerialPortSendBytes() {
 
        //Data and to compute the CRC of CRC two bytes
        byte[] crcBytes = new byte[9 + this.AddBytes.length + 2];
 
        //Send out the data
        byte[] sendBytes = new byte[2 + crcBytes.length];
 
        //Boot code
        sendBytes[0] = (byte) 0xAA;
        sendBytes[1] = (byte) 0xAA;
 
        //16    The length of the packet   11-78
        crcBytes[0] = (byte) crcBytes.length;
        //17    Source subnet addresses  0-254
        crcBytes[1] = (byte) Global.subnetID;// Global.subnetId;/
        //18    source device address   0-254
        crcBytes[2] = (byte) Global.deviceID;//Global.deviceId;
        //19    High source device type
        crcBytes[3] = (byte) (Global.DeviceType / 256);
        //20    The source device type low
        crcBytes[4] = (byte) (Global.DeviceType % 256);
        //21    Opcode high
        crcBytes[5] = (byte) (this.Command / 256);
        //22    Opcode low
        crcBytes[6] = (byte) (this.Command % 256);
        //23    The target subnet addresses  0-254
        crcBytes[7] = (byte) this.DesSubnetID;
        //24    The destination address  0-254
        crcBytes[8] = (byte) this.DesDeviceID;
        //25~n  Additional data
        System.arraycopy(this.AddBytes, 0, crcBytes, 9, this.AddBytes.length);
        //Check CRC
        Crc.ConCRC(crcBytes, crcBytes.length - 2);
 
        //Copy the CRC data to send data
        System.arraycopy(crcBytes, 0, sendBytes, 2, crcBytes.length);
 
        return sendBytes;
 
    }
 
    // 操作码
    public int Command;
    // 每个字节对应是否已经发送出去的数次
    public boolean[] HaveSend = new boolean[]{false, false, false};
    // 临时表示发送出去的数据的引用
    private static SendDatas currentSendBytesInfo = null;
 
    // 这个函数可以增加一个标识,选择当前这条数据需要发送多少次,这亲使用起来就比较方便点
    // 有可能还需要加入哪条数据的发送优先级,这亲需要先发送的数据就发送快点。
    // 增加要发送的数据
    public static void AddSendData(int command, int desSubnetID, int desDeviceID, byte[] addBytes, int sendCount,
                                   InetAddress ip, int port, int _protocolType) {
        SendDatas sendDatas = new SendDatas();
        sendDatas.Command = command; // 这里的操作码最好是用枚举,这样才不会出错又方便
        sendDatas.DesSubnetID = desSubnetID;
        sendDatas.DesDeviceID = desDeviceID;
        sendDatas.AddBytes = addBytes;
        sendDatas.SendCount = sendCount; // 如果这个值
        // 大于等于500表示只需要发送两次,如果大于等于1000表示只需要发送一次,如果大于等于1500,表示不需要再发送数据了
        sendDatas.InetAddress = ip;
        sendDatas.Port = port;
        sendDatas.protocolType = _protocolType;
        synchronized (SendDatas.sendDataArrayList) {
            sendDataArrayList.add(sendDatas);// 加入到发送缓冲区,等待发送线程来发送数据
        }
    }
 
    public static void AddSendData(int command, int desSubnetID, int desDeviceID, byte[] addBytes) {
        SendDatas sendDatas = new SendDatas();
        sendDatas.Command = command; // 这里的操作码最好是用枚举,这样才不会出错又方便
        sendDatas.DesSubnetID = desSubnetID;
        sendDatas.DesDeviceID = desDeviceID;
        sendDatas.AddBytes = addBytes;
        sendDatas.SendCount = 0; // 如果这个值大于2表示不需要重发了
        sendDatas.Port = 6000;
        synchronized (SendDatas.sendDataArrayList) {
            sendDataArrayList.add(sendDatas);// 加入到发送缓冲区,等待发送线程来发送数据
        }
    }
 
    public static void AddSendData(int command, int desSubnetID, int desDeviceID, byte[] addBytes, int sendCount) {
        SendDatas sendDatas = new SendDatas();
        sendDatas.Command = command; // 这里的操作码最好是用枚举,这样才不会出错又方便
        sendDatas.DesSubnetID = desSubnetID;
        sendDatas.DesDeviceID = desDeviceID;
        sendDatas.AddBytes = addBytes;
        sendDatas.SendCount = sendCount; // 如果这个值大于2表示不需要重发了
        sendDatas.Port = 6000;
        synchronized (SendDatas.sendDataArrayList) {
            sendDataArrayList.add(sendDatas);// 加入到发送缓冲区,等待发送线程来发送数据
        }
    }
 
    public static void AddSendData(int command, int desSubnetID, int desDeviceID, byte[] addBytes, int sendCount, InetAddress ip, int port) {
        SendDatas sendDatas = new SendDatas();
        sendDatas.Command = command; // 这里的操作码最好是用枚举,这样才不会出错又方便
        sendDatas.DesSubnetID = desSubnetID;
        sendDatas.DesDeviceID = desDeviceID;
        sendDatas.AddBytes = addBytes;
        sendDatas.SendCount = sendCount; // 如果这个值大于2表示不需要重发了
        sendDatas.InetAddress = ip;
        sendDatas.Port = port;
        synchronized (SendDatas.sendDataArrayList) {
            sendDataArrayList.add(sendDatas);// 加入到发送缓冲区,等待发送线程来发送数据
        }
    }
 
    /**
     * 更新发送是否成功的信息
     *
     * @param command
     * @param subnetID
     * @param deviceID
     * @param usefulBytes
     */
    public static void ReceiveBytes(int command, int subnetID, int deviceID, byte[] usefulBytes) {
 
        try {
 
            if (usefulBytes.length < 1) return;
 
            for (int i = 0; i < SendDatas.sendDataArrayList.size(); i++) {
 
                currentSendBytesInfo = sendDataArrayList.get(i);
 
                if (currentSendBytesInfo.DesSubnetID != subnetID || currentSendBytesInfo.DesDeviceID != deviceID || currentSendBytesInfo.Command + 1 != command)
                    continue;
 
                switch (command) {
                    case 0x0032:// 单路调节控制反馈
                    case 0x1939:// 模块空调读取反馈
                    case 0x193B:// 空调模块控制反馈
                    case 0xE01D:// 通用开关回复
                    case 0xE3D9:// 面板控制反馈
                    case 0xE3E3:// 窗帘开关读取回复
                    case 0xE45D:// 逻辑灯RGB控制返回
                    case 0xE473:// 逻辑灯RGB读取反馈
                    case 0x1c5f:// 地热m模块读取反馈
                    case 0x1c5d:// 地热模块控制反馈
                        if (currentSendBytesInfo.AddBytes[0] == usefulBytes[0]) {
                            currentSendBytesInfo.SendCount = FINISH;
                        }
                        break;
                    case 0x0003:// 场景控制反馈
                    case 0x001B:// 序列控制反馈
                    case 0x0034:// 灯光读取反馈
                    case 0x16A7:// 通用控制反馈
                    case 0xE3E1:// 窗帘开关回复
                    case 0x1945:// 地热面板读取反馈
                    case 0x1947:// 地热面板控制反馈
                        currentSendBytesInfo.SendCount = FINISH;
                        break;
                }
            }
        } catch (Exception e) {
            e.getMessage();
        }
    }
 
    // 加入重发列表
    public static void AddSendDataList(SendDatas sendDatas) {
 
        synchronized (RetransmissionDateList) {
 
            for (int i = 0; i < RetransmissionDateList.size(); i++) {
 
                SendDatas _data = RetransmissionDateList.get(i);
 
                switch (_data.Command) {
                    case 0x0031:// 单路调节控制反馈
                    case 0xE45C:// 逻辑灯RGB控制返回
                    case 0xE472:// 逻辑灯RGB读取反馈
                    case 0xE01C:// 通用开关回复
                    case 0xE3E0:// 窗帘开关回复
                    case 0x193A:// 空调模块控制反馈
                    case 0x1938:// 模块空调读取反馈
                    case 0xE3D8:// 面板控制反馈
                    case 0xE3E2:// 窗帘开关读取回复
                        if (_data.DesSubnetID == sendDatas.DesSubnetID && _data.DesDeviceID == sendDatas.DesDeviceID
                                && _data.Command == sendDatas.Command && _data.AddBytes[0] == sendDatas.AddBytes[0]) {
                            return;
                        }
                        break;
                    case 0x192E://音乐控制
                    case 0x1970:
                        return;
                    case 0x0034:// 灯光读取反馈
                    case 0x0003:// 场景控制反馈
                    case 0x001B:// 序列控制反馈
                    case 0x16A7:// 通用控制反馈
                    default:
                        if (_data.DesSubnetID == sendDatas.DesSubnetID && _data.DesDeviceID == sendDatas.DesDeviceID
                                && _data.Command == sendDatas.Command) {
                            return;
                        }
                        break;
                }
            }
            RetransmissionDateList.add(sendDatas);
        }
    }
 
    public static ArrayList<SendDatas> GetSendDataList() {
        return RetransmissionDateList;
    }
 
 
    /**
     * 字符串转换为整数
     *
     * @param s
     * @return
     */
    public static int GetStringToInteger(String s) {
 
        try {
            return Integer.parseInt(s);
        } catch (Exception e) {
            return 0;
        }
    }
}