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;
|
}
|
}
|
}
|