集中器服务拆分
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
processor/selfDevelop/src/main/java/com/back/sync/DataSyncUtil.java

667 lines
19 KiB

package com.back.sync;
import java.text.SimpleDateFormat;
import java.util.List;
import com.back.action.Log;
import com.back.common.Common;
import com.back.entity.Control;
import com.back.entity.Mcontrol;
import com.back.entity.Sensor;
import com.back.protocol.GW3761;
public class DataSyncUtil {
/**
* 获取设置命令 datas 具体设置的报文 terminal 集中器通信地址
*/
private static class Cmdinfor {
String afn; // AFN
String Comid; // 通信地址
String datas; // 数据区内容
Boolean FCV; // 帧计数有效位FCV
String FCB; // FCB
String host; // 主站地址
String PWD; // 密码
int PFC; // PFC
Boolean bTime; // 是否有时间标签
int outTime;// 允许发送传输延时时间
Boolean TP;// 是否有时间标签
Boolean CON;// CON位置“true”,表示需要对该帧报文进行确认;置“false”,表示不需要对该帧报文进行确认。
public void Create(String afn, String comid, String datas, int PFC, Boolean btime) {
datas = datas.replace(" ", "");
datas = datas.trim();
this.afn = afn;
while (comid.length() < 8)
comid = "0" + comid;
this.Comid = comid;
this.datas = datas;
this.FCV = false;
this.PFC = PFC;
this.FCB = "01";
this.host = "02";
this.PWD = "00000000000000000000000000000000";// 固定密码 16个零
this.bTime = btime;
this.outTime = 5;
this.TP = btime;
this.CON = true;
}
}
private static Cmdinfor cmdinfor = new Cmdinfor();
/**
* 配置灯具下发数据 202101
*
* @param
*
* @param flag
* true为新增false为删除
* @return
*/
public static String configLampData(List<Control> controlList, boolean flag) {
String data = "", temp = "";
try {
for (int i = 0; i < controlList.size(); i++) {
Control control = controlList.get(i);
// 灯装置序号(2个字节)
temp = dec2Hex(control.getNum(), 4);
data = data + " " + temp.substring(2, 4);
data = data + " " + temp.substring(0, 2);
// 测量点号(2个字节)
// if (flag) {
// data = data + " " + temp.substring(2, 4);
// data = data + " " + temp.substring(0, 2);
// } else {
// data += " 00 00";
// }
// 灯通信地址(6个字节)
temp = control.getComid();
temp = "000000000000" + temp;
temp = temp.substring(temp.length() - 12);
for (int j = temp.length(); j > 0; j -= 2) {
data += " " + temp.substring(j - 2, j);
}
// 通讯信道(1个字节),即通信端口
// 1-载波通信 2-RS485_1口通信 3-RS485_2口通信 4-LORA无线通信(5-255:备用)
String tunnel = control.getTunnel();
data += " " + tunnel.substring(2, 4);
// 通信协议(1个字节)
// 1-DL645_97版 2-DL645_07版 3-ModBus协议 (4-255:备用)
String protocol = control.getProtocol();
data += " " + protocol.substring(2, 4);
// 所属组号(1个字节)
data = data + " " + dec2Hex(control.getGroupid(), 2);
// 工作方式(1个字节)
String worktypeString = control.getWorktype();
// 00 时间表;01经纬度;02 场景模式
data += " " + worktypeString.substring(2, 4);
// 灯杆类型(1个字节)
// 1—单灯调光 2-双色温调光 3-双灯头调光(3-255:备用)
String type = control.getType();
data += " " + type.substring(2, 4);
}
} catch (Exception e) {
Log.writelog1("构造灯杆安装命令出错, error:" + e.getMessage());
e.printStackTrace();
}
return data;
}
public static String SendCmd(int type, int count, String message) {
int[] cmd = new int[3];
cmd[0] = 0x81;
cmd[1] = 0x01;
cmd[2] = type;
StringBuilder builder = new StringBuilder();
for (int i = 1; i < cmd.length; i++) {
builder.append(" " + dec2Hex(cmd[i], 1));
}
return builder.toString();
}
public static String preSendCmd(String terminal) {
String cmdCode = "0000" + GW3761.GetDAOrDT(4, 1) + "81" + "01" + "00";
String binarypfc = "00000000" + Common.inttobinary(PFC);
PFC++;
if (PFC == 255)
PFC = 0;
binarypfc = Common.right(binarypfc, 4);
String seqdomain = Common.binarytohex("0111" + binarypfc);
char[] chars = terminal.toCharArray();
String adomain = String.valueOf(chars[2]) + String.valueOf(chars[3]) + String.valueOf(chars[0])
+ String.valueOf(chars[1]) + String.valueOf(chars[6]) + String.valueOf(chars[7])
+ String.valueOf(chars[4]) + String.valueOf(chars[5]) + "04";
return gw3761.create3761("64", adomain, "FD", seqdomain, cmdCode);
}
public static String genetateLampData(String terminal, List<Control> controlList) {
String data = configLampData(controlList, Boolean.TRUE);
// String temp = dec2Hex(controlList.size(), 4);
// String msgString = temp.substring(2, 4) + " " + temp.substring(0, 2) + " " + data;
// msgString = GetDAOrDT(21, 1) + msgString.trim();
// cmdinfor.Create("A4", terminal, msgString, GetPFC(), false);
String cmdCode = "0000" + GW3761.GetDAOrDT(4, 1)
+ "81" + "02" + "01" + dec2Hex(controlList.size(), 2) + data;
cmdCode = cmdCode.replace(" ", "");
String binarypfc = "00000000" + Common.inttobinary(PFC);
PFC++;
if (PFC == 255)
PFC = 0;
binarypfc = Common.right(binarypfc, 4);
String seqdomain = Common.binarytohex("0111" + binarypfc);
char[] chars = terminal.toCharArray();
String adomain = String.valueOf(chars[2]) + String.valueOf(chars[3]) + String.valueOf(chars[0])
+ String.valueOf(chars[1]) + String.valueOf(chars[6]) + String.valueOf(chars[7])
+ String.valueOf(chars[4]) + String.valueOf(chars[5]) + "04";
return gw3761.create3761("64", adomain, "FD", seqdomain, cmdCode);
}
private static GW3761 gw3761 = new GW3761(); // 新集中器解码类
private static int PFC = 0; // 启动帧帧序号计数器(0~255)
public static String generateMcontrolData(String terminal, List<Mcontrol> mcontrolList) {
String message = configMcontrolData(mcontrolList, Boolean.TRUE);
// message = GetDAOrDT(36, 1) + message;
// cmdinfor.Create("A4", terminal, message, GetPFC(), false);
String cmdCode = "0000" + GW3761.GetDAOrDT(4, 1)
+ "81" + "02" + "02" + dec2Hex(mcontrolList.size(), 2) + message;
cmdCode = cmdCode.replace(" ", "");
String binarypfc = "00000000" + Common.inttobinary(PFC);
PFC++;
if (PFC == 255)
PFC = 0;
binarypfc = Common.right(binarypfc, 4);
String seqdomain = Common.binarytohex("0111" + binarypfc);
char[] chars = terminal.toCharArray();
String adomain = String.valueOf(chars[2]) + String.valueOf(chars[3]) + String.valueOf(chars[0])
+ String.valueOf(chars[1]) + String.valueOf(chars[6]) + String.valueOf(chars[7])
+ String.valueOf(chars[4]) + String.valueOf(chars[5]) + "04";
return gw3761.create3761("64", adomain, "FD", seqdomain, cmdCode);
}
public static String generateSensorData(String terminal, List<Sensor> sensorList, int fn, String sensorType) {
String message = configSensorData(sensorList, Boolean.TRUE);
// String temp = dec2Hex(1, 2);
// message = temp.substring(0, 2) + " " + message;
// message = GetDAOrDT(fn, 1) + message.trim();
// cmdinfor.Create("A4", terminal, message, GetPFC(), false);
// return GetSendCmd(cmdinfor);
String cmdCode = "0000" + GW3761.GetDAOrDT(4, 1)
+ "81" + "02" + sensorType + dec2Hex(sensorList.size(), 2) + message;
cmdCode = cmdCode.replace(" ", "");
String binarypfc = "00000000" + Common.inttobinary(PFC);
PFC++;
if (PFC == 255)
PFC = 0;
binarypfc = Common.right(binarypfc, 4);
String seqdomain = Common.binarytohex("0111" + binarypfc);
char[] chars = terminal.toCharArray();
String adomain = String.valueOf(chars[2]) + String.valueOf(chars[3]) + String.valueOf(chars[0])
+ String.valueOf(chars[1]) + String.valueOf(chars[6]) + String.valueOf(chars[7])
+ String.valueOf(chars[4]) + String.valueOf(chars[5]) + "04";
return gw3761.create3761("64", adomain, "FD", seqdomain, cmdCode);
}
public static String configMcontrolData(List<Mcontrol> mcontrolList, boolean flag) {
String data = "", temp = "";
try {
for (int i = 0; i < mcontrolList.size(); i++) {
Mcontrol mcontrol = mcontrolList.get(i);
// 主控装置序号(2个字节)
temp = dec2Hex(mcontrol.getNum(), 4);
data = data + temp.substring(2, 4) + " " + temp.substring(0, 2);
// 测量点号(2个字节)
// if (flag) {
// data += " " + temp.substring(2, 4) + " " + temp.substring(0,
// 2);
// } else {
// data += " 00 00";
// }
// 通信地址(6个字节)
temp = mcontrol.getComid();
while (temp.length() < 12)
temp = "0" + temp;
for (int j = temp.length(); j > 0; j -= 2) {
data += " " + temp.substring(j - 2, j);
}
// 通讯信道(1个字节):1为载波口 2为第一个485口 3为第二个485口
temp = mcontrol.getTunnel();
data += " " + temp.substring(2, 4);
// 通讯协议(1个字节):1-DL645_97版 2-DL645_07版 3-ModBus协议 (4-255:备用)
temp = mcontrol.getProtocol();
data += " " + temp.substring(2, 4);
// 该线路所属组号(1个字节)
if (mcontrol.getGroups() == null) {
temp = "";
} else {
temp = mcontrol.getGroups().trim();
}
if (temp.equals("")) {
data += " 00";
} else {
temp = dec2Hex(Integer.parseInt(temp), 2);
data += " " + temp;
}
// 工作方式(1个字节)
String worktypeString = mcontrol.getWorktype();
if (worktypeString.equals("0001")) { // 走经纬度
data += " 01";
} else if (worktypeString.equals("0000")) { // 走时间表
data += " 00";
} else if (worktypeString.equals("0002")) { // 场景模式
data += " 02";
}
// 回路类型(1个字节)
temp = dec2Hex(mcontrol.getType(), 2);
data += " " + temp;
// 回路电流互感器变比值(1个字节)
temp = dec2Hex(mcontrol.getRatio(), 2);
data += " " + temp;
}
} catch (Exception e) {
Log.writelog1("构造回路安装命令出错, error:" + e.getMessage());
e.printStackTrace();
}
return data;
}
public static String configSensorData(List<Sensor> sensorList, boolean flag) {
String data = "", temp = "";
try {
for (int i = 0; i < sensorList.size(); i++) {
Sensor sensor = sensorList.get(i);
// 灯装置序号(2个字节)
temp = dec2Hex(sensor.getNum(), 4);
data = data + " " + temp.substring(2, 4);
data = data + " " + temp.substring(0, 2);
// 测量点号(2个字节)
// if (flag) {
// data = data + " " + temp.substring(2, 4);
// data = data + " " + temp.substring(0, 2);
// } else {
// data += " 00 00";
// }
// 灯通信地址(6个字节)
temp = sensor.getComid();
temp = "000000000000" + temp;
temp = temp.substring(temp.length() - 12);
for (int j = temp.length(); j > 0; j -= 2) {
data += " " + temp.substring(j - 2, j);
}
// 通讯信道(1个字节),即通信端口 1-载波通信 2-RS485_1口通信 3-RS485_2口通信
// 4-LORA无线通信(5-255:备用)
String tunnel = sensor.getTunnel();
data += " " + tunnel.substring(2, 4);
// 通信协议(1个字节) 1-DL645_97版 2-DL645_07版 3-ModBus协议 (4-255:备用)
String protocol = sensor.getProtocol();
data += " " + protocol.substring(2, 4);
int fn = 0;
if (sensor.getType().equals("0001")) {// 照度传感器
fn = 37;
} else if (sensor.getType().equals("0002")) {// 亮度传感器
fn = 38;
// 转换系数(1个字节)
temp = dec2Hex(sensor.getRatio(), 2);
data += " " + temp;
} else if (sensor.getType().equals("0003")) {// 车流量传感器
fn = 39;
// 车流量统计周期(1个字节)
temp = dec2Hex(sensor.getCycle(), 2);
data += " " + temp;
// 车道数量(1个字节)
temp = dec2Hex(sensor.getLane(), 2);
data += " " + temp;
}
}
} catch (Exception e) {
Log.writelog1("构造传感器安装命令出错, error:" + e.getMessage());
e.printStackTrace();
}
return data;
}
/**
* 10进制转16进制
*
* @param dec
* 要转换的数值
* @param len
* 16进制的长度
* @return
*/
private static String dec2Hex(int dec, int len) {
String tempString = Integer.toHexString(dec);
while (tempString.length() < len) {
tempString = "0" + tempString;
}
return tempString.trim();
}
/**
* 10进制字符串转16进制字符串
*
* @param dec
* @return
*/
public static String dec2Hex(String dec, int len) {
if (dec == null || dec.equals(""))
dec = "0";
String tempString = Long.toHexString(Long.parseLong(dec));
while (tempString.length() < len) {
tempString = "0" + tempString;
}
return tempString.trim();
}
/**
* 为0时计算信息点标识DA(Pn)为1计算信息类标识DT(Fn)
*
* @param value
* @param flag
* 0/1
* @return F30,返回值格式00 00 20 03
*/
public static String GetDAOrDT(int value, int flag) {
int d = 0;
String D1, D2 = "0";
if (value == 0) {
D1 = "0";
D2 = "0";
} else {
d = value % 8;
if (d == 0) {
D1 = "1" + repeat(7, '0');
d = value / 8 - 1;
if (flag == 0) {
d = d + 1;
}
} else {
D1 = "1" + repeat(d - 1, '0');
d = value / 8;
if (flag == 0) {
d = d + 1;
}
}
}
D1 = Common.right("00" + Common.binarytohex(D1), 2);
D2 = Common.right("00" + Common.inttohex(d), 2);
return "00 00 " + D1 + " " + D2;
}
/** 返回指定字符的重复 */
public static String repeat(int len, char c) {
StringBuffer sbf = new StringBuffer();
int i = 0;
while (i < len) {
i += 1;
sbf.append(c);
}
return sbf.toString();
}
private static int GetPFC() {
return 1;
}
private static int msg[] = new int[2024];
private static String GetSendCmd(Cmdinfor cmdinfor) {
int count = cmdinfor.datas.length();
int i;
String temp;
for (i = 0; i < msg.length; i++)
msg[i] = 0;
// 报文头
msg[0] = 0x68;// 68H
msg[5] = 0x68;// 68H
// 控制码
msg[6] = GetDownCortrolByte(cmdinfor.afn, cmdinfor.FCB, cmdinfor.FCV);// C
// 控制位
// 通信地址 16进制字
temp = cmdinfor.Comid.substring(0, 4);
msg[8] = Integer.parseInt(temp.substring(0, 2), 16) & 0xFF; // A 地址域 -->
// 行政区划码 A1
// 2字节 BCD码
msg[7] = Integer.parseInt(temp.substring(2), 16) & 0xFF; // A 地址域 -->
// 行政区划码 A1
// 2字节 BCD码
temp = cmdinfor.Comid.substring(4);
msg[10] = Integer.parseInt(temp.substring(0, 2), 16) & 0xFF; // A 地址域
// -->
// 行政区划码
// A2
// 2字节
// BCD码
msg[9] = Integer.parseInt(temp.substring(2), 16) & 0xFF; // A 地址域 -->
// 行政区划码 A2
// 2字节 BCD码
// 主站地址
msg[11] = (Integer.parseInt(cmdinfor.host, 16) << 1) & 0xFF;// A 地址域 -->
// 主站地址 A3
// 1字节 Bin码
msg[12] = Integer.parseInt(cmdinfor.afn, 16) & 0xFF; // AFN
if (cmdinfor.bTime)
temp = "111";
else
temp = "011";
// 20190216 增加 请求确认标志位
if (cmdinfor.CON)
temp = temp + "1";
else
temp = temp + "0";
msg[13] = (binaryString2Int(temp) << 4) + (cmdinfor.PFC % 16); // SEQ
// 帧序列域
int len = cmdinfor.datas.length() / 2;
for (int j = 0; j < (len); j++) {
temp = cmdinfor.datas.substring(j * 2, (j * 2 + 2));
msg[14 + j] = Integer.parseInt(temp, 16) & 0xFF;
}
len = len + 13;
if (CheckDwnPw(cmdinfor.afn)) {
len++;
for (int j = 0; j < 16; j++) { // 密码
temp = cmdinfor.PWD.substring(j * 2, (j * 2 + 2));
msg[len + j] = Integer.parseInt(temp, 16) & 0xFF;
}
len = len + 15;
}
if (cmdinfor.TP) {
SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String datetime = tempDate.format(new java.util.Date());
len++;
msg[len] = cmdinfor.PFC;// 启动帧帧序号计数器PFC
len++;
msg[len] = Integer.parseInt(datetime.substring(17, 19), 16);// 启动帧发送时标
// 秒
len++;
msg[len] = Integer.parseInt(datetime.substring(14, 16), 16);// 启动帧发送时标
// 分
len++;
msg[len] = Integer.parseInt(datetime.substring(11, 13), 16);// 启动帧发送时标
// 时
len++;
msg[len] = Integer.parseInt(datetime.substring(8, 10), 16);// 启动帧发送时标
// 日
len++;
msg[len] = 1;// 允许发送传输延时时间
}
len++;
msg[len] = GetCS(len);
len++;
msg[len] = 0x16;
count = len - 7;
count = (count << 2) + 2;
msg[1] = count % 0x100;
msg[2] = count / 0x100;
msg[3] = count % 0x100;
msg[4] = count / 0x100;
// 转成字符串
StringBuffer sendBuffer = new StringBuffer();
for (int j = 0; j <= len; j++)
sendBuffer.append(" " + dec2Hex(msg[j], 2));
System.out.println(sendBuffer.toString().trim());
return sendBuffer.toString().trim();
}
/**
* 获取相应的功能码
*
* @param sType
* @param sFCB
* @param bFCV
* @return
*/
private static Integer GetDownCortrolByte(String sType, String sFCB, Boolean bFCV) {
String temp = "";
sType = sType.toUpperCase();
sType = sType.trim();
if (sType.equals("00"))
temp = "0001";
if (sType.equals("02"))
temp = "1001";
if (sType.equals("03"))
temp = "1011";
if (sType.equals("04"))
temp = "1010";
if (sType.equals("05"))
temp = "1010";
if (sType.equals("06"))
temp = "1011";
if (sType.equals("08"))
temp = "1011";
if (sType.equals("09"))
temp = "1011";
if (sType.equals("0A"))
temp = "1011";
if (sType.equals("0B"))
temp = "1011";
if (sType.equals("0C"))
temp = "1011";
if (sType.equals("0D"))
temp = "1011";
if (sType.equals("0E"))
temp = "1011";
if (sType.equals("0F"))
temp = "1011";
if (sType.equals("10"))
temp = "1011";
if (sType.equals("8C"))
temp = "1011";
if (sType.equals("A4"))
temp = "1010";
if (sType.equals("A5"))
temp = "1010";
if (sType.equals("AA"))
temp = "1011";
if (sType.equals("AC"))
temp = "1011";
if (sType.equals("AD"))
temp = "1011";
if (bFCV)
temp = "01" + sFCB.substring(1, 2) + "1" + temp;
else
temp = "01" + sFCB.substring(1, 2) + "0" + temp;
return binaryString2Int(temp);
}
private static Boolean CheckDwnPw(String sType) {
Boolean sign = false;
if (sType.equals("01"))
sign = true;
if (sType.equals("03"))
sign = true;
if (sType.equals("04"))
sign = true;
if (sType.equals("05"))
sign = true;
if (sType.equals("06"))
sign = true;
if (sType.equals("0F"))
sign = true;
if (sType.equals("10"))
sign = true;
if (sType.equals("01"))
sign = true;
if (sType.equals("01"))
sign = true;
if (sType.equals("01"))
sign = true;
if (sType.equals("A4"))
sign = true;
if (sType.equals("A5"))
sign = true;
return sign;
}
/**
* 二进制字符串转整型
*
* @param bString
* @return
*/
public static int binaryString2Int(String bString) {
int temp = 0;
for (int i = 0; i < bString.length(); i++) {
temp <<= 1;
temp += Integer.parseInt(bString.substring(i, i + 1));
}
return temp;
}
private static int GetCS(int len) {
int ics = 0;
for (int i = 6; i < len; i++) {
ics = ics + msg[i];
}
return ics & 0xFF;
}
}